futex_like.h 1.5 KB

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