| 703 | static MutexOwnerMapEntry g_mutex_owner_map[MUTEX_MAP_SIZE] = {}; // zero-initialize |
| 704 | |
| 705 | static void InitMutexOwnerMapEntry(pthread_mutex_t* mutex, |
| 706 | const pthread_mutexattr_t* mutexattr) { |
| 707 | int type = PTHREAD_MUTEX_DEFAULT; |
| 708 | if (NULL != mutexattr) { |
| 709 | pthread_mutexattr_gettype(mutexattr, &type); |
| 710 | } |
| 711 | // Only normal mutexes are tracked. |
| 712 | if (type != PTHREAD_MUTEX_NORMAL) { |
| 713 | return; |
| 714 | } |
| 715 | |
| 716 | // Fast path: If the hash entry is not used, use it. |
| 717 | MutexOwnerMapEntry& hash_entry = |
| 718 | g_mutex_owner_map[hash_mutex_ptr(mutex) & (MUTEX_MAP_SIZE - 1)]; |
| 719 | if (!hash_entry.valid.exchange(true, butil::memory_order_relaxed)) { |
| 720 | MUTEX_RESET_OWNER_COMMON(hash_entry.owner); |
| 721 | return; |
| 722 | } |
| 723 | |
| 724 | // Slow path: Find an unused entry. |
| 725 | for (auto& entry : g_mutex_owner_map) { |
| 726 | if (!entry.valid.exchange(true, butil::memory_order_relaxed)) { |
| 727 | MUTEX_RESET_OWNER_COMMON(entry.owner); |
| 728 | return; |
| 729 | } |
| 730 | } |
| 731 | } |
| 732 | |
| 733 | static BUTIL_FORCE_INLINE |
| 734 | MutexOwnerMapEntry* FindMutexOwnerMapEntry(pthread_mutex_t* mutex) { |
nothing calls this directly
no test coverage detected