Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <linux/futex.h>
- #include <sys/syscall.h>
- #include <sys/time.h>
- #include <unistd.h>
- #include <atomic>
- #include <cstdint>
- // Atomically do the following:
- // if (*val_ue == expected_val_ue) {
- // sleep_on_address(value)
- // if (*(uint64_t*)addr == expected_value) {
- // sleep_on_address(addr)
- // }
- void FutexWait(std::atomic<int> *value, int expected_value) {
- syscall(SYS_futex, value, FUTEX_WAIT_PRIVATE, expected_value, nullptr, nullptr, 0);
- }
- void FutexWake(std::atomic<int> *value, int count) {
- syscall(SYS_futex, value, FUTEX_WAKE_PRIVATE, count, nullptr, nullptr, 0);
- }
- class Mutex {
- public:
- Mutex() : val_(0) {
- }
- void Lock() {
- int c = 0;
- if (!val_.compare_exchange_strong(c, 1)) {
- c = val_.exchange(2);
- while (c != 0) {
- FutexWait(&val_, 2);
- c = val_.exchange(2);
- }
- }
- }
- void Unlock() {
- if (val_.fetch_sub(1) != 1) {
- val_ = 0;
- FutexWake(&val_, 1);
- }
- }
- private:
- std::atomic<int> val_;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement