]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/testsuite/gdb.threads/interrupted-hand-call.c
Update years in copyright notice for the GDB files.
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.threads / interrupted-hand-call.c
CommitLineData
b89667eb
DE
1/* Test case for hand function calls interrupted by a signal in another thread.
2
8acc9f48 3 Copyright 2008-2013 Free Software Foundation, Inc.
b89667eb
DE
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 <signal.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <time.h>
25#include <unistd.h>
26
27#ifndef NR_THREADS
28#define NR_THREADS 4
29#endif
30
31pthread_t threads[NR_THREADS];
32
33/* Number of threads currently running. */
34int thread_count;
35
36pthread_mutex_t thread_count_mutex;
37
38pthread_cond_t thread_count_condvar;
39
40sig_atomic_t sigabrt_received;
41
42void
43incr_thread_count (void)
44{
45 pthread_mutex_lock (&thread_count_mutex);
46 ++thread_count;
47 if (thread_count == NR_THREADS)
48 pthread_cond_signal (&thread_count_condvar);
49 pthread_mutex_unlock (&thread_count_mutex);
50}
51
52void
53cond_wait (pthread_cond_t *cond, pthread_mutex_t *mut)
54{
55 pthread_mutex_lock (mut);
56 pthread_cond_wait (cond, mut);
57 pthread_mutex_unlock (mut);
58}
59
60void
61noreturn (void)
62{
63 pthread_mutex_t mut;
64 pthread_cond_t cond;
65
66 pthread_mutex_init (&mut, NULL);
67 pthread_cond_init (&cond, NULL);
68
69 /* Wait for a condition that will never be signaled, so we effectively
70 block the thread here. */
71 cond_wait (&cond, &mut);
72}
73
74void *
75thread_entry (void *unused)
76{
77 incr_thread_count ();
78 noreturn ();
79}
80
81void
82sigabrt_handler (int signo)
83{
84 sigabrt_received = 1;
85}
86
87/* Helper to test a hand-call being "interrupted" by a signal on another
88 thread. */
89
90void
91hand_call_with_signal (void)
92{
93 const struct timespec ts = { 0, 10000000 }; /* 0.01 sec */
94
95 sigabrt_received = 0;
96 pthread_kill (threads[0], SIGABRT);
97 while (! sigabrt_received)
98 nanosleep (&ts, NULL);
99}
100
101/* Wait until all threads are running. */
102
103void
104wait_all_threads_running (void)
105{
106 pthread_mutex_lock (&thread_count_mutex);
107 if (thread_count == NR_THREADS)
108 {
109 pthread_mutex_unlock (&thread_count_mutex);
110 return;
111 }
112 pthread_cond_wait (&thread_count_condvar, &thread_count_mutex);
113 if (thread_count == NR_THREADS)
114 {
115 pthread_mutex_unlock (&thread_count_mutex);
116 return;
117 }
118 pthread_mutex_unlock (&thread_count_mutex);
119 printf ("failed waiting for all threads to start\n");
120 abort ();
121}
122
123/* Called when all threads are running.
124 Easy place for a breakpoint. */
125
126void
127all_threads_running (void)
128{
129}
130
131int
132main (void)
133{
134 int i;
135
136 signal (SIGABRT, sigabrt_handler);
137
138 pthread_mutex_init (&thread_count_mutex, NULL);
139 pthread_cond_init (&thread_count_condvar, NULL);
140
141 for (i = 0; i < NR_THREADS; ++i)
142 pthread_create (&threads[i], NULL, thread_entry, NULL);
143
144 wait_all_threads_running ();
145 all_threads_running ();
146
147 return 0;
148}
149