1/* This testcase is part of GDB, the GNU debugger.
2
3   Copyright 2016-2023 Free Software Foundation, Inc.
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*/
19
20#include <pthread.h>
21#include <unistd.h>
22#include <stdint.h>
23
24#define NUM_THREADS 2
25
26static volatile int unblock_main[NUM_THREADS];
27
28static void
29child_sub_function (int child_idx)
30{
31  volatile int dummy = 0;
32
33  unblock_main[child_idx] = 1;
34
35  while (1)
36    /* Dummy loop body to allow setting breakpoint.  */
37    dummy = !dummy; /* thread loop line */
38}
39
40static void *
41child_function (void *args)
42{
43  int child_idx = (int) (uintptr_t) args;
44
45  child_sub_function (child_idx); /* thread caller line */
46
47  return NULL;
48}
49
50int
51main (void)
52{
53  int i = 0;
54  pthread_t threads[NUM_THREADS];
55
56  /* Make the test exit eventually.  */
57  alarm (20);
58
59  for (i = 0; i < NUM_THREADS; i++)
60    pthread_create (&threads[i], NULL, child_function, (void *) (uintptr_t) i);
61
62  /* Wait for child threads to reach child_sub_function.  */
63  for (i = 0; i < NUM_THREADS; i++)
64    while (!unblock_main[i])
65      ;
66
67  volatile int dummy = 0;
68  while (1)
69    /* Dummy loop body to allow setting breakpoint.  */
70    dummy = !dummy; /* main break line */
71
72  return 0;
73}
74