]>
Commit | Line | Data |
---|---|---|
1d506c26 | 1 | /* Copyright 2023-2024 Free Software Foundation, Inc. |
2968b79f AB |
2 | |
3 | This file is part of GDB. | |
4 | ||
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. | |
9 | ||
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. | |
14 | ||
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/>. */ | |
17 | ||
18 | #include <pthread.h> | |
19 | #include <unistd.h> | |
20 | #include <stdlib.h> | |
21 | ||
22 | #define NTHREAD 1 | |
23 | ||
24 | /* Barrier for synchronising threads. */ | |
25 | static pthread_barrier_t barrier; | |
26 | ||
27 | /* Wrapper around pthread_barrier_wait that aborts if the wait returns an | |
28 | error. */ | |
29 | static void | |
30 | barrier_wait (pthread_barrier_t *barrier) | |
31 | { | |
32 | int res = pthread_barrier_wait (barrier); | |
33 | if (res != PTHREAD_BARRIER_SERIAL_THREAD && res != 0) | |
34 | abort (); | |
35 | } | |
36 | ||
37 | /* GDB can set this to 0 to force the 'spin' function to return. */ | |
38 | volatile int do_spin = 1; | |
39 | ||
40 | void | |
41 | breakpt () | |
42 | { | |
43 | /* Nothing. */ | |
44 | } | |
45 | ||
46 | /* Spin for a reasonably long while (this lets GDB run some commands in | |
47 | async mode), but return early if/when do_spin is set to 0 (which is done | |
48 | by GDB). */ | |
49 | ||
50 | void | |
51 | spin () | |
52 | { | |
53 | int i; | |
54 | ||
55 | for (i = 0; i < 300 && do_spin; ++i) | |
56 | sleep (1); | |
57 | } | |
58 | ||
59 | void * | |
60 | thread_worker (void *arg) | |
61 | { | |
62 | barrier_wait (&barrier); | |
63 | return NULL; | |
64 | } | |
65 | ||
66 | int | |
67 | main () | |
68 | { | |
69 | pthread_t thr[NTHREAD]; | |
70 | int i; | |
71 | ||
72 | if (pthread_barrier_init (&barrier, NULL, NTHREAD + 1) != 0) | |
73 | abort (); | |
74 | ||
75 | for (i = 0; i < NTHREAD; ++i) | |
76 | pthread_create (&thr[i], NULL, thread_worker, NULL); | |
77 | ||
78 | breakpt (); /* First breakpoint. */ | |
79 | ||
80 | barrier_wait (&barrier); | |
81 | ||
82 | for (i = 0; i < NTHREAD; ++i) | |
83 | pthread_join (thr[i], NULL); | |
84 | ||
85 | spin (); | |
86 | ||
87 | breakpt (); | |
88 | } |