| 1 | #include <pthread.h> |
|---|---|
| 2 | #include <mach/thread_act.h> |
| 3 | #include <unistd.h> |
| 4 | |
| 5 | pthread_mutex_t suspend_mutex = PTHREAD_MUTEX_INITIALIZER; |
| 6 | pthread_mutex_t signal_mutex = PTHREAD_MUTEX_INITIALIZER; |
| 7 | pthread_cond_t signal_cond = PTHREAD_COND_INITIALIZER; |
| 8 | |
| 9 | int g_running_count = 0; |
| 10 | |
| 11 | int |
| 12 | function_to_call() { |
| 13 | return g_running_count; |
| 14 | } |
| 15 | |
| 16 | void * |
| 17 | suspend_func (void *unused) { |
| 18 | pthread_setname_np("Look for me"); |
| 19 | pthread_cond_signal(cond: &signal_cond); |
| 20 | pthread_mutex_lock(mutex: &suspend_mutex); |
| 21 | |
| 22 | return NULL; // We allowed the suspend thread to run |
| 23 | } |
| 24 | |
| 25 | void * |
| 26 | running_func (void *input) { |
| 27 | while (g_running_count < 10) { |
| 28 | usleep (useconds: 100); |
| 29 | g_running_count++; // Break here to show we can handle breakpoints |
| 30 | } |
| 31 | return NULL; |
| 32 | } |
| 33 | |
| 34 | int |
| 35 | main() |
| 36 | { |
| 37 | pthread_t suspend_thread; // Stop here to get things going |
| 38 | |
| 39 | pthread_mutex_lock(mutex: &suspend_mutex); |
| 40 | pthread_mutex_lock(mutex: &signal_mutex); |
| 41 | pthread_create(newthread: &suspend_thread, NULL, start_routine: suspend_func, NULL); |
| 42 | |
| 43 | pthread_cond_wait(cond: &signal_cond, mutex: &signal_mutex); |
| 44 | |
| 45 | mach_port_t th_port = pthread_mach_thread_np(suspend_thread); |
| 46 | thread_suspend(th_port); |
| 47 | |
| 48 | pthread_mutex_unlock(mutex: &suspend_mutex); |
| 49 | |
| 50 | pthread_t running_thread; |
| 51 | pthread_create(newthread: &running_thread, NULL, start_routine: running_func, NULL); |
| 52 | |
| 53 | pthread_join(th: running_thread, NULL); |
| 54 | thread_resume(th_port); // Break here after thread_join |
| 55 | |
| 56 | pthread_join(th: suspend_thread, NULL); |
| 57 | return 0; // Break here to make sure the thread exited normally |
| 58 | } |
| 59 |
