| 926 | |
| 927 | template <typename Mutex> |
| 928 | BUTIL_FORCE_INLINE int pthread_mutex_unlock_impl(Mutex* mutex) { |
| 929 | // Don't change behavior of unlock when profiler is off. |
| 930 | if (!g_cp || tls_inside_lock) { |
| 931 | // This branch brings an issue that an entry created by |
| 932 | // add_pthread_contention_site may not be cleared. Thus we add a |
| 933 | // 16-bit rolling version in the entry to find out such entry. |
| 934 | return pthread_mutex_unlock_internal(mutex); |
| 935 | } |
| 936 | int64_t unlock_start_ns = 0; |
| 937 | bool miss_in_tls = true; |
| 938 | bthread_contention_site_t saved_csite = {0,0}; |
| 939 | #ifndef DONT_SPEEDUP_PTHREAD_CONTENTION_PROFILER_WITH_TLS |
| 940 | TLSPthreadContentionSites& fast_alt = tls_csites; |
| 941 | for (int i = fast_alt.count - 1; i >= 0; --i) { |
| 942 | if (fast_alt.list[i].mutex == mutex) { |
| 943 | if (is_contention_site_valid(fast_alt.list[i].csite)) { |
| 944 | saved_csite = fast_alt.list[i].csite; |
| 945 | unlock_start_ns = butil::cpuwide_time_ns(); |
| 946 | } |
| 947 | fast_alt.list[i] = fast_alt.list[--fast_alt.count]; |
| 948 | miss_in_tls = false; |
| 949 | break; |
| 950 | } |
| 951 | } |
| 952 | #endif |
| 953 | // Check the map to see if the lock is sampled. Notice that we're still |
| 954 | // inside critical section. |
| 955 | if (miss_in_tls) { |
| 956 | if (remove_pthread_contention_site(mutex, &saved_csite)) { |
| 957 | unlock_start_ns = butil::cpuwide_time_ns(); |
| 958 | } |
| 959 | } |
| 960 | const int rc = pthread_mutex_unlock_internal(mutex); |
| 961 | // [Outside lock] |
| 962 | if (unlock_start_ns) { |
| 963 | const int64_t unlock_end_ns = butil::cpuwide_time_ns(); |
| 964 | saved_csite.duration_ns += unlock_end_ns - unlock_start_ns; |
| 965 | submit_contention(saved_csite, unlock_end_ns); |
| 966 | } |
| 967 | return rc; |
| 968 | } |
| 969 | |
| 970 | } |
| 971 |
no test coverage detected