semaphore.cc 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #include "semaphore.h"
  2. #include "os_compat.h"
  3. #include <unistd.h>
  4. #include <sys/syscall.h>
  5. #include <linux/futex.h>
  6. #include <limits.h>
  7. Semaphore::Semaphore(int count)
  8. : _count(count)
  9. , _numWaiting(0)
  10. , _futx(0)
  11. {
  12. }
  13. Semaphore::Semaphore()
  14. : _count(0)
  15. , _numWaiting(0)
  16. , _futx(0)
  17. {
  18. }
  19. Semaphore::~Semaphore()
  20. {
  21. }
  22. void Semaphore::wait()
  23. {
  24. _lock.acquire();
  25. while (_count <= 0)
  26. {
  27. _numWaiting ++;
  28. _futx = 0;
  29. _lock.release();
  30. syscall(SYS_futex, (void*) &_futx, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, NULL, NULL, 0);
  31. _lock.acquire();
  32. _numWaiting --;
  33. }
  34. _count --;
  35. _lock.release();
  36. }
  37. void Semaphore::signal()
  38. {
  39. _lock.acquire();
  40. _count ++;
  41. if (_numWaiting > 0)
  42. {
  43. _futx = 1;
  44. syscall(SYS_futex, (void*) &_futx, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1, NULL, NULL, 0);
  45. }
  46. _lock.release();
  47. }
  48. void Semaphore::broadcast()
  49. {
  50. _lock.acquire();
  51. _count ++;
  52. if (_numWaiting > 0)
  53. {
  54. _futx = 1;
  55. syscall(SYS_futex, (void*) &_futx, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, INT_MAX, NULL, NULL, 0);
  56. }
  57. _lock.release();
  58. }