| 1211 | } |
| 1212 | |
| 1213 | static int bthread_mutex_lock_impl(bthread_mutex_t* __restrict m, |
| 1214 | const struct timespec* __restrict abstime) { |
| 1215 | if (0 == bthread::mutex_trylock_impl(m)) { |
| 1216 | return 0; |
| 1217 | } |
| 1218 | // Don't sample when contention profiler is off. |
| 1219 | if (!bthread::g_cp) { |
| 1220 | return bthread::mutex_lock_contended_impl(m, abstime); |
| 1221 | } |
| 1222 | // Ask Collector if this (contended) locking should be sampled. |
| 1223 | const size_t sampling_range = |
| 1224 | m->enable_csite ? bvar::is_collectable(&bthread::g_cp_sl) : bvar::INVALID_SAMPLING_RANGE; |
| 1225 | if (!bvar::is_sampling_range_valid(sampling_range)) { // Don't sample |
| 1226 | return bthread::mutex_lock_contended_impl(m, abstime); |
| 1227 | } |
| 1228 | // Start sampling. |
| 1229 | const int64_t start_ns = butil::cpuwide_time_ns(); |
| 1230 | // NOTE: Don't modify m->csite outside lock since multiple threads are |
| 1231 | // still contending with each other. |
| 1232 | const int rc = bthread::mutex_lock_contended_impl(m, abstime); |
| 1233 | if (!rc) { // Inside lock |
| 1234 | m->csite.duration_ns = butil::cpuwide_time_ns() - start_ns; |
| 1235 | m->csite.sampling_range = sampling_range; |
| 1236 | } else if (rc == ETIMEDOUT) { |
| 1237 | // Failed to lock due to ETIMEDOUT, submit the elapse directly. |
| 1238 | const int64_t end_ns = butil::cpuwide_time_ns(); |
| 1239 | const bthread_contention_site_t csite = {end_ns - start_ns, sampling_range}; |
| 1240 | bthread::submit_contention(csite, end_ns); |
| 1241 | } |
| 1242 | return rc; |
| 1243 | } |
| 1244 | |
| 1245 | int bthread_mutex_lock(bthread_mutex_t* m) { |
| 1246 | return bthread_mutex_lock_impl(m, NULL); |
no test coverage detected