1#include <pthread.h> 2#include <stdlib.h> 3#include <unistd.h> 4#include <stdio.h> 5 6pthread_mutex_t contended_mutex = PTHREAD_MUTEX_INITIALIZER; 7 8pthread_mutex_t control_mutex = PTHREAD_MUTEX_INITIALIZER; 9pthread_cond_t control_condition; 10 11pthread_mutex_t thread_started_mutex = PTHREAD_MUTEX_INITIALIZER; 12pthread_cond_t thread_started_condition; 13 14// This function runs in a thread. The locking dance is to make sure that 15// by the time the main thread reaches the pthread_join below, this thread 16// has for sure acquired the contended_mutex. So then the call_me_to_get_lock 17// function will block trying to get the mutex, and only succeed once it 18// signals this thread, then lets it run to wake up from the cond_wait and 19// release the mutex. 20 21void * 22lock_acquirer_1 (void *input) 23{ 24 pthread_mutex_lock (&contended_mutex); 25 26 // Grab this mutex, that will ensure that the main thread 27 // is in its cond_wait for it (since that's when it drops the mutex. 28 29 pthread_mutex_lock (&thread_started_mutex); 30 pthread_mutex_unlock(&thread_started_mutex); 31 32 // Now signal the main thread that it can continue, we have the contended lock 33 // so the call to call_me_to_get_lock won't make any progress till this 34 // thread gets a chance to run. 35 36 pthread_mutex_lock (&control_mutex); 37 38 pthread_cond_signal (&thread_started_condition); 39 40 pthread_cond_wait (&control_condition, &control_mutex); 41 42 pthread_mutex_unlock (&contended_mutex); 43 return NULL; 44} 45 46int 47call_me_to_get_lock () 48{ 49 pthread_cond_signal (&control_condition); 50 pthread_mutex_lock (&contended_mutex); 51 return 567; 52} 53 54int main () 55{ 56 pthread_t thread_1; 57 58 pthread_cond_init (&control_condition, NULL); 59 pthread_cond_init (&thread_started_condition, NULL); 60 61 pthread_mutex_lock (&thread_started_mutex); 62 63 pthread_create (&thread_1, NULL, lock_acquirer_1, NULL); 64 65 pthread_cond_wait (&thread_started_condition, &thread_started_mutex); 66 67 pthread_mutex_lock (&control_mutex); 68 pthread_mutex_unlock (&control_mutex); 69 70 // Break here. At this point the other thread will have the contended_mutex, 71 // and be sitting in its cond_wait for the control condition. So there is 72 // no way that our by-hand calling of call_me_to_get_lock will proceed 73 // without running the first thread at least somewhat. 74 75 call_me_to_get_lock(); 76 pthread_join (thread_1, NULL); 77 78 return 0; 79 80} 81