Advertisement
Ilya_konstantinov

Untitled

Dec 7th, 2024
40
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.13 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <linux/futex.h>
  4. #include <sys/syscall.h>
  5. #include <sys/time.h>
  6. #include <unistd.h>
  7.  
  8. #include <atomic>
  9. #include <cstdint>
  10.  
  11. // Atomically do the following:
  12. //    if (*val_ue == expected_val_ue) {
  13. //        sleep_on_address(value)
  14. //    if (*(uint64_t*)addr == expected_value) {
  15. //        sleep_on_address(addr)
  16. //    }
  17.  
  18. void FutexWait(std::atomic<int> *value, int expected_value) {
  19.     syscall(SYS_futex, value, FUTEX_WAIT_PRIVATE, expected_value, nullptr, nullptr, 0);
  20. }
  21.  
  22. void FutexWake(std::atomic<int> *value, int count) {
  23.     syscall(SYS_futex, value, FUTEX_WAKE_PRIVATE, count, nullptr, nullptr, 0);
  24. }
  25.  
  26. class Mutex {
  27. public:
  28.     Mutex() : val_(0) {
  29.     }
  30.  
  31.     void Lock() {
  32.         int c = 0;
  33.         if (!val_.compare_exchange_strong(c, 1)) {
  34.             c = val_.exchange(2);
  35.             while (c != 0) {
  36.                 FutexWait(&val_, 2);
  37.                 c = val_.exchange(2);
  38.             }
  39.         }
  40.     }
  41.     void Unlock() {
  42.         if (val_.fetch_sub(1) != 1) {
  43.             val_ = 0;
  44.             FutexWake(&val_, 1);
  45.         }
  46.     }
  47.  
  48. private:
  49.     std::atomic<int> val_;
  50. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement