summaryrefslogtreecommitdiffstats
path: root/lldb/test/functionalities/expr-doesnt-deadlock/locking.c
diff options
context:
space:
mode:
authorChaoren Lin <chaorenl@google.com>2015-08-18 00:27:08 +0000
committerChaoren Lin <chaorenl@google.com>2015-08-18 00:27:08 +0000
commitdea51da7a516e65263a3ca857b31c7eccbbe1cfc (patch)
treee1eeaca699918b3b2ad1776b3e6575e2d5661593 /lldb/test/functionalities/expr-doesnt-deadlock/locking.c
parent040cd4207c09fab65c655b473de0ac8678d101be (diff)
downloadbcm5719-llvm-dea51da7a516e65263a3ca857b31c7eccbbe1cfc.tar.gz
bcm5719-llvm-dea51da7a516e65263a3ca857b31c7eccbbe1cfc.zip
Revert part of "Convert all use of pthreads in tests to c++11 threads."
TestExprDoesntBlock started failing because deadlocks behave differently with pthread_mutex and std::mutex. This reverts part of commit r245234. llvm-svn: 245262
Diffstat (limited to 'lldb/test/functionalities/expr-doesnt-deadlock/locking.c')
-rw-r--r--lldb/test/functionalities/expr-doesnt-deadlock/locking.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/lldb/test/functionalities/expr-doesnt-deadlock/locking.c b/lldb/test/functionalities/expr-doesnt-deadlock/locking.c
new file mode 100644
index 00000000000..fae9979611d
--- /dev/null
+++ b/lldb/test/functionalities/expr-doesnt-deadlock/locking.c
@@ -0,0 +1,80 @@
+#include <pthread.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+
+pthread_mutex_t contended_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+pthread_mutex_t control_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t control_condition;
+
+pthread_mutex_t thread_started_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t thread_started_condition;
+
+// This function runs in a thread. The locking dance is to make sure that
+// by the time the main thread reaches the pthread_join below, this thread
+// has for sure acquired the contended_mutex. So then the call_me_to_get_lock
+// function will block trying to get the mutex, and only succeed once it
+// signals this thread, then lets it run to wake up from the cond_wait and
+// release the mutex.
+
+void *
+lock_acquirer_1 (void *input)
+{
+ pthread_mutex_lock (&contended_mutex);
+
+ // Grab this mutex, that will ensure that the main thread
+ // is in its cond_wait for it (since that's when it drops the mutex.
+
+ pthread_mutex_lock (&thread_started_mutex);
+ pthread_mutex_unlock(&thread_started_mutex);
+
+ // Now signal the main thread that it can continue, we have the contended lock
+ // so the call to call_me_to_get_lock won't make any progress till this
+ // thread gets a chance to run.
+
+ pthread_mutex_lock (&control_mutex);
+
+ pthread_cond_signal (&thread_started_condition);
+
+ pthread_cond_wait (&control_condition, &control_mutex);
+
+ pthread_mutex_unlock (&contended_mutex);
+ return NULL;
+}
+
+int
+call_me_to_get_lock ()
+{
+ pthread_cond_signal (&control_condition);
+ pthread_mutex_lock (&contended_mutex);
+ return 567;
+}
+
+int main ()
+{
+ pthread_t thread_1;
+
+ pthread_cond_init (&control_condition, NULL);
+ pthread_cond_init (&thread_started_condition, NULL);
+
+ pthread_mutex_lock (&thread_started_mutex);
+
+ pthread_create (&thread_1, NULL, lock_acquirer_1, NULL);
+
+ pthread_cond_wait (&thread_started_condition, &thread_started_mutex);
+
+ pthread_mutex_lock (&control_mutex);
+ pthread_mutex_unlock (&control_mutex);
+
+ // Break here. At this point the other thread will have the contended_mutex,
+ // and be sitting in its cond_wait for the control condition. So there is
+ // no way that our by-hand calling of call_me_to_get_lock will proceed
+ // without running the first thread at least somewhat.
+
+ call_me_to_get_lock();
+ pthread_join (thread_1, NULL);
+
+ return 0;
+
+}
OpenPOWER on IntegriCloud