| 584 | |
| 585 | template <typename Mutex> |
| 586 | inline bthread_contention_site_t* |
| 587 | add_pthread_contention_site(const Mutex* mutex) { |
| 588 | MutexMapEntry& entry = g_mutex_map[hash_mutex_ptr(mutex) & (MUTEX_MAP_SIZE - 1)]; |
| 589 | butil::static_atomic<uint64_t>& m = entry.versioned_mutex; |
| 590 | uint64_t expected = m.load(butil::memory_order_relaxed); |
| 591 | // If the entry is not used or used by previous profiler, try to CAS it. |
| 592 | if (expected == 0 || |
| 593 | (expected >> PTR_BITS) != (g_cp_version & ((1 << (64 - PTR_BITS)) - 1))) { |
| 594 | uint64_t desired = (g_cp_version << PTR_BITS) | (uint64_t)mutex; |
| 595 | if (m.compare_exchange_strong( |
| 596 | expected, desired, butil::memory_order_acquire)) { |
| 597 | return &entry.csite; |
| 598 | } |
| 599 | } |
| 600 | g_nconflicthash.fetch_add(1, butil::memory_order_relaxed); |
| 601 | return NULL; |
| 602 | } |
| 603 | |
| 604 | template <typename Mutex> |
| 605 | inline bool remove_pthread_contention_site(const Mutex* mutex, |
no test coverage detected