| 61 | } |
| 62 | |
| 63 | int futex_wait_private(void* addr1, int expected, const timespec* timeout) { |
| 64 | if (pthread_once(&init_futex_map_once, InitFutexMap) != 0) { |
| 65 | LOG(FATAL) << "Fail to pthread_once"; |
| 66 | exit(1); |
| 67 | } |
| 68 | std::unique_lock<pthread_mutex_t> mu(s_futex_map_mutex); |
| 69 | SimuFutex& simu_futex = (*s_futex_map)[addr1]; |
| 70 | ++simu_futex.ref; |
| 71 | mu.unlock(); |
| 72 | |
| 73 | int rc = 0; |
| 74 | { |
| 75 | std::unique_lock<pthread_mutex_t> mu1(simu_futex.lock); |
| 76 | if (static_cast<butil::atomic<int>*>(addr1)->load() == expected) { |
| 77 | ++simu_futex.counts; |
| 78 | if (timeout) { |
| 79 | timespec timeout_abs = butil::timespec_from_now(*timeout); |
| 80 | if ((rc = pthread_cond_timedwait(&simu_futex.cond, &simu_futex.lock, &timeout_abs)) != 0) { |
| 81 | errno = rc; |
| 82 | rc = -1; |
| 83 | } |
| 84 | } else { |
| 85 | if ((rc = pthread_cond_wait(&simu_futex.cond, &simu_futex.lock)) != 0) { |
| 86 | errno = rc; |
| 87 | rc = -1; |
| 88 | } |
| 89 | } |
| 90 | --simu_futex.counts; |
| 91 | } else { |
| 92 | errno = EAGAIN; |
| 93 | rc = -1; |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | std::unique_lock<pthread_mutex_t> mu1(s_futex_map_mutex); |
| 98 | if (--simu_futex.ref == 0) { |
| 99 | s_futex_map->erase(addr1); |
| 100 | } |
| 101 | mu1.unlock(); |
| 102 | return rc; |
| 103 | } |
| 104 | |
| 105 | int futex_wake_private(void* addr1, int nwake) { |
| 106 | if (pthread_once(&init_futex_map_once, InitFutexMap) != 0) { |
nothing calls this directly
no test coverage detected