Remove the broken pthread deadlock prediction.

This hasn't built in over one release cycle and no one even noticed.
art does this the right way and other projects should do the same.

Change-Id: I7d1fb84c4080e008f329ee73e209ce85a36e6d55
diff --git a/libc/Android.mk b/libc/Android.mk
index ed7d055..c0da9b2 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -747,10 +747,6 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
 
-# Set -DPTHREAD_DEBUG_ENABLED=true to enable support for pthread deadlock prediction.
-# Since this code is experimental it is disabled by default.
-LOCAL_CFLAGS += -DPTHREAD_DEBUG_ENABLED=false
-
 ifneq ($(TARGET_USES_LOGD),false)
 LOCAL_CFLAGS += -DTARGET_USES_LOGD
 endif
@@ -889,7 +885,6 @@
     bionic/malloc_debug_common.cpp \
     bionic/debug_mapinfo.cpp \
     bionic/debug_stacktrace.cpp \
-    bionic/pthread_debug.cpp \
     bionic/libc_init_dynamic.cpp \
     bionic/NetdClient.cpp \
 
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 3d98861..659cf39 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -55,7 +55,6 @@
 #include "private/KernelArgumentBlock.h"
 
 extern "C" {
-  extern void pthread_debug_init(void);
   extern void malloc_debug_init(void);
   extern void malloc_debug_fini(void);
   extern void netdClientInit(void);
@@ -77,11 +76,8 @@
 
   __libc_init_common(*args);
 
-  // Hooks for the debug malloc and pthread libraries to let them know that we're starting up.
-  pthread_debug_init();
+  // Hooks for various libraries to let them know that we're starting up.
   malloc_debug_init();
-
-  // Hook for the netd client library to let it know that we're starting up.
   netdClientInit();
 }
 
diff --git a/libc/bionic/pthread_debug.cpp b/libc/bionic/pthread_debug.cpp
deleted file mode 100644
index be89b46..0000000
--- a/libc/bionic/pthread_debug.cpp
+++ /dev/null
@@ -1,717 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-#include <sys/atomics.h>
-#include <sys/system_properties.h>
-#include <sys/mman.h>
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <pthread.h>
-#include <unwind.h>
-#include <unistd.h>
-
-#include "private/bionic_tls.h"
-#include "debug_mapinfo.h"
-#include "debug_stacktrace.h"
-#include "private/libc_logging.h"
-
-/*
- * ===========================================================================
- *      Deadlock prediction
- * ===========================================================================
- */
-/*
-The idea is to predict the possibility of deadlock by recording the order
-in which locks are acquired.  If we see an attempt to acquire a lock
-out of order, we can identify the locks and offending code.
-
-To make this work, we need to keep track of the locks held by each thread,
-and create history trees for each lock.  When a thread tries to acquire
-a new lock, we walk through the "history children" of the lock, looking
-for a match with locks the thread already holds.  If we find a match,
-it means the thread has made a request that could result in a deadlock.
-
-To support recursive locks, we always allow re-locking a currently-held
-lock, and maintain a recursion depth count.
-
-An ASCII-art example, where letters represent locks:
-
-        A
-       /|\
-      / | \
-     B  |  D
-      \ |
-       \|
-        C
-
-The above is the tree we'd have after handling lock synchronization
-sequences "ABC", "AC", "AD".  A has three children, {B, C, D}.  C is also
-a child of B.  (The lines represent pointers between parent and child.
-Every node can have multiple parents and multiple children.)
-
-If we hold AC, and want to lock B, we recursively search through B's
-children to see if A or C appears.  It does, so we reject the attempt.
-(A straightforward way to implement it: add a link from C to B, then
-determine whether the graph starting at B contains a cycle.)
-
-If we hold AC and want to lock D, we would succeed, creating a new link
-from C to D.
-
-Updates to MutexInfo structs are only allowed for the thread that holds
-the lock, so we actually do most of our deadlock prediction work after
-the lock has been acquired.
-*/
-
-#if PTHREAD_DEBUG_ENABLED
-
-// =============================================================================
-// log functions
-// =============================================================================
-
-#define LOGD(format, ...)  \
-    __libc_format_log(ANDROID_LOG_DEBUG, "pthread_debug", (format), ##__VA_ARGS__ )
-
-#define LOGW(format, ...)  \
-    __libc_format_log(ANDROID_LOG_WARN, "pthread_debug", (format), ##__VA_ARGS__ )
-
-#define LOGE(format, ...)  \
-    __libc_format_log(ANDROID_LOG_ERROR, "pthread_debug", (format), ##__VA_ARGS__ )
-
-#define LOGI(format, ...)  \
-    __libc_format_log(ANDROID_LOG_INFO, "pthread_debug", (format), ##__VA_ARGS__ )
-
-static const char* const kStartBanner =
-        "===============================================================";
-
-static const char* const kEndBanner =
-        "===============================================================";
-
-extern const char* __progname;
-
-#define STACK_TRACE_DEPTH 16
-
-/****************************************************************************/
-
-/*
- * level <= 0 : deadlock prediction disabled
- * level    1 : deadlock prediction enabled, w/o call stacks
- * level    2 : deadlock prediction enabled w/ call stacks
- */
-#define CAPTURE_CALLSTACK 2
-static int g_pthread_debug_level = 0;
-static pid_t g_pthread_debug_disabled_thread = -1;
-static pthread_mutex_t g_dbg_lock = PTHREAD_MUTEX_INITIALIZER;
-
-/****************************************************************************/
-
-/* some simple/lame malloc replacement
- * NOT thread-safe and leaks everything
- */
-
-#define DBG_ALLOC_BLOCK_SIZE PAGESIZE
-static size_t g_dbg_alloc_offset = DBG_ALLOC_BLOCK_SIZE;
-static char* g_dbg_alloc_ptr = NULL;
-
-template <typename T>
-static T* DbgAllocLocked(size_t count = 1) {
-    size_t size = sizeof(T) * count;
-    if ((g_dbg_alloc_offset + size) > DBG_ALLOC_BLOCK_SIZE) {
-        g_dbg_alloc_offset = 0;
-        g_dbg_alloc_ptr = reinterpret_cast<char*>(mmap(NULL, DBG_ALLOC_BLOCK_SIZE,
-                                                    PROT_READ|PROT_WRITE,
-                                                    MAP_ANON | MAP_PRIVATE, 0, 0));
-        if (g_dbg_alloc_ptr == MAP_FAILED) {
-            return NULL;
-        }
-    }
-    void* addr = g_dbg_alloc_ptr + g_dbg_alloc_offset;
-    g_dbg_alloc_offset += size;
-    return reinterpret_cast<T*>(addr);
-}
-
-static void* debug_realloc(void *ptr, size_t size, size_t old_size) {
-    void* addr = mmap(NULL, size, PROT_READ|PROT_WRITE,
-            MAP_ANON | MAP_PRIVATE, 0, 0);
-    if (addr != MAP_FAILED) {
-        if (ptr) {
-            memcpy(addr, ptr, old_size);
-            munmap(ptr, old_size);
-        }
-    } else {
-        addr = NULL;
-    }
-    return addr;
-}
-
-/*****************************************************************************/
-
-struct MutexInfo;
-
-typedef struct CallStack {
-    uintptr_t    depth;
-    uintptr_t*   addrs;
-} CallStack;
-
-typedef struct MutexInfo* MutexInfoListEntry;
-typedef struct CallStack  CallStackListEntry;
-
-typedef struct GrowingList {
-    int alloc;
-    int count;
-    union {
-        void*               data;
-        MutexInfoListEntry* list;
-        CallStackListEntry* stack;
-    };
-} GrowingList;
-
-typedef GrowingList MutexInfoList;
-typedef GrowingList CallStackList;
-
-typedef struct MutexInfo {
-    // thread currently holding the lock or 0
-    pid_t               owner;
-
-    // most-recently-locked doubly-linked list
-    struct MutexInfo*   prev;
-    struct MutexInfo*   next;
-
-    // for reentrant locks
-    int                 lockCount;
-    // when looking for loops in the graph, marks visited nodes
-    int                 historyMark;
-    // the actual mutex
-    pthread_mutex_t*    mutex;
-    // list of locks directly acquired AFTER this one in the same thread
-    MutexInfoList       children;
-    // list of locks directly acquired BEFORE this one in the same thread
-    MutexInfoList       parents;
-    // list of call stacks when a new link is established to this lock form its parent
-    CallStackList       stacks;
-    // call stack when this lock was acquired last
-    int                 stackDepth;
-    uintptr_t           stackTrace[STACK_TRACE_DEPTH];
-} MutexInfo;
-
-static void growingListInit(GrowingList* list) {
-    list->alloc = 0;
-    list->count = 0;
-    list->data = NULL;
-}
-
-static void growingListAdd(GrowingList* pList, size_t objSize) {
-    if (pList->count == pList->alloc) {
-        size_t oldsize = pList->alloc * objSize;
-        pList->alloc += PAGESIZE / objSize;
-        size_t size = pList->alloc * objSize;
-        pList->data = debug_realloc(pList->data, size, oldsize);
-    }
-    pList->count++;
-}
-
-static void initMutexInfo(MutexInfo* object, pthread_mutex_t* mutex) {
-    object->owner = 0;
-    object->prev = 0;
-    object->next = 0;
-    object->lockCount = 0;
-    object->historyMark = 0;
-    object->mutex = mutex;
-    growingListInit(&object->children);
-    growingListInit(&object->parents);
-    growingListInit(&object->stacks);
-    object->stackDepth = 0;
-}
-
-typedef struct ThreadInfo {
-    pid_t       pid;
-    MutexInfo*  mrl;
-} ThreadInfo;
-
-static void initThreadInfo(ThreadInfo* object, pid_t pid) {
-    object->pid = pid;
-    object->mrl = NULL;
-}
-
-/****************************************************************************/
-
-static MutexInfo* get_mutex_info(pthread_mutex_t *mutex);
-static void mutex_lock_checked(MutexInfo* mrl, MutexInfo* object);
-static void mutex_unlock_checked(MutexInfo* object);
-
-/****************************************************************************/
-
-extern "C" int pthread_mutex_lock_impl(pthread_mutex_t *mutex);
-extern "C" int pthread_mutex_unlock_impl(pthread_mutex_t *mutex);
-
-static int pthread_mutex_lock_unchecked(pthread_mutex_t *mutex) {
-    return pthread_mutex_lock_impl(mutex);
-}
-
-static int pthread_mutex_unlock_unchecked(pthread_mutex_t *mutex) {
-    return pthread_mutex_unlock_impl(mutex);
-}
-
-/****************************************************************************/
-
-static void dup_backtrace(CallStack* stack, size_t count, uintptr_t const* addrs) {
-    stack->depth = count;
-    stack->addrs = DbgAllocLocked<uintptr_t>(count);
-    memcpy(stack->addrs, addrs, count * sizeof(uintptr_t));
-}
-
-/****************************************************************************/
-
-static int historyListHas(
-        const MutexInfoList* list, MutexInfo const * obj) {
-    int i;
-    for (i=0; i<list->count; i++) {
-        if (list->list[i] == obj) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-static void historyListAdd(MutexInfoList* pList, MutexInfo* obj) {
-    growingListAdd(pList, sizeof(MutexInfoListEntry));
-    pList->list[pList->count - 1] = obj;
-}
-
-static int historyListRemove(MutexInfoList* pList, MutexInfo* obj) {
-    int i;
-    for (i = pList->count-1; i >= 0; i--) {
-        if (pList->list[i] == obj) {
-            break;
-        }
-    }
-    if (i < 0) {
-        // not found!
-        return 0;
-    }
-
-    if (i != pList->count-1) {
-        // copy the last entry to the new free slot
-        pList->list[i] = pList->list[pList->count-1];
-    }
-    pList->count--;
-    memset(&pList->list[pList->count], 0, sizeof(MutexInfoListEntry));
-    return 1;
-}
-
-static void linkParentToChild(MutexInfo* parent, MutexInfo* child) {
-    historyListAdd(&parent->children, child);
-    historyListAdd(&child->parents, parent);
-}
-
-static void unlinkParentFromChild(MutexInfo* parent, MutexInfo* child) {
-    historyListRemove(&parent->children, child);
-    historyListRemove(&child->parents, parent);
-}
-
-/****************************************************************************/
-
-static void callstackListAdd(CallStackList* pList,
-        int count, uintptr_t const* addrs) {
-    growingListAdd(pList, sizeof(CallStackListEntry));
-    dup_backtrace(&pList->stack[pList->count - 1], count, addrs);
-}
-
-/****************************************************************************/
-
-/*
- * Recursively traverse the object hierarchy starting at "obj".  We mark
- * ourselves on entry and clear the mark on exit.  If we ever encounter
- * a marked object, we have a cycle.
- *
- * Returns "true" if all is well, "false" if we found a cycle.
- */
-
-static int traverseTree(MutexInfo* obj, MutexInfo const* objParent)
-{
-    /*
-     * Have we been here before?
-     */
-    if (obj->historyMark) {
-        int stackDepth;
-        uintptr_t addrs[STACK_TRACE_DEPTH];
-
-        /* Turn off prediction temporarily in this thread while logging */
-        g_pthread_debug_disabled_thread = gettid();
-
-        backtrace_startup();
-
-        LOGW("%s\n", kStartBanner);
-        LOGW("pid: %d, tid: %d >>> %s <<<", getpid(), gettid(), __progname);
-        LOGW("Illegal lock attempt:\n");
-        LOGW("--- pthread_mutex_t at %p\n", obj->mutex);
-        stackDepth = get_backtrace(addrs, STACK_TRACE_DEPTH);
-        log_backtrace(addrs, stackDepth);
-
-        LOGW("+++ Currently held locks in this thread (in reverse order):");
-        MutexInfo* cur = obj;
-        pid_t ourtid = gettid();
-        int i;
-        for (i=0 ; i<cur->parents.count ; i++) {
-            MutexInfo* parent = cur->parents.list[i];
-            if (parent->owner == ourtid) {
-                LOGW("--- pthread_mutex_t at %p\n", parent->mutex);
-                if (g_pthread_debug_level >= CAPTURE_CALLSTACK) {
-                    log_backtrace(parent->stackTrace, parent->stackDepth);
-                }
-                cur = parent;
-                break;
-            }
-        }
-
-        LOGW("+++ Earlier, the following lock order (from last to first) was established\n");
-        return 0;
-    }
-
-    obj->historyMark = 1;
-
-    MutexInfoList* pList = &obj->children;
-    int result = 1;
-    int i;
-    for (i = pList->count-1; i >= 0; i--) {
-        MutexInfo* child = pList->list[i];
-        if (!traverseTree(child,  obj)) {
-            LOGW("--- pthread_mutex_t at %p\n", obj->mutex);
-            if (g_pthread_debug_level >= CAPTURE_CALLSTACK) {
-                int index = historyListHas(&obj->parents, objParent);
-                if ((size_t)index < (size_t)obj->stacks.count) {
-                    log_backtrace(obj->stacks.stack[index].addrs, obj->stacks.stack[index].depth);
-                } else {
-                    log_backtrace(obj->stackTrace, obj->stackDepth);
-                }
-            }
-            result = 0;
-            break;
-        }
-    }
-
-    obj->historyMark = 0;
-    return result;
-}
-
-/****************************************************************************/
-
-static void mutex_lock_checked(MutexInfo* mrl, MutexInfo* object)
-{
-    pid_t tid = gettid();
-    if (object->owner == tid) {
-        object->lockCount++;
-        return;
-    }
-
-    object->owner = tid;
-    object->lockCount = 0;
-
-    if (g_pthread_debug_level >= CAPTURE_CALLSTACK) {
-        // always record the call stack when acquiring a lock.
-        // it's not efficient, but is useful during diagnostics
-        object->stackDepth = get_backtrace(object->stackTrace, STACK_TRACE_DEPTH);
-    }
-
-    // no other locks held in this thread -- no deadlock possible!
-    if (mrl == NULL)
-        return;
-
-    // check if the lock we're trying to acquire is a direct descendant of
-    // the most recently locked mutex in this thread, in which case we're
-    // in a good situation -- no deadlock possible
-    if (historyListHas(&mrl->children, object) >= 0)
-        return;
-
-    pthread_mutex_lock_unchecked(&g_dbg_lock);
-
-    linkParentToChild(mrl, object);
-    if (!traverseTree(object, mrl)) {
-        backtrace_shutdown();
-        LOGW("%s\n", kEndBanner);
-        unlinkParentFromChild(mrl, object);
-        // reenable pthread debugging for this thread
-        g_pthread_debug_disabled_thread = -1;
-    } else {
-        // record the call stack for this link
-        // NOTE: the call stack is added at the same index
-        // as mrl in object->parents[]
-        // ie: object->parents.count == object->stacks.count, which is
-        // also the index.
-        if (g_pthread_debug_level >= CAPTURE_CALLSTACK) {
-            callstackListAdd(&object->stacks,
-                    object->stackDepth, object->stackTrace);
-        }
-    }
-
-    pthread_mutex_unlock_unchecked(&g_dbg_lock);
-}
-
-static void mutex_unlock_checked(MutexInfo* object)
-{
-    pid_t tid = gettid();
-    if (object->owner == tid) {
-        if (object->lockCount == 0) {
-            object->owner = 0;
-        } else {
-            object->lockCount--;
-        }
-    }
-}
-
-
-// =============================================================================
-// Hash Table functions
-// =============================================================================
-
-/****************************************************************************/
-
-#define HASHTABLE_SIZE      256
-
-typedef struct HashEntry HashEntry;
-struct HashEntry {
-    size_t slot;
-    HashEntry* prev;
-    HashEntry* next;
-    void* data;
-};
-
-typedef struct HashTable HashTable;
-struct HashTable {
-    HashEntry* slots[HASHTABLE_SIZE];
-};
-
-static HashTable g_mutex_map;
-static HashTable g_thread_map;
-
-/****************************************************************************/
-
-static uint32_t get_hashcode(void const * key, size_t keySize)
-{
-    uint32_t h = keySize;
-    char const* data = (char const*)key;
-    size_t i;
-    for (i = 0; i < keySize; i++) {
-        h = h * 31 + *data;
-        data++;
-    }
-    return (uint32_t)h;
-}
-
-static size_t get_index(uint32_t h)
-{
-    // We apply this secondary hashing discovered by Doug Lea to defend
-    // against bad hashes.
-    h += ~(h << 9);
-    h ^= (((unsigned int) h) >> 14);
-    h += (h << 4);
-    h ^= (((unsigned int) h) >> 10);
-    return (size_t)h & (HASHTABLE_SIZE - 1);
-}
-
-/****************************************************************************/
-
-static void hashmap_init(HashTable* table) {
-    memset(table, 0, sizeof(HashTable));
-}
-
-static void hashmap_removeEntry(HashTable* table, HashEntry* entry)
-{
-    HashEntry* prev = entry->prev;
-    HashEntry* next = entry->next;
-    if (prev != NULL) entry->prev->next = next;
-    if (next != NULL) entry->next->prev = prev;
-    if (prev == NULL) {
-        // we are the head of the list. set the head to be next
-        table->slots[entry->slot] = entry->next;
-    }
-}
-
-static HashEntry* hashmap_lookup(HashTable* table,
-        void const* key, size_t ksize,
-        int (*equals)(void const* data, void const* key))
-{
-    const uint32_t hash = get_hashcode(key, ksize);
-    const size_t slot = get_index(hash);
-
-    HashEntry* entry = table->slots[slot];
-    while (entry) {
-        if (equals(entry->data, key)) {
-            break;
-        }
-        entry = entry->next;
-    }
-
-    if (entry == NULL) {
-        // create a new entry
-        entry = DbgAllocLocked<HashEntry>();
-        entry->data = NULL;
-        entry->slot = slot;
-        entry->prev = NULL;
-        entry->next = table->slots[slot];
-        if (entry->next != NULL) {
-            entry->next->prev = entry;
-        }
-        table->slots[slot] = entry;
-    }
-    return entry;
-}
-
-/****************************************************************************/
-
-static int MutexInfo_equals(void const* data, void const* key) {
-    return ((MutexInfo const *)data)->mutex == *(pthread_mutex_t **)key;
-}
-
-static MutexInfo* get_mutex_info(pthread_mutex_t *mutex)
-{
-    pthread_mutex_lock_unchecked(&g_dbg_lock);
-
-    HashEntry* entry = hashmap_lookup(&g_mutex_map,
-            &mutex, sizeof(mutex),
-            &MutexInfo_equals);
-    if (entry->data == NULL) {
-        MutexInfo* mutex_info = DbgAllocLocked<MutexInfo>();
-        entry->data = mutex_info;
-        initMutexInfo(mutex_info, mutex);
-    }
-
-    pthread_mutex_unlock_unchecked(&g_dbg_lock);
-
-    return (MutexInfo *)entry->data;
-}
-
-/****************************************************************************/
-
-static int ThreadInfo_equals(void const* data, void const* key) {
-    return ((ThreadInfo const *)data)->pid == *(pid_t *)key;
-}
-
-static ThreadInfo* get_thread_info(pid_t pid)
-{
-    pthread_mutex_lock_unchecked(&g_dbg_lock);
-
-    HashEntry* entry = hashmap_lookup(&g_thread_map,
-            &pid, sizeof(pid),
-            &ThreadInfo_equals);
-    if (entry->data == NULL) {
-        ThreadInfo* thread_info = DbgAllocLocked<ThreadInfo>();
-        entry->data = thread_info;
-        initThreadInfo(thread_info, pid);
-    }
-
-    pthread_mutex_unlock_unchecked(&g_dbg_lock);
-
-    return (ThreadInfo *)entry->data;
-}
-
-static void push_most_recently_locked(MutexInfo* mrl) {
-    ThreadInfo* tinfo = get_thread_info(gettid());
-    mrl->next = NULL;
-    mrl->prev = tinfo->mrl;
-    tinfo->mrl = mrl;
-}
-
-static void remove_most_recently_locked(MutexInfo* mrl) {
-    ThreadInfo* tinfo = get_thread_info(gettid());
-    if (mrl->next) {
-        (mrl->next)->prev = mrl->prev;
-    }
-    if (mrl->prev) {
-        (mrl->prev)->next = mrl->next;
-    }
-    if (tinfo->mrl == mrl) {
-        tinfo->mrl = mrl->next;
-    }
-}
-
-static MutexInfo* get_most_recently_locked() {
-    ThreadInfo* tinfo = get_thread_info(gettid());
-    return tinfo->mrl;
-}
-
-/****************************************************************************/
-
-/*
- * See if we were allowed to grab the lock at this time.  We do it
- * *after* acquiring the lock, rather than before, so that we can
- * freely update the MutexInfo struct.  This seems counter-intuitive,
- * but our goal is deadlock *prediction* not deadlock *prevention*.
- * (If we actually deadlock, the situation is easy to diagnose from
- * a thread dump, so there's no point making a special effort to do
- * the checks before the lock is held.)
- */
-
-extern "C" __LIBC_HIDDEN__ void pthread_debug_mutex_lock_check(pthread_mutex_t *mutex)
-{
-    if (g_pthread_debug_level == 0) return;
-    // prediction disabled for this thread
-    if (g_pthread_debug_disabled_thread == gettid())
-        return;
-    MutexInfo* object = get_mutex_info(mutex);
-    MutexInfo* mrl = get_most_recently_locked();
-    mutex_lock_checked(mrl, object);
-    push_most_recently_locked(object);
-}
-
-/*
- * pthread_debug_mutex_unlock_check() must be called with the mutex
- * still held (ie: before calling the real unlock)
- */
-
-extern "C" __LIBC_HIDDEN__ void pthread_debug_mutex_unlock_check(pthread_mutex_t *mutex)
-{
-    if (g_pthread_debug_level == 0) return;
-    // prediction disabled for this thread
-    if (g_pthread_debug_disabled_thread == gettid())
-        return;
-    MutexInfo* object = get_mutex_info(mutex);
-    remove_most_recently_locked(object);
-    mutex_unlock_checked(object);
-}
-
-#endif // PTHREAD_DEBUG_ENABLED
-
-// Called from libc_init_dynamic() just after system properties have been initialized.
-extern "C" __LIBC_HIDDEN__ void pthread_debug_init() {
-#if PTHREAD_DEBUG_ENABLED
-    char env[PROP_VALUE_MAX];
-    if (__system_property_get("debug.libc.pthread", env)) {
-        int level = atoi(env);
-        if (level) {
-            LOGI("pthread deadlock detection level %d enabled for pid %d (%s)",
-                    level, getpid(), __progname);
-            hashmap_init(&g_mutex_map);
-            g_pthread_debug_level = level;
-        }
-    }
-#endif
-}
diff --git a/libc/bionic/pthread_mutex.cpp b/libc/bionic/pthread_mutex.cpp
index c4cd9e0..9fd5d32 100644
--- a/libc/bionic/pthread_mutex.cpp
+++ b/libc/bionic/pthread_mutex.cpp
@@ -445,9 +445,7 @@
     }
 }
 
-__LIBC_HIDDEN__
-int pthread_mutex_lock_impl(pthread_mutex_t *mutex)
-{
+int pthread_mutex_lock(pthread_mutex_t* mutex) {
     int mvalue, mtype, tid, shared;
 
     mvalue = mutex->value;
@@ -523,20 +521,7 @@
     /* NOTREACHED */
 }
 
-int pthread_mutex_lock(pthread_mutex_t *mutex)
-{
-    int err = pthread_mutex_lock_impl(mutex);
-    if (PTHREAD_DEBUG_ENABLED) {
-        if (!err) {
-            pthread_debug_mutex_lock_check(mutex);
-        }
-    }
-    return err;
-}
-
-__LIBC_HIDDEN__
-int pthread_mutex_unlock_impl(pthread_mutex_t *mutex)
-{
+int pthread_mutex_unlock(pthread_mutex_t* mutex) {
     int mvalue, mtype, tid, shared;
 
     mvalue = mutex->value;
@@ -588,17 +573,7 @@
     return 0;
 }
 
-int pthread_mutex_unlock(pthread_mutex_t *mutex)
-{
-    if (PTHREAD_DEBUG_ENABLED) {
-        pthread_debug_mutex_unlock_check(mutex);
-    }
-    return pthread_mutex_unlock_impl(mutex);
-}
-
-__LIBC_HIDDEN__
-int pthread_mutex_trylock_impl(pthread_mutex_t *mutex)
-{
+int pthread_mutex_trylock(pthread_mutex_t* mutex) {
     int mvalue, mtype, tid, shared;
 
     mvalue = mutex->value;
@@ -638,17 +613,6 @@
     return EBUSY;
 }
 
-int pthread_mutex_trylock(pthread_mutex_t *mutex)
-{
-    int err = pthread_mutex_trylock_impl(mutex);
-    if (PTHREAD_DEBUG_ENABLED) {
-        if (!err) {
-            pthread_debug_mutex_lock_check(mutex);
-        }
-    }
-    return err;
-}
-
 static int __pthread_mutex_timedlock(pthread_mutex_t* mutex, const timespec* abs_timeout, clockid_t clock) {
   timespec ts;
 
@@ -761,16 +725,11 @@
     abs_timeout.tv_nsec -= 1000000000;
   }
 
-  int err = __pthread_mutex_timedlock(mutex, &abs_timeout, CLOCK_MONOTONIC);
-  if (err == ETIMEDOUT) {
-    err = EBUSY;
+  int error = __pthread_mutex_timedlock(mutex, &abs_timeout, CLOCK_MONOTONIC);
+  if (error == ETIMEDOUT) {
+    error = EBUSY;
   }
-  if (PTHREAD_DEBUG_ENABLED) {
-    if (!err) {
-      pthread_debug_mutex_lock_check(mutex);
-    }
-  }
-  return err;
+  return error;
 }
 #endif
 
@@ -778,16 +737,12 @@
   return __pthread_mutex_timedlock(mutex, abs_timeout, CLOCK_REALTIME);
 }
 
-int pthread_mutex_destroy(pthread_mutex_t *mutex)
-{
-    int ret;
-
-    /* use trylock to ensure that the mutex value is
-     * valid and is not already locked. */
-    ret = pthread_mutex_trylock_impl(mutex);
-    if (ret != 0)
-        return ret;
-
-    mutex->value = 0xdead10cc;
-    return 0;
+int pthread_mutex_destroy(pthread_mutex_t* mutex) {
+  // Use trylock to ensure that the mutex is valid and not already locked.
+  int error = pthread_mutex_trylock(mutex);
+  if (error != 0) {
+    return error;
+  }
+  mutex->value = 0xdead10cc;
+  return 0;
 }