Semaphore.h 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2023 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. JPH_SUPPRESS_WARNINGS_STD_BEGIN
  6. #include <atomic>
  7. #include <mutex>
  8. #include <condition_variable>
  9. JPH_SUPPRESS_WARNINGS_STD_END
  10. JPH_NAMESPACE_BEGIN
  11. // Things we're using from STL
  12. using std::atomic;
  13. using std::mutex;
  14. using std::condition_variable;
  15. /// Implements a semaphore
  16. /// When we switch to C++20 we can use counting_semaphore to unify this
  17. class JPH_EXPORT Semaphore
  18. {
  19. public:
  20. /// Constructor
  21. Semaphore();
  22. ~Semaphore();
  23. /// Release the semaphore, signalling the thread waiting on the barrier that there may be work
  24. void Release(uint inNumber = 1);
  25. /// Acquire the semaphore inNumber times
  26. void Acquire(uint inNumber = 1);
  27. /// Get the current value of the semaphore
  28. inline int GetValue() const { return mCount; }
  29. private:
  30. #ifdef JPH_PLATFORM_WINDOWS
  31. // On windows we use a semaphore object since it is more efficient than a lock and a condition variable
  32. alignas(JPH_CACHE_LINE_SIZE) atomic<int> mCount { 0 }; ///< We increment mCount for every release, to acquire we decrement the count. If the count is negative we know that we are waiting on the actual semaphore.
  33. void * mSemaphore; ///< The semaphore is an expensive construct so we only acquire/release it if we know that we need to wait/have waiting threads
  34. #else
  35. // Other platforms: Emulate a semaphore using a mutex, condition variable and count
  36. mutex mLock;
  37. condition_variable mWaitVariable;
  38. int mCount = 0;
  39. #endif
  40. };
  41. JPH_NAMESPACE_END