futex_like.h 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #pragma once
  2. #include <library/cpp/deprecated/atomic/atomic.h>
  3. #include <util/system/condvar.h>
  4. #include <util/system/mutex.h>
  5. #include <util/system/platform.h>
  6. class TFutexLike {
  7. private:
  8. #ifdef _linux_
  9. int Value;
  10. #else
  11. TAtomic Value;
  12. TMutex Mutex;
  13. TCondVar CondVar;
  14. #endif
  15. public:
  16. TFutexLike()
  17. : Value(0)
  18. {
  19. }
  20. int AddAndGet(int add) {
  21. #ifdef _linux_
  22. //return __atomic_add_fetch(&Value, add, __ATOMIC_SEQ_CST);
  23. return __sync_add_and_fetch(&Value, add);
  24. #else
  25. return AtomicAdd(Value, add);
  26. #endif
  27. }
  28. int GetAndAdd(int add) {
  29. return AddAndGet(add) - add;
  30. }
  31. // until we have modern GCC
  32. #if 0
  33. int GetAndSet(int newValue) {
  34. #ifdef _linux_
  35. return __atomic_exchange_n(&Value, newValue, __ATOMIC_SEQ_CST);
  36. #else
  37. return AtomicSwap(&Value, newValue);
  38. #endif
  39. }
  40. #endif
  41. int Get() {
  42. #ifdef _linux_
  43. //return __atomic_load_n(&Value, __ATOMIC_SEQ_CST);
  44. __sync_synchronize();
  45. return Value;
  46. #else
  47. return AtomicGet(Value);
  48. #endif
  49. }
  50. void Set(int newValue) {
  51. #ifdef _linux_
  52. //__atomic_store_n(&Value, newValue, __ATOMIC_SEQ_CST);
  53. Value = newValue;
  54. __sync_synchronize();
  55. #else
  56. AtomicSet(Value, newValue);
  57. #endif
  58. }
  59. int GetAndIncrement() {
  60. return AddAndGet(1) - 1;
  61. }
  62. int IncrementAndGet() {
  63. return AddAndGet(1);
  64. }
  65. int GetAndDecrement() {
  66. return AddAndGet(-1) + 1;
  67. }
  68. int DecrementAndGet() {
  69. return AddAndGet(-1);
  70. }
  71. void Wake(size_t count = Max<size_t>());
  72. void Wait(int expected);
  73. };