EventSemaphore.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #pragma once
  2. #include "../C/Baselib_EventSemaphore.h"
  3. #include "Time.h"
  4. namespace baselib
  5. {
  6. BASELIB_CPP_INTERFACE
  7. {
  8. // 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
  9. // particular condition has become true.
  10. // An event is an abstract data type with a boolean state and the following operations:
  11. // * 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.
  12. // * set - sets the event's state to true, release all waiting processes.
  13. // * clear - sets the event's state to false.
  14. //
  15. // "Event (synchronization primitive)", Wikipedia: The Free Encyclopedia
  16. // https://en.wikipedia.org/w/index.php?title=Event_(synchronization_primitive)&oldid=781517732
  17. //
  18. // For optimal performance, baselib::EventSemaphore should be stored at a cache aligned memory location.
  19. class EventSemaphore
  20. {
  21. public:
  22. // non-copyable
  23. EventSemaphore(const EventSemaphore& other) = delete;
  24. EventSemaphore& operator=(const EventSemaphore& other) = delete;
  25. // non-movable (strictly speaking not needed but listed to signal intent)
  26. EventSemaphore(EventSemaphore&& other) = delete;
  27. EventSemaphore& operator=(EventSemaphore&& other) = delete;
  28. // Creates an event semaphore synchronization primitive. Initial state of event is unset.
  29. //
  30. // If there are not enough system resources to create a semaphore, process abort is triggered.
  31. EventSemaphore()
  32. {
  33. Baselib_EventSemaphore_CreateInplace(&m_EventSemaphoreData);
  34. }
  35. // Reclaim resources and memory held by the semaphore.
  36. // If threads are waiting on the semaphore, calling free may trigger an assert and may cause process abort.
  37. ~EventSemaphore()
  38. {
  39. Baselib_EventSemaphore_FreeInplace(&m_EventSemaphoreData);
  40. }
  41. // Try to acquire semaphore.
  42. //
  43. // When semaphore is acquired this function is guaranteed to emit an acquire barrier.
  44. //
  45. // \returns true if event is set, false other wise.
  46. COMPILER_WARN_UNUSED_RESULT
  47. inline bool TryAcquire()
  48. {
  49. return Baselib_EventSemaphore_TryAcquire(&m_EventSemaphoreData);
  50. }
  51. // Acquire semaphore.
  52. //
  53. // This function is guaranteed to emit an acquire barrier.
  54. inline void Acquire()
  55. {
  56. return Baselib_EventSemaphore_Acquire(&m_EventSemaphoreData);
  57. }
  58. // Try to acquire semaphore.
  59. //
  60. // If event is set this function return true, otherwise the thread will wait for event to be set or for release to be called.
  61. //
  62. // When semaphore is acquired this function is guaranteed to emit an acquire barrier.
  63. //
  64. // Acquire with a zero timeout differs from TryAcquire in that TryAcquire is guaranteed to be a user space operation
  65. // while Acquire may enter the kernel and cause a context switch.
  66. //
  67. // Timeout passed to this function may be subject to system clock resolution.
  68. // 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.
  69. //
  70. // \returns true if semaphore was acquired.
  71. COMPILER_WARN_UNUSED_RESULT
  72. inline bool TryTimedAcquire(const timeout_ms timeoutInMilliseconds)
  73. {
  74. return Baselib_EventSemaphore_TryTimedAcquire(&m_EventSemaphoreData, timeoutInMilliseconds.count());
  75. }
  76. // Sets the event
  77. //
  78. // Setting the event will cause all waiting threads to wakeup. And will let all future acquiring threads through until Baselib_EventSemaphore_Reset is called.
  79. // 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)
  80. //
  81. // Guaranteed to emit a release barrier.
  82. inline void Set()
  83. {
  84. return Baselib_EventSemaphore_Set(&m_EventSemaphoreData);
  85. }
  86. // Reset event
  87. //
  88. // Resetting the event will cause all future acquiring threads to enter a wait state.
  89. // Has no effect if the EventSemaphore is already in a reset state.
  90. //
  91. // Guaranteed to emit a release barrier.
  92. inline void Reset()
  93. {
  94. return Baselib_EventSemaphore_Reset(&m_EventSemaphoreData);
  95. }
  96. // Reset event and release all waiting threads
  97. //
  98. // Resetting the event will cause all future acquiring threads to enter a wait state.
  99. // If there were any threads waiting (i.e. the EventSemaphore was already in a release state) they will be released.
  100. //
  101. // Guaranteed to emit a release barrier.
  102. inline void ResetAndRelease()
  103. {
  104. return Baselib_EventSemaphore_ResetAndReleaseWaitingThreads(&m_EventSemaphoreData);
  105. }
  106. private:
  107. Baselib_EventSemaphore m_EventSemaphoreData;
  108. };
  109. }
  110. }