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

Collapse All | Expand All

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

Return to bug 11588