1 /* Test case for hand function calls in multi-threaded program. 2 3 Copyright 2008-2023 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include <pthread.h> 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <time.h> 24 #include <unistd.h> 25 26 #ifndef NR_THREADS 27 #define NR_THREADS 4 28 #endif 29 30 int thread_count; 31 32 pthread_mutex_t thread_count_mutex; 33 34 pthread_cond_t thread_count_condvar; 35 36 void 37 incr_thread_count (void) 38 { 39 pthread_mutex_lock (&thread_count_mutex); 40 ++thread_count; 41 if (thread_count == NR_THREADS) 42 pthread_cond_signal (&thread_count_condvar); 43 pthread_mutex_unlock (&thread_count_mutex); 44 } 45 46 void 47 cond_wait (pthread_cond_t *cond, pthread_mutex_t *mut) 48 { 49 pthread_mutex_lock (mut); 50 pthread_cond_wait (cond, mut); 51 pthread_mutex_unlock (mut); 52 } 53 54 void 55 noreturn (void) 56 { 57 pthread_mutex_t mut; 58 pthread_cond_t cond; 59 60 pthread_mutex_init (&mut, NULL); 61 pthread_cond_init (&cond, NULL); 62 63 /* Wait for a condition that will never be signaled, so we effectively 64 block the thread here. */ 65 cond_wait (&cond, &mut); 66 } 67 68 void * 69 forever_pthread (void *unused) 70 { 71 incr_thread_count (); 72 noreturn (); 73 } 74 75 void 76 hand_call (void) 77 { 78 } 79 80 /* Wait until all threads are running. */ 81 82 void 83 wait_all_threads_running (void) 84 { 85 pthread_mutex_lock (&thread_count_mutex); 86 if (thread_count == NR_THREADS) 87 { 88 pthread_mutex_unlock (&thread_count_mutex); 89 return; 90 } 91 pthread_cond_wait (&thread_count_condvar, &thread_count_mutex); 92 if (thread_count == NR_THREADS) 93 { 94 pthread_mutex_unlock (&thread_count_mutex); 95 return; 96 } 97 pthread_mutex_unlock (&thread_count_mutex); 98 printf ("failed waiting for all threads to start\n"); 99 abort (); 100 } 101 102 /* Called when all threads are running. 103 Easy place for a breakpoint. */ 104 105 void 106 all_threads_running (void) 107 { 108 } 109 110 int 111 main (void) 112 { 113 pthread_t forever[NR_THREADS]; 114 int i; 115 116 pthread_mutex_init (&thread_count_mutex, NULL); 117 pthread_cond_init (&thread_count_condvar, NULL); 118 119 for (i = 0; i < NR_THREADS; ++i) 120 pthread_create (&forever[i], NULL, forever_pthread, NULL); 121 122 wait_all_threads_running (); 123 all_threads_running (); 124 125 return 0; 126 } 127 128