futex.cpp 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. #include "futex.h"
  2. #ifdef _linux_
  3. #include <linux/futex.h>
  4. #include <sys/time.h>
  5. #include <sys/syscall.h>
  6. #endif
  7. namespace NYT::NThreading {
  8. ////////////////////////////////////////////////////////////////////////////////
  9. #ifdef _linux_
  10. namespace {
  11. int Futex(
  12. int* uaddr,
  13. int op,
  14. int val,
  15. const timespec* timeout,
  16. int* uaddr2,
  17. int val3)
  18. {
  19. return ::syscall(SYS_futex, uaddr, op, val, timeout, uaddr2, val3);
  20. }
  21. } // namespace
  22. int FutexWait(int* addr, int value, TDuration timeout)
  23. {
  24. struct timespec timeoutSpec;
  25. if (timeout != TDuration::Max()) {
  26. timeoutSpec.tv_sec = timeout.Seconds();
  27. timeoutSpec.tv_nsec = (timeout - TDuration::Seconds(timeout.Seconds())).MicroSeconds() * 1000;
  28. }
  29. return Futex(
  30. addr,
  31. FUTEX_WAIT_PRIVATE,
  32. value,
  33. timeout != TDuration::Max() ? &timeoutSpec : nullptr,
  34. nullptr,
  35. 0);
  36. }
  37. int FutexWake(int* addr, int count)
  38. {
  39. return Futex(
  40. addr,
  41. FUTEX_WAKE_PRIVATE,
  42. count,
  43. nullptr,
  44. nullptr,
  45. 0);
  46. }
  47. #endif
  48. ////////////////////////////////////////////////////////////////////////////////
  49. } // namespace NYT::NThreading