summaryrefslogblamecommitdiffstatshomepage
path: root/src/osd/osdsync.h
blob: 71726a830cfc879ef3781dc136cade517d912ee7 (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                                                 

                                                              
                                              
  

                                                              

                   
 




                             
                    
 



                                                                            
                                                 
 
                                                                             
 











                                                                                       
 
                         
 












                                                                                       

                                                           





























                                                                                       
                                                                                        





                                                                                                                              
                                                                     





























                                                                                       
                                    




















                                                                                       
                                         
                 
                                           










                                                    

                                               

  
 
                         
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert, R. Belmont
//============================================================
//
//  osdsync.h - Core synchronization functions
//
//============================================================

#ifndef __OSDSYNC__
#define __OSDSYNC__

// C++ headers
#include <mutex>
#include <atomic>
#include <condition_variable>

#include "osdcomm.h"

/***************************************************************************
    SYNCHRONIZATION INTERFACES - Events
***************************************************************************/

#define OSD_EVENT_WAIT_INFINITE (~(osd_ticks_t)0)

/* osd_event is an opaque type which represents a setable/resettable event */

class osd_event
{
public:
	/*-----------------------------------------------------------------------------
	    constructor: allocate a new event

	    Parameters:

	        manualreset  - boolean. If true, the event will be automatically set
	                       to non-signalled after a thread successfully waited for
	                       it.
	        initialstate - boolean. If true, the event is signalled initially.

	    Return value:

	        A pointer to the allocated event.
	-----------------------------------------------------------------------------*/
	osd_event(int manualreset, int initialstate)
	{
		m_signalled = initialstate;
		m_autoreset = !manualreset;
	}

	~osd_event()
	{
	}

	/*-----------------------------------------------------------------------------
	    wait:   wait for an event to be signalled
	            If the event is in signalled state, the
	            function returns immediately. If not it will wait for the event
	            to become signalled.

	    Parameters:

	        timeout - timeout in osd_ticks

	    Return value:

	        true:  The event was signalled
	        false: A timeout occurred
	-----------------------------------------------------------------------------*/

	bool wait(osd_ticks_t timeout)
	{
		if (timeout == OSD_EVENT_WAIT_INFINITE)
			timeout = osd_ticks_per_second() * (osd_ticks_t)10000;

		std::unique_lock<std::mutex> lock(m_mutex);
		if (!timeout)
		{
			if (!m_signalled)
			{
				return false;
			}
		}
		else
		{
			if (!m_signalled)
			{
				uint64_t msec = timeout * 1000 / osd_ticks_per_second();

				do {
					if (m_cond.wait_for(lock, std::chrono::milliseconds(msec)) == std::cv_status::timeout)
					{
						if (!m_signalled)
						{
							return false;
						}
						else
							break;
					} else
						break;

				} while (true);
			}
		}

		if (m_autoreset)
			m_signalled = 0;

		return true;
	}

	/*-----------------------------------------------------------------------------
	    osd_event_reset: reset an event to non-signalled state

	    Parameters:

	        None

	    Return value:

	        None
	-----------------------------------------------------------------------------*/
	void reset()
	{
		m_mutex.lock();
		m_signalled = false;
		m_mutex.unlock();
	}

	/*-----------------------------------------------------------------------------
	    osd_event_set: set an event to signalled state

	    Parameters:

	        None

	    Return value:

	        None

	    Notes:

	        All threads waiting for the event will be signalled.
	-----------------------------------------------------------------------------*/
	void set()
	{
		m_mutex.lock();
		if (m_signalled == false)
		{
			m_signalled = true;
			if (m_autoreset)
				m_cond.notify_one();
			else
				m_cond.notify_all();
		}
		m_mutex.unlock();
	}

private:
	std::mutex               m_mutex;
	std::condition_variable  m_cond;
	std::atomic<int32_t>       m_autoreset;
	std::atomic<int32_t>       m_signalled;

};

#endif  /* __OSDSYNC__ */