From c1f7102fbe0826b142414d250f1fa533842b09b8 Mon Sep 17 00:00:00 2001 From: Xinyi Zou Date: Tue, 15 Oct 2024 17:12:52 +0800 Subject: [PATCH] 2 --- thirdparty/download-thirdparty.sh | 2 +- .../brpc-1.4.0-no-pthread_mutex-hook.patch | 419 ++++++++++++++++++ 2 files changed, 420 insertions(+), 1 deletion(-) create mode 100644 thirdparty/patches/brpc-1.4.0-no-pthread_mutex-hook.patch diff --git a/thirdparty/download-thirdparty.sh b/thirdparty/download-thirdparty.sh index 1bebdac7769f85..f6395e5c8b6cf4 100755 --- a/thirdparty/download-thirdparty.sh +++ b/thirdparty/download-thirdparty.sh @@ -454,7 +454,7 @@ if [[ " ${TP_ARCHIVES[*]} " =~ " BRPC " ]]; then if [[ ! -f "${PATCHED_MARK}" ]]; then for patch_file in "${TP_PATCH_DIR}"/brpc-*; do echo "patch ${patch_file}" - patch -p1 <"${patch_file}" + patch -p1 <"${patch_file}" --ignore-whitespace done touch "${PATCHED_MARK}" fi diff --git a/thirdparty/patches/brpc-1.4.0-no-pthread_mutex-hook.patch b/thirdparty/patches/brpc-1.4.0-no-pthread_mutex-hook.patch new file mode 100644 index 00000000000000..d44884a5fb3fb1 --- /dev/null +++ b/thirdparty/patches/brpc-1.4.0-no-pthread_mutex-hook.patch @@ -0,0 +1,419 @@ +diff --git a/src/brpc/builtin/hotspots_service.cpp b/src/brpc/builtin/hotspots_service.cpp +index c7577320..a5575b39 100644 +--- a/src/brpc/builtin/hotspots_service.cpp ++++ b/src/brpc/builtin/hotspots_service.cpp +@@ -760,8 +760,7 @@ static void DoProfiling(ProfilingType type, + ProfilerStop(); + } else if (type == PROFILING_CONTENTION) { + if (!bthread::ContentionProfilerStart(prof_name)) { +- os << "Another profiler (not via /hotspots/contention) is running, " +- "try again later" << (use_html ? "" : "\n"); ++ os << "Contention profiler has been disabled by doris\n"; + os.move_to(resp); + cntl->http_response().set_status_code(HTTP_STATUS_SERVICE_UNAVAILABLE); + return NotifyWaiters(type, cntl, view); +@@ -855,6 +854,12 @@ static void StartProfiling(ProfilingType type, + enabled = IsHeapProfilerEnabled(); + } + const char* const type_str = ProfilingType2String(type); ++ if (type == PROFILING_CONTENTION) { ++ os << "Error: " << type_str << " profiler is disabled by doris.\n"; ++ os.move_to(cntl->response_attachment()); ++ cntl->http_response().set_status_code(HTTP_STATUS_SERVICE_UNAVAILABLE); ++ return; ++ } + + #if defined(OS_MACOSX) + if (!has_GOOGLE_PPROF_BINARY_PATH()) { +diff --git a/src/brpc/builtin/pprof_service.cpp b/src/brpc/builtin/pprof_service.cpp +index eba71377..48fa5560 100644 +--- a/src/brpc/builtin/pprof_service.cpp ++++ b/src/brpc/builtin/pprof_service.cpp +@@ -188,7 +188,7 @@ void PProfService::contention( + return; + } + if (!bthread::ContentionProfilerStart(prof_name)) { +- cntl->SetFailed(EAGAIN, "Another profiler is running, try again later"); ++ cntl->SetFailed(EAGAIN, "Contention profiler has been disabled by doris"); + return; + } + if (bthread_usleep(sleep_sec * 1000000L) != 0) { +diff --git a/src/bthread/mutex.cpp b/src/bthread/mutex.cpp +index 3d38ef93..aad189bc 100644 +--- a/src/bthread/mutex.cpp ++++ b/src/bthread/mutex.cpp +@@ -305,6 +305,8 @@ static int64_t get_nconflicthash(void*) { + + // Start profiling contention. + bool ContentionProfilerStart(const char* filename) { ++ LOG(ERROR) << "Contention profiler is disabled by doris."; ++ return false; + if (filename == NULL) { + LOG(ERROR) << "Parameter [filename] is NULL"; + return false; +@@ -364,77 +366,79 @@ make_contention_site_invalid(bthread_contention_site_t* cs) { + cs->sampling_range = 0; + } + +-// Replace pthread_mutex_lock and pthread_mutex_unlock: +-// First call to sys_pthread_mutex_lock sets sys_pthread_mutex_lock to the +-// real function so that next calls go to the real function directly. This +-// technique avoids calling pthread_once each time. +-typedef int (*MutexOp)(pthread_mutex_t*); +-int first_sys_pthread_mutex_lock(pthread_mutex_t* mutex); +-int first_sys_pthread_mutex_unlock(pthread_mutex_t* mutex); +-static MutexOp sys_pthread_mutex_lock = first_sys_pthread_mutex_lock; +-static MutexOp sys_pthread_mutex_unlock = first_sys_pthread_mutex_unlock; +-static pthread_once_t init_sys_mutex_lock_once = PTHREAD_ONCE_INIT; +- +-// dlsym may call malloc to allocate space for dlerror and causes contention +-// profiler to deadlock at boostraping when the program is linked with +-// libunwind. The deadlock bt: +-// #0 0x00007effddc99b80 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81 +-// #1 0x00000000004b4df7 in butil::internal::SpinLockDelay(int volatile*, int, int) () +-// #2 0x00000000004b4d57 in SpinLock::SlowLock() () +-// #3 0x00000000004b4a63 in tcmalloc::ThreadCache::InitModule() () +-// #4 0x00000000004aa2b5 in tcmalloc::ThreadCache::GetCache() () +-// #5 0x000000000040c6c5 in (anonymous namespace)::do_malloc_no_errno(unsigned long) [clone.part.16] () +-// #6 0x00000000006fc125 in tc_calloc () +-// #7 0x00007effdd245690 in _dlerror_run (operate=operate@entry=0x7effdd245130 , args=args@entry=0x7fff483dedf0) at dlerror.c:141 +-// #8 0x00007effdd245198 in __dlsym (handle=, name=) at dlsym.c:70 +-// #9 0x0000000000666517 in bthread::init_sys_mutex_lock () at bthread/mutex.cpp:358 +-// #10 0x00007effddc97a90 in pthread_once () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S:103 +-// #11 0x000000000066649f in bthread::first_sys_pthread_mutex_lock (mutex=0xbaf880 <_ULx86_64_lock>) at bthread/mutex.cpp:366 +-// #12 0x00000000006678bc in pthread_mutex_lock_impl (mutex=0xbaf880 <_ULx86_64_lock>) at bthread/mutex.cpp:489 +-// #13 pthread_mutex_lock (__mutex=__mutex@entry=0xbaf880 <_ULx86_64_lock>) at bthread/mutex.cpp:751 +-// #14 0x00000000004c6ea1 in _ULx86_64_init () at x86_64/Gglobal.c:83 +-// #15 0x00000000004c44fb in _ULx86_64_init_local (cursor=0x7fff483df340, uc=0x7fff483def90) at x86_64/Ginit_local.c:47 +-// #16 0x00000000004b5012 in GetStackTrace(void**, int, int) () +-// #17 0x00000000004b2095 in tcmalloc::PageHeap::GrowHeap(unsigned long) () +-// #18 0x00000000004b23a3 in tcmalloc::PageHeap::New(unsigned long) () +-// #19 0x00000000004ad457 in tcmalloc::CentralFreeList::Populate() () +-// #20 0x00000000004ad628 in tcmalloc::CentralFreeList::FetchFromSpansSafe() () +-// #21 0x00000000004ad6a3 in tcmalloc::CentralFreeList::RemoveRange(void**, void**, int) () +-// #22 0x00000000004b3ed3 in tcmalloc::ThreadCache::FetchFromCentralCache(unsigned long, unsigned long) () +-// #23 0x00000000006fbb9a in tc_malloc () +-// Call _dl_sym which is a private function in glibc to workaround the malloc +-// causing deadlock temporarily. This fix is hardly portable. +- +-static void init_sys_mutex_lock() { +-#if defined(OS_LINUX) +- // TODO: may need dlvsym when GLIBC has multiple versions of a same symbol. +- // http://blog.fesnel.com/blog/2009/08/25/preloading-with-multiple-symbol-versions +- if (_dl_sym) { +- sys_pthread_mutex_lock = (MutexOp)_dl_sym(RTLD_NEXT, "pthread_mutex_lock", (void*)init_sys_mutex_lock); +- sys_pthread_mutex_unlock = (MutexOp)_dl_sym(RTLD_NEXT, "pthread_mutex_unlock", (void*)init_sys_mutex_lock); +- } else { +- // _dl_sym may be undefined reference in some system, fallback to dlsym +- sys_pthread_mutex_lock = (MutexOp)dlsym(RTLD_NEXT, "pthread_mutex_lock"); +- sys_pthread_mutex_unlock = (MutexOp)dlsym(RTLD_NEXT, "pthread_mutex_unlock"); +- } +-#elif defined(OS_MACOSX) +- // TODO: look workaround for dlsym on mac +- sys_pthread_mutex_lock = (MutexOp)dlsym(RTLD_NEXT, "pthread_mutex_lock"); +- sys_pthread_mutex_unlock = (MutexOp)dlsym(RTLD_NEXT, "pthread_mutex_unlock"); +-#endif +-} +- +-// Make sure pthread functions are ready before main(). +-const int ALLOW_UNUSED dummy = pthread_once(&init_sys_mutex_lock_once, init_sys_mutex_lock); +- +-int first_sys_pthread_mutex_lock(pthread_mutex_t* mutex) { +- pthread_once(&init_sys_mutex_lock_once, init_sys_mutex_lock); +- return sys_pthread_mutex_lock(mutex); +-} +-int first_sys_pthread_mutex_unlock(pthread_mutex_t* mutex) { +- pthread_once(&init_sys_mutex_lock_once, init_sys_mutex_lock); +- return sys_pthread_mutex_unlock(mutex); +-} ++// #ifndef NO_PTHREAD_MUTEX_HOOK ++// // Replace pthread_mutex_lock and pthread_mutex_unlock: ++// // First call to sys_pthread_mutex_lock sets sys_pthread_mutex_lock to the ++// // real function so that next calls go to the real function directly. This ++// // technique avoids calling pthread_once each time. ++// typedef int (*MutexOp)(pthread_mutex_t*); ++// int first_sys_pthread_mutex_lock(pthread_mutex_t* mutex); ++// int first_sys_pthread_mutex_unlock(pthread_mutex_t* mutex); ++// static MutexOp sys_pthread_mutex_lock = first_sys_pthread_mutex_lock; ++// static MutexOp sys_pthread_mutex_unlock = first_sys_pthread_mutex_unlock; ++// static pthread_once_t init_sys_mutex_lock_once = PTHREAD_ONCE_INIT; ++ ++// // dlsym may call malloc to allocate space for dlerror and causes contention ++// // profiler to deadlock at boostraping when the program is linked with ++// // libunwind. The deadlock bt: ++// // #0 0x00007effddc99b80 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81 ++// // #1 0x00000000004b4df7 in butil::internal::SpinLockDelay(int volatile*, int, int) () ++// // #2 0x00000000004b4d57 in SpinLock::SlowLock() () ++// // #3 0x00000000004b4a63 in tcmalloc::ThreadCache::InitModule() () ++// // #4 0x00000000004aa2b5 in tcmalloc::ThreadCache::GetCache() () ++// // #5 0x000000000040c6c5 in (anonymous namespace)::do_malloc_no_errno(unsigned long) [clone.part.16] () ++// // #6 0x00000000006fc125 in tc_calloc () ++// // #7 0x00007effdd245690 in _dlerror_run (operate=operate@entry=0x7effdd245130 , args=args@entry=0x7fff483dedf0) at dlerror.c:141 ++// // #8 0x00007effdd245198 in __dlsym (handle=, name=) at dlsym.c:70 ++// // #9 0x0000000000666517 in bthread::init_sys_mutex_lock () at bthread/mutex.cpp:358 ++// // #10 0x00007effddc97a90 in pthread_once () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S:103 ++// // #11 0x000000000066649f in bthread::first_sys_pthread_mutex_lock (mutex=0xbaf880 <_ULx86_64_lock>) at bthread/mutex.cpp:366 ++// // #12 0x00000000006678bc in pthread_mutex_lock_impl (mutex=0xbaf880 <_ULx86_64_lock>) at bthread/mutex.cpp:489 ++// // #13 pthread_mutex_lock (__mutex=__mutex@entry=0xbaf880 <_ULx86_64_lock>) at bthread/mutex.cpp:751 ++// // #14 0x00000000004c6ea1 in _ULx86_64_init () at x86_64/Gglobal.c:83 ++// // #15 0x00000000004c44fb in _ULx86_64_init_local (cursor=0x7fff483df340, uc=0x7fff483def90) at x86_64/Ginit_local.c:47 ++// // #16 0x00000000004b5012 in GetStackTrace(void**, int, int) () ++// // #17 0x00000000004b2095 in tcmalloc::PageHeap::GrowHeap(unsigned long) () ++// // #18 0x00000000004b23a3 in tcmalloc::PageHeap::New(unsigned long) () ++// // #19 0x00000000004ad457 in tcmalloc::CentralFreeList::Populate() () ++// // #20 0x00000000004ad628 in tcmalloc::CentralFreeList::FetchFromSpansSafe() () ++// // #21 0x00000000004ad6a3 in tcmalloc::CentralFreeList::RemoveRange(void**, void**, int) () ++// // #22 0x00000000004b3ed3 in tcmalloc::ThreadCache::FetchFromCentralCache(unsigned long, unsigned long) () ++// // #23 0x00000000006fbb9a in tc_malloc () ++// // Call _dl_sym which is a private function in glibc to workaround the malloc ++// // causing deadlock temporarily. This fix is hardly portable. ++ ++// static void init_sys_mutex_lock() { ++// #if defined(OS_LINUX) ++// // TODO: may need dlvsym when GLIBC has multiple versions of a same symbol. ++// // http://blog.fesnel.com/blog/2009/08/25/preloading-with-multiple-symbol-versions ++// if (_dl_sym) { ++// sys_pthread_mutex_lock = (MutexOp)_dl_sym(RTLD_NEXT, "pthread_mutex_lock", (void*)init_sys_mutex_lock); ++// sys_pthread_mutex_unlock = (MutexOp)_dl_sym(RTLD_NEXT, "pthread_mutex_unlock", (void*)init_sys_mutex_lock); ++// } else { ++// // _dl_sym may be undefined reference in some system, fallback to dlsym ++// sys_pthread_mutex_lock = (MutexOp)dlsym(RTLD_NEXT, "pthread_mutex_lock"); ++// sys_pthread_mutex_unlock = (MutexOp)dlsym(RTLD_NEXT, "pthread_mutex_unlock"); ++// } ++// #elif defined(OS_MACOSX) ++// // TODO: look workaround for dlsym on mac ++// sys_pthread_mutex_lock = (MutexOp)dlsym(RTLD_NEXT, "pthread_mutex_lock"); ++// sys_pthread_mutex_unlock = (MutexOp)dlsym(RTLD_NEXT, "pthread_mutex_unlock"); ++// #endif ++// } ++ ++// // Make sure pthread functions are ready before main(). ++// const int ALLOW_UNUSED dummy = pthread_once(&init_sys_mutex_lock_once, init_sys_mutex_lock); ++ ++// int first_sys_pthread_mutex_lock(pthread_mutex_t* mutex) { ++// pthread_once(&init_sys_mutex_lock_once, init_sys_mutex_lock); ++// return sys_pthread_mutex_lock(mutex); ++// } ++// int first_sys_pthread_mutex_unlock(pthread_mutex_t* mutex) { ++// pthread_once(&init_sys_mutex_lock_once, init_sys_mutex_lock); ++// return sys_pthread_mutex_unlock(mutex); ++// } ++// #endif + + inline uint64_t hash_mutex_ptr(const pthread_mutex_t* m) { + return butil::fmix64((uint64_t)m); +@@ -524,99 +528,101 @@ void submit_contention(const bthread_contention_site_t& csite, int64_t now_ns) { + tls_inside_lock = false; + } + +-BUTIL_FORCE_INLINE int pthread_mutex_lock_impl(pthread_mutex_t* mutex) { +- // Don't change behavior of lock when profiler is off. +- if (!g_cp || +- // collecting code including backtrace() and submit() may call +- // pthread_mutex_lock and cause deadlock. Don't sample. +- tls_inside_lock) { +- return sys_pthread_mutex_lock(mutex); +- } +- // Don't slow down non-contended locks. +- int rc = pthread_mutex_trylock(mutex); +- if (rc != EBUSY) { +- return rc; +- } +- // Ask bvar::Collector if this (contended) locking should be sampled +- const size_t sampling_range = bvar::is_collectable(&g_cp_sl); +- +- bthread_contention_site_t* csite = NULL; +-#ifndef DONT_SPEEDUP_PTHREAD_CONTENTION_PROFILER_WITH_TLS +- TLSPthreadContentionSites& fast_alt = tls_csites; +- if (fast_alt.cp_version != g_cp_version) { +- fast_alt.cp_version = g_cp_version; +- fast_alt.count = 0; +- } +- if (fast_alt.count < TLS_MAX_COUNT) { +- MutexAndContentionSite& entry = fast_alt.list[fast_alt.count++]; +- entry.mutex = mutex; +- csite = &entry.csite; +- if (!sampling_range) { +- make_contention_site_invalid(&entry.csite); +- return sys_pthread_mutex_lock(mutex); +- } +- } +-#endif +- if (!sampling_range) { // don't sample +- return sys_pthread_mutex_lock(mutex); +- } +- // Lock and monitor the waiting time. +- const int64_t start_ns = butil::cpuwide_time_ns(); +- rc = sys_pthread_mutex_lock(mutex); +- if (!rc) { // Inside lock +- if (!csite) { +- csite = add_pthread_contention_site(mutex); +- if (csite == NULL) { +- return rc; +- } +- } +- csite->duration_ns = butil::cpuwide_time_ns() - start_ns; +- csite->sampling_range = sampling_range; +- } // else rare +- return rc; +-} +- +-BUTIL_FORCE_INLINE int pthread_mutex_unlock_impl(pthread_mutex_t* mutex) { +- // Don't change behavior of unlock when profiler is off. +- if (!g_cp || tls_inside_lock) { +- // This branch brings an issue that an entry created by +- // add_pthread_contention_site may not be cleared. Thus we add a +- // 16-bit rolling version in the entry to find out such entry. +- return sys_pthread_mutex_unlock(mutex); +- } +- int64_t unlock_start_ns = 0; +- bool miss_in_tls = true; +- bthread_contention_site_t saved_csite = {0,0}; +-#ifndef DONT_SPEEDUP_PTHREAD_CONTENTION_PROFILER_WITH_TLS +- TLSPthreadContentionSites& fast_alt = tls_csites; +- for (int i = fast_alt.count - 1; i >= 0; --i) { +- if (fast_alt.list[i].mutex == mutex) { +- if (is_contention_site_valid(fast_alt.list[i].csite)) { +- saved_csite = fast_alt.list[i].csite; +- unlock_start_ns = butil::cpuwide_time_ns(); +- } +- fast_alt.list[i] = fast_alt.list[--fast_alt.count]; +- miss_in_tls = false; +- break; +- } +- } +-#endif +- // Check the map to see if the lock is sampled. Notice that we're still +- // inside critical section. +- if (miss_in_tls) { +- if (remove_pthread_contention_site(mutex, &saved_csite)) { +- unlock_start_ns = butil::cpuwide_time_ns(); +- } +- } +- const int rc = sys_pthread_mutex_unlock(mutex); +- // [Outside lock] +- if (unlock_start_ns) { +- const int64_t unlock_end_ns = butil::cpuwide_time_ns(); +- saved_csite.duration_ns += unlock_end_ns - unlock_start_ns; +- submit_contention(saved_csite, unlock_end_ns); +- } +- return rc; +-} ++// #ifndef NO_PTHREAD_MUTEX_HOOK ++// BUTIL_FORCE_INLINE int pthread_mutex_lock_impl(pthread_mutex_t* mutex) { ++// // Don't change behavior of lock when profiler is off. ++// if (!g_cp || ++// // collecting code including backtrace() and submit() may call ++// // pthread_mutex_lock and cause deadlock. Don't sample. ++// tls_inside_lock) { ++// return sys_pthread_mutex_lock(mutex); ++// } ++// // Don't slow down non-contended locks. ++// int rc = pthread_mutex_trylock(mutex); ++// if (rc != EBUSY) { ++// return rc; ++// } ++// // Ask bvar::Collector if this (contended) locking should be sampled ++// const size_t sampling_range = bvar::is_collectable(&g_cp_sl); ++ ++// bthread_contention_site_t* csite = NULL; ++// #ifndef DONT_SPEEDUP_PTHREAD_CONTENTION_PROFILER_WITH_TLS ++// TLSPthreadContentionSites& fast_alt = tls_csites; ++// if (fast_alt.cp_version != g_cp_version) { ++// fast_alt.cp_version = g_cp_version; ++// fast_alt.count = 0; ++// } ++// if (fast_alt.count < TLS_MAX_COUNT) { ++// MutexAndContentionSite& entry = fast_alt.list[fast_alt.count++]; ++// entry.mutex = mutex; ++// csite = &entry.csite; ++// if (!sampling_range) { ++// make_contention_site_invalid(&entry.csite); ++// return sys_pthread_mutex_lock(mutex); ++// } ++// } ++// #endif ++// if (!sampling_range) { // don't sample ++// return sys_pthread_mutex_lock(mutex); ++// } ++// // Lock and monitor the waiting time. ++// const int64_t start_ns = butil::cpuwide_time_ns(); ++// rc = sys_pthread_mutex_lock(mutex); ++// if (!rc) { // Inside lock ++// if (!csite) { ++// csite = add_pthread_contention_site(mutex); ++// if (csite == NULL) { ++// return rc; ++// } ++// } ++// csite->duration_ns = butil::cpuwide_time_ns() - start_ns; ++// csite->sampling_range = sampling_range; ++// } // else rare ++// return rc; ++// } ++ ++// BUTIL_FORCE_INLINE int pthread_mutex_unlock_impl(pthread_mutex_t* mutex) { ++// // Don't change behavior of unlock when profiler is off. ++// if (!g_cp || tls_inside_lock) { ++// // This branch brings an issue that an entry created by ++// // add_pthread_contention_site may not be cleared. Thus we add a ++// // 16-bit rolling version in the entry to find out such entry. ++// return sys_pthread_mutex_unlock(mutex); ++// } ++// int64_t unlock_start_ns = 0; ++// bool miss_in_tls = true; ++// bthread_contention_site_t saved_csite = {0,0}; ++// #ifndef DONT_SPEEDUP_PTHREAD_CONTENTION_PROFILER_WITH_TLS ++// TLSPthreadContentionSites& fast_alt = tls_csites; ++// for (int i = fast_alt.count - 1; i >= 0; --i) { ++// if (fast_alt.list[i].mutex == mutex) { ++// if (is_contention_site_valid(fast_alt.list[i].csite)) { ++// saved_csite = fast_alt.list[i].csite; ++// unlock_start_ns = butil::cpuwide_time_ns(); ++// } ++// fast_alt.list[i] = fast_alt.list[--fast_alt.count]; ++// miss_in_tls = false; ++// break; ++// } ++// } ++// #endif ++// // Check the map to see if the lock is sampled. Notice that we're still ++// // inside critical section. ++// if (miss_in_tls) { ++// if (remove_pthread_contention_site(mutex, &saved_csite)) { ++// unlock_start_ns = butil::cpuwide_time_ns(); ++// } ++// } ++// const int rc = sys_pthread_mutex_unlock(mutex); ++// // [Outside lock] ++// if (unlock_start_ns) { ++// const int64_t unlock_end_ns = butil::cpuwide_time_ns(); ++// saved_csite.duration_ns += unlock_end_ns - unlock_start_ns; ++// submit_contention(saved_csite, unlock_end_ns); ++// } ++// return rc; ++// } ++// #endif + + // Implement bthread_mutex_t related functions + struct MutexInternal { +@@ -815,11 +821,13 @@ int bthread_mutex_unlock(bthread_mutex_t* m) { + return 0; + } + +-int pthread_mutex_lock (pthread_mutex_t *__mutex) { +- return bthread::pthread_mutex_lock_impl(__mutex); +-} +-int pthread_mutex_unlock (pthread_mutex_t *__mutex) { +- return bthread::pthread_mutex_unlock_impl(__mutex); +-} ++// #ifndef NO_PTHREAD_MUTEX_HOOK ++// int pthread_mutex_lock (pthread_mutex_t *__mutex) { ++// return bthread::pthread_mutex_lock_impl(__mutex); ++// } ++// int pthread_mutex_unlock (pthread_mutex_t *__mutex) { ++// return bthread::pthread_mutex_unlock_impl(__mutex); ++// } ++// #endif + + } // extern "C"