Remove obsolete test from gdb.cp/var-tag.exp
[binutils-gdb.git] / gdb / testsuite / gdb.threads / infcall-from-bp-cond-timeout.c
blob415eaea8ccb7d83f36cf2ceae4ffe3a01e7b2415
1 /* This testcase is part of GDB, the GNU debugger.
3 Copyright 2022-2024 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 #include <stdio.h>
19 #include <pthread.h>
20 #include <unistd.h>
21 #include <stdlib.h>
22 #include <errno.h>
23 #include <semaphore.h>
25 #define NUM_THREADS 5
27 /* Semaphores, used to track when threads have started, and to control
28 when the threads finish. */
29 sem_t startup_semaphore;
30 sem_t finish_semaphore;
31 sem_t thread_1_semaphore;
32 sem_t thread_2_semaphore;
34 /* Mutex to control when the first worker thread hit a breakpoint
35 location. */
36 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
38 /* Global variable to poke, just so threads have something to do. */
39 volatile int global_var = 0;
41 int
42 condition_func ()
44 /* Let thread 2 run. */
45 if (sem_post (&thread_2_semaphore) != 0)
46 abort ();
48 /* Wait for thread 2 to complete its actions. */
49 if (sem_wait (&thread_1_semaphore) != 0)
50 abort ();
52 return 1;
55 void
56 do_segfault ()
58 volatile int *p = 0;
59 *p = 0; /* Segfault here. */
62 void *
63 worker_func (void *arg)
65 int tid = *((int *) arg);
67 /* Let the main thread know that this worker has started. */
68 if (sem_post (&startup_semaphore) != 0)
69 abort ();
71 switch (tid)
73 case 0:
74 /* Wait for MUTEX to become available, then pass through the
75 conditional breakpoint location. */
76 if (pthread_mutex_lock (&mutex) != 0)
77 abort ();
78 global_var = 99; /* Conditional breakpoint here. */
79 if (pthread_mutex_unlock (&mutex) != 0)
80 abort ();
81 break;
83 case 1:
84 if (sem_wait (&thread_2_semaphore) != 0)
85 abort ();
86 do_segfault ();
87 if (sem_post (&thread_1_semaphore) != 0)
88 abort ();
90 /* Fall through. */
91 default:
92 /* Wait until we are allowed to finish. */
93 if (sem_wait (&finish_semaphore) != 0)
94 abort ();
95 break;
99 void
100 stop_marker ()
102 global_var = 99; /* Stop marker. */
105 /* The main program entry point. */
108 main ()
110 pthread_t threads[NUM_THREADS];
111 int args[NUM_THREADS];
112 void *retval;
114 /* An alarm, just in case the thread deadlocks. */
115 alarm (300);
117 /* Semaphore initialization. */
118 if (sem_init (&startup_semaphore, 0, 0) != 0)
119 abort ();
120 if (sem_init (&finish_semaphore, 0, 0) != 0)
121 abort ();
122 if (sem_init (&thread_1_semaphore, 0, 0) != 0)
123 abort ();
124 if (sem_init (&thread_2_semaphore, 0, 0) != 0)
125 abort ();
127 /* Lock MUTEX, this prevents the first worker thread from rushing ahead. */
128 if (pthread_mutex_lock (&mutex) != 0)
129 abort ();
131 /* Worker thread creation. */
132 for (int i = 0; i < NUM_THREADS; i++)
134 args[i] = i;
135 pthread_create (&threads[i], NULL, worker_func, &args[i]);
138 /* Wait for every thread to start. */
139 for (int i = 0; i < NUM_THREADS; i++)
141 if (sem_wait (&startup_semaphore) != 0)
142 abort ();
145 /* Unlock the first thread so it can proceed. */
146 if (pthread_mutex_unlock (&mutex) != 0)
147 abort ();
149 /* Wait for the first thread only. */
150 pthread_join (threads[0], &retval);
152 /* Now post FINISH_SEMAPHORE to allow all the other threads to finish. */
153 for (int i = 1; i < NUM_THREADS; i++)
154 sem_post (&finish_semaphore);
156 /* Now wait for the remaining threads to complete. */
157 for (int i = 1; i < NUM_THREADS; i++)
158 pthread_join (threads[i], &retval);
160 /* Semaphore cleanup. */
161 sem_destroy (&finish_semaphore);
162 sem_destroy (&startup_semaphore);
163 sem_destroy (&thread_1_semaphore);
164 sem_destroy (&thread_2_semaphore);
166 stop_marker ();
168 return 0;