OSDN Git Service

modified: utilsrc/src/Admin/Makefile
[eos/others.git] / utilsrc / srcX86MAC64 / Admin / gdb-7.7.1 / gdb / testsuite / gdb.threads / interrupted-hand-call.c
1 /* Test case for hand function calls interrupted by a signal in another thread.
2
3    Copyright 2008-2014 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 <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
31 pthread_t threads[NR_THREADS];
32
33 /* Number of threads currently running.  */
34 int thread_count;
35
36 pthread_mutex_t thread_count_mutex;
37
38 pthread_cond_t thread_count_condvar;
39
40 sig_atomic_t sigabrt_received;
41
42 void
43 incr_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
52 void
53 cond_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
60 void
61 noreturn (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
74 void *
75 thread_entry (void *unused)
76 {
77   incr_thread_count ();
78   noreturn ();
79 }
80
81 void
82 sigabrt_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
90 void
91 hand_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
103 void
104 wait_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
126 void
127 all_threads_running (void)
128 {
129 }
130
131 int
132 main (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