| 103 | } |
| 104 | |
| 105 | int futex_wake_private(void* addr1, int nwake) { |
| 106 | if (pthread_once(&init_futex_map_once, InitFutexMap) != 0) { |
| 107 | LOG(FATAL) << "Fail to pthread_once"; |
| 108 | exit(1); |
| 109 | } |
| 110 | std::unique_lock<pthread_mutex_t> mu(s_futex_map_mutex); |
| 111 | auto it = s_futex_map->find(addr1); |
| 112 | if (it == s_futex_map->end()) { |
| 113 | mu.unlock(); |
| 114 | return 0; |
| 115 | } |
| 116 | SimuFutex& simu_futex = it->second; |
| 117 | ++simu_futex.ref; |
| 118 | mu.unlock(); |
| 119 | |
| 120 | int nwakedup = 0; |
| 121 | int rc = 0; |
| 122 | { |
| 123 | std::unique_lock<pthread_mutex_t> mu1(simu_futex.lock); |
| 124 | nwake = (nwake < simu_futex.counts)? nwake: simu_futex.counts; |
| 125 | for (int i = 0; i < nwake; ++i) { |
| 126 | if ((rc = pthread_cond_signal(&simu_futex.cond)) != 0) { |
| 127 | errno = rc; |
| 128 | break; |
| 129 | } else { |
| 130 | ++nwakedup; |
| 131 | } |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | std::unique_lock<pthread_mutex_t> mu2(s_futex_map_mutex); |
| 136 | if (--simu_futex.ref == 0) { |
| 137 | s_futex_map->erase(addr1); |
| 138 | } |
| 139 | mu2.unlock(); |
| 140 | return nwakedup; |
| 141 | } |
| 142 | |
| 143 | } // namespace bthread |
| 144 | |