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 30int thread_count; 31 32pthread_mutex_t thread_count_mutex; 33 34pthread_cond_t thread_count_condvar; 35 36void 37incr_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 46void 47cond_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 54void 55noreturn (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 68void * 69forever_pthread (void *unused) 70{ 71 incr_thread_count (); 72 noreturn (); 73} 74 75void 76hand_call (void) 77{ 78} 79 80/* Wait until all threads are running. */ 81 82void 83wait_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 105void 106all_threads_running (void) 107{ 108} 109 110int 111main (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