| 603 | |
| 604 | template <typename Mutex> |
| 605 | inline bool remove_pthread_contention_site(const Mutex* mutex, |
| 606 | bthread_contention_site_t* saved_csite) { |
| 607 | MutexMapEntry& entry = g_mutex_map[hash_mutex_ptr(mutex) & (MUTEX_MAP_SIZE - 1)]; |
| 608 | butil::static_atomic<uint64_t>& m = entry.versioned_mutex; |
| 609 | if ((m.load(butil::memory_order_relaxed) & ((((uint64_t)1) << PTR_BITS) - 1)) |
| 610 | != (uint64_t)mutex) { |
| 611 | // This branch should be the most common case since most locks are |
| 612 | // neither contended nor sampled. We have one memory indirection and |
| 613 | // several bitwise operations here, the cost should be ~ 5-50ns |
| 614 | return false; |
| 615 | } |
| 616 | // Although this branch is inside a contended lock, we should also make it |
| 617 | // as simple as possible because altering the critical section too much |
| 618 | // may make unpredictable impact to thread interleaving status, which |
| 619 | // makes profiling result less accurate. |
| 620 | *saved_csite = entry.csite; |
| 621 | make_contention_site_invalid(&entry.csite); |
| 622 | m.store(0, butil::memory_order_release); |
| 623 | return true; |
| 624 | } |
| 625 | |
| 626 | // Submit the contention along with the callsite('s stacktrace) |
| 627 | void submit_contention(const bthread_contention_site_t& csite, int64_t now_ns) { |
no test coverage detected