View | Details | Raw Unified | Return to bug 11588 | Differences between
and this patch

Collapse All | Expand All

(-)a/nptl/Makefile (-1 / +1 lines)
Lines 209-215 tests = tst-typesizes \ Link Here
209
	tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
209
	tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
210
	tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
210
	tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
211
	tst-cond20 tst-cond21 tst-cond22 tst-cond23 \
211
	tst-cond20 tst-cond21 tst-cond22 tst-cond23 \
212
	tst-condpi1 \
212
	tst-condpi1 tst-condpi2 \
213
	tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
213
	tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
214
	tst-robust6 tst-robust7 tst-robust8 tst-robust9 \
214
	tst-robust6 tst-robust7 tst-robust8 tst-robust9 \
215
	tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 tst-robustpi5 \
215
	tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 tst-robustpi5 \
(-)a/nptl/tst-condpi2.c (-1 / +292 lines)
Line 0 Link Here
0
- 
1
/* Copyright (C) 2002 Free Software Foundation, Inc.
2
   This file is part of the GNU C Library.
3
   Contributed by Darren Hart <dvhltc@us.ibm.com>
4
   Based on pthread_cond_hang.c by Dinakar Guniguntala <dino@in.ibm.com>
5
6
   The GNU C Library is free software; you can redistribute it and/or
7
   modify it under the terms of the GNU Lesser General Public
8
   License as published by the Free Software Foundation; either
9
   version 2.1 of the License, or (at your option) any later version.
10
11
   The GNU C Library is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
   Lesser General Public License for more details.
15
16
   You should have received a copy of the GNU Lesser General Public
17
   License along with the GNU C Library; if not, write to the Free
18
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19
   02111-1307 USA.  */
20
21
22
#include <error.h>
23
#include <errno.h>
24
#include <pthread.h>
25
#include <sched.h>
26
#include <stdio.h>
27
#include <stdlib.h>
28
#include <string.h>
29
#include <time.h>
30
#include <sys/time.h>
31
#include <unistd.h>
32
33
#define LOW_PRIO  1
34
#define MED_PRIO  2
35
#define HIGH_PRIO 3
36
#define MAIN_PRIO 4
37
38
static pthread_cond_t race_var;
39
static pthread_mutex_t race_mut;
40
41
static pthread_cond_t sig1, sig2, sig3;
42
static pthread_mutex_t m1, m2, m3;
43
44
static volatile unsigned int done = 0;
45
46
static void *
47
low_tf (void *p)
48
{
49
  int err;
50
  
51
  /* Wait for do_test to start all the threads.  */
52
  err = pthread_mutex_lock (&m1);
53
  if (err != 0)
54
    error (EXIT_FAILURE, err, "low_tf: failed to lock m1");
55
  err = pthread_cond_wait (&sig1, &m1);
56
  if (err != 0)
57
    error (EXIT_FAILURE, err, "low_tf: cond_wait failed on sig1");
58
59
  err = pthread_mutex_lock (&race_mut);
60
  if (err != 0)
61
    error (EXIT_FAILURE, err, "low_tf: failed to lock race_mut");
62
63
  puts ("low_tf: locked");
64
65
  /* Signal the high_tf that we have the race_mut, it will preempt us until it
66
   * blocks on race_mut.  */
67
  err = pthread_cond_signal (&sig2);
68
  if (err != 0)
69
    error (EXIT_FAILURE, err, "low_tf: failed to signal sig2");
70
71
  /* pthread_cond_wait() holds the cond_lock when it unlocks race_mut.  high_tf
72
     will preempt us before we can release the cond_lock.  It will signal med_tf
73
     which will continue to block us after high_tf tries to block on race_var if
74
     it isn't PTHREAD_PRIO_INHERIT, and the cond_lock will never be released.  */
75
  err = pthread_cond_wait (&race_var, &race_mut);
76
  if (err != 0)
77
    error (EXIT_FAILURE, err, "low_tf: cond_wait failed on race_var");
78
79
  puts ("low_tf: done waiting");
80
81
  err = pthread_mutex_unlock (&race_mut);
82
  if (err != 0)
83
    error (EXIT_FAILURE, err, "low_tf: failed to unlock race_mut");
84
85
  return NULL;
86
}
87
88
static void *
89
high_tf (void *p)
90
{
91
  int err;
92
93
  err = pthread_mutex_lock (&m2);
94
  if (err != 0)
95
    error (EXIT_FAILURE, err, "high_tf: failed to lock m2");
96
97
  /* Wait for low_tf to take race_mut and signal us.  We will preempt low_tf
98
   * until we block on race_mut below.  */
99
  err = pthread_cond_wait (&sig2, &m2);
100
  if (err != 0)
101
    error (EXIT_FAILURE, err, "high_tf: cond_wait failed on sig2");
102
103
  /* Wait for low_tf to release the lock as it waits on race_var.  */
104
  err = pthread_mutex_lock (&race_mut);
105
  if (err != 0)
106
    error (EXIT_FAILURE, err, "high_tf: failed to lock race_mut");
107
108
  puts ("high_tf: locked");
109
110
  /* Signal the med_tf to start spinning.  */
111
  err = pthread_cond_signal (&sig3);
112
  if (err != 0)
113
    error (EXIT_FAILURE, err, "high_tf: failed to signal sig3");
114
115
  /* If the race_var isn't PTHREAD_PRIO_INHERIT, we will block on the
116
     race_var cond_lock waiting for the low_tf to release it in it's
117
     pthread_cond_wait(&race_var, &race_mut) call.  */
118
  err = pthread_cond_wait (&race_var, &race_mut);
119
  if (err != 0)
120
    error (EXIT_FAILURE, err, "high_tf: cond_wait failed on race_var");
121
122
  puts ("high_tf: done waiting");
123
124
  err = pthread_mutex_unlock (&race_mut);
125
  if (err != 0)
126
    error (EXIT_FAILURE, err, "high_tf: failed to unlock race_mut");
127
128
  done = 1;
129
  return NULL;
130
}
131
132
static void *
133
med_tf (void *p)
134
{
135
  int err;
136
137
  err = pthread_mutex_lock (&m3);
138
  if (err != 0)
139
    error (EXIT_FAILURE, err, "med_tf: failed to lock m3");
140
141
  /* Wait for high_tf to signal us.  */
142
  err = pthread_cond_wait (&sig3, &m3);
143
  if (err != 0)
144
    error (EXIT_FAILURE, err, "med_tf: cond_wait failed on sig3");
145
146
  puts ("med_tf: spinning");
147
148
  while (!done)
149
          /* Busy wait to block low threads.  */;
150
151
  puts ("med_tf: done spinning");
152
153
  return NULL;
154
}
155
156
static int
157
do_test (void)
158
{
159
  pthread_t low_thread;
160
  pthread_t med_thread;
161
  pthread_t high_thread;
162
  struct sched_param param;
163
  pthread_attr_t attr;
164
  pthread_mutexattr_t m_attr;
165
  pthread_condattr_t c_attr;
166
  cpu_set_t cset;
167
168
  int err;
169
170
171
  /* Initialize mutexes and condvars.  */
172
173
  err = pthread_attr_init (&attr);
174
  if (err != 0)
175
    error (EXIT_FAILURE, err, "parent: failed to init pthread_attr");
176
  err = pthread_attr_setinheritsched (&attr, PTHREAD_EXPLICIT_SCHED);
177
  if (err != 0)
178
    error (EXIT_FAILURE, err, "parent: failed to set attr inheritsched");
179
  err = pthread_attr_setschedpolicy (&attr, SCHED_FIFO);
180
  if (err != 0)
181
    error (EXIT_FAILURE, err, "parent: failed to set attr schedpolicy");
182
183
  err = pthread_condattr_init (&c_attr);
184
  if (err != 0)
185
    error (EXIT_FAILURE, err, "parent: failed to init condattr");
186
187
  err = pthread_condattr_setprotocol_np (&c_attr, PTHREAD_PRIO_INHERIT);
188
  if (err != 0)
189
    error (EXIT_FAILURE, err, "parent: failed to set condattr protocol");
190
191
  err = pthread_cond_init (&sig1, &c_attr);
192
  if (err != 0)
193
    error (EXIT_FAILURE, err, "parent: failed to init cond sig1");
194
  err = pthread_cond_init (&sig2, &c_attr);
195
  if (err != 0)
196
    error (EXIT_FAILURE, err, "parent: failed to init cond sig2");
197
  err = pthread_cond_init (&sig3, &c_attr);
198
  if (err != 0)
199
    error (EXIT_FAILURE, err, "parent: failed to init cond sig3");
200
  err = pthread_cond_init (&race_var, &c_attr);
201
  if (err != 0)
202
    error (EXIT_FAILURE, err, "parent: failed to init cond race_var");
203
204
  err = pthread_mutexattr_init (&m_attr);
205
  if (err != 0)
206
    error (EXIT_FAILURE, err, "parent: failed to init mutexattr");
207
  err = pthread_mutexattr_setprotocol (&m_attr, PTHREAD_PRIO_INHERIT);
208
  if (err != 0)
209
    error (EXIT_FAILURE, err, "parent: failed to set mutexattr protocol");
210
  err = pthread_mutex_init (&m1, &m_attr);
211
  if (err != 0)
212
    error (EXIT_FAILURE, err, "parent: failed to init mutex m1");
213
  err = pthread_mutex_init (&m2, &m_attr);
214
  if (err != 0)
215
    error (EXIT_FAILURE, err, "parent: failed to init mutex m2");
216
  err = pthread_mutex_init (&m3, &m_attr);
217
  if (err != 0)
218
    error (EXIT_FAILURE, err, "parent: failed to init mutex m3");
219
  err = pthread_mutex_init (&race_mut, &m_attr);
220
  if (err != 0)
221
    error (EXIT_FAILURE, err, "parent: failed to init mutex race_mut");
222
223
  /* Setup scheduling parameters and create threads.  */
224
  param.sched_priority = MAIN_PRIO;
225
  err = sched_setscheduler (0, SCHED_FIFO, &param);
226
  if (err != 0)
227
    error (EXIT_FAILURE, err, "parent: failed to set scheduler policy");
228
229
  CPU_ZERO (&cset);
230
  CPU_SET (0, &cset);
231
  err = sched_setaffinity (0, sizeof (cpu_set_t), &cset);
232
  if (err != 0)
233
    error (EXIT_FAILURE, err, "parent: failed to set CPU affinity");
234
235
  param.sched_priority = LOW_PRIO;
236
  err = pthread_attr_setschedparam (&attr, &param);
237
  if (err != 0)
238
    error (EXIT_FAILURE, err, "parent: failed to set sched param for low_tf");
239
  err = pthread_create (&low_thread, &attr, low_tf, (void*)NULL);
240
  if (err != 0)
241
    error (EXIT_FAILURE, err, "parent: failed to create low_tf");
242
243
  param.sched_priority = MED_PRIO;
244
  err = pthread_attr_setschedparam (&attr, &param);
245
  if (err != 0)
246
    error (EXIT_FAILURE, err, "parent: failed to set sched param for med_tf");
247
  pthread_create (&med_thread, &attr, med_tf, (void*)NULL);
248
  if (err != 0)
249
    error (EXIT_FAILURE, err, "parent: failed to create med_tf");
250
251
  param.sched_priority = HIGH_PRIO;
252
  err = pthread_attr_setschedparam (&attr, &param);
253
  if (err != 0)
254
    error (EXIT_FAILURE, err, "parent: failed to set sched param for high_tf");
255
  err = pthread_create (&high_thread, &attr, high_tf, (void*)NULL);
256
  if (err != 0)
257
    error (EXIT_FAILURE, err, "parent: failed to create high_tf");
258
259
  /* Wait for the threads to start and block on their respective condvars.  */
260
  usleep (1000);
261
  err = pthread_cond_signal (&sig1);
262
  if (err != 0)
263
    error (EXIT_FAILURE, err, "parent: failed to signal condition");
264
265
  /* Wake low_tf and high_tf, allowing them to complete.  If race_var is not
266
     PTHREAD_PRIO_INHERIT, low_tf will not have released the race_var cond_lock
267
     and neither thread will have waited on race_var.  */
268
  usleep (1000);
269
  err = pthread_cond_broadcast (&race_var);
270
  if (err != 0)
271
    error (EXIT_FAILURE, err, "parent: failed to broadcast condition");
272
273
  /* Wait for threads to complete.  */
274
  err = pthread_join (low_thread, (void**) NULL);
275
  if (err != 0)
276
    error (EXIT_FAILURE, err, "join of low_tf failed");
277
  err = pthread_join (med_thread, (void**) NULL);
278
  if (err != 0)
279
    error (EXIT_FAILURE, err, "join of med_tf failed");
280
  err = pthread_join (high_thread, (void**) NULL);
281
  if (err != 0)
282
    error (EXIT_FAILURE, err, "join of high_tf failed");
283
284
  puts ("done");
285
286
  return 0;
287
}
288
289
290
#define TIMEOUT 2
291
#define TEST_FUNCTION do_test ()
292
#include "../test-skeleton.c"

Return to bug 11588