123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- #pragma once
- #include "../C/Baselib_EventSemaphore.h"
- #include "Time.h"
- namespace baselib
- {
- BASELIB_CPP_INTERFACE
- {
- // In computer science, an event (also called event semaphore) is a type of synchronization mechanism that is used to indicate to waiting processes when a
- // particular condition has become true.
- // An event is an abstract data type with a boolean state and the following operations:
- // * wait - when executed, causes the suspension of the executing process until the state of the event is set to true. If the state is already set to true has no effect.
- // * set - sets the event's state to true, release all waiting processes.
- // * clear - sets the event's state to false.
- //
- // "Event (synchronization primitive)", Wikipedia: The Free Encyclopedia
- // https://en.wikipedia.org/w/index.php?title=Event_(synchronization_primitive)&oldid=781517732
- //
- // For optimal performance, baselib::EventSemaphore should be stored at a cache aligned memory location.
- class EventSemaphore
- {
- public:
- // non-copyable
- EventSemaphore(const EventSemaphore& other) = delete;
- EventSemaphore& operator=(const EventSemaphore& other) = delete;
- // non-movable (strictly speaking not needed but listed to signal intent)
- EventSemaphore(EventSemaphore&& other) = delete;
- EventSemaphore& operator=(EventSemaphore&& other) = delete;
- // Creates an event semaphore synchronization primitive. Initial state of event is unset.
- //
- // If there are not enough system resources to create a semaphore, process abort is triggered.
- EventSemaphore()
- {
- Baselib_EventSemaphore_CreateInplace(&m_EventSemaphoreData);
- }
- // Reclaim resources and memory held by the semaphore.
- // If threads are waiting on the semaphore, calling free may trigger an assert and may cause process abort.
- ~EventSemaphore()
- {
- Baselib_EventSemaphore_FreeInplace(&m_EventSemaphoreData);
- }
- // Try to acquire semaphore.
- //
- // When semaphore is acquired this function is guaranteed to emit an acquire barrier.
- //
- // \returns true if event is set, false other wise.
- COMPILER_WARN_UNUSED_RESULT
- inline bool TryAcquire()
- {
- return Baselib_EventSemaphore_TryAcquire(&m_EventSemaphoreData);
- }
- // Acquire semaphore.
- //
- // This function is guaranteed to emit an acquire barrier.
- inline void Acquire()
- {
- return Baselib_EventSemaphore_Acquire(&m_EventSemaphoreData);
- }
- // Try to acquire semaphore.
- //
- // If event is set this function return true, otherwise the thread will wait for event to be set or for release to be called.
- //
- // When semaphore is acquired this function is guaranteed to emit an acquire barrier.
- //
- // Acquire with a zero timeout differs from TryAcquire in that TryAcquire is guaranteed to be a user space operation
- // while Acquire may enter the kernel and cause a context switch.
- //
- // Timeout passed to this function may be subject to system clock resolution.
- // If the system clock has a resolution of e.g. 16ms that means this function may exit with a timeout error 16ms earlier than originally scheduled.
- //
- // \returns true if semaphore was acquired.
- COMPILER_WARN_UNUSED_RESULT
- inline bool TryTimedAcquire(const timeout_ms timeoutInMilliseconds)
- {
- return Baselib_EventSemaphore_TryTimedAcquire(&m_EventSemaphoreData, timeoutInMilliseconds.count());
- }
- // Sets the event
- //
- // Setting the event will cause all waiting threads to wakeup. And will let all future acquiring threads through until Baselib_EventSemaphore_Reset is called.
- // It is guaranteed that any thread waiting previously on the EventSemaphore will be woken up, even if the semaphore is immediately reset. (no lock stealing)
- //
- // Guaranteed to emit a release barrier.
- inline void Set()
- {
- return Baselib_EventSemaphore_Set(&m_EventSemaphoreData);
- }
- // Reset event
- //
- // Resetting the event will cause all future acquiring threads to enter a wait state.
- // Has no effect if the EventSemaphore is already in a reset state.
- //
- // Guaranteed to emit a release barrier.
- inline void Reset()
- {
- return Baselib_EventSemaphore_Reset(&m_EventSemaphoreData);
- }
- // Reset event and release all waiting threads
- //
- // Resetting the event will cause all future acquiring threads to enter a wait state.
- // If there were any threads waiting (i.e. the EventSemaphore was already in a release state) they will be released.
- //
- // Guaranteed to emit a release barrier.
- inline void ResetAndRelease()
- {
- return Baselib_EventSemaphore_ResetAndReleaseWaitingThreads(&m_EventSemaphoreData);
- }
- private:
- Baselib_EventSemaphore m_EventSemaphoreData;
- };
- }
- }
|