1 /* Test of condition variables in multithreaded situations.
2 Copyright (C) 2008-2020 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
19 #if USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS
21 /* Which tests to perform.
22 Uncomment some of these, to verify that all tests crash if no locking
24 #define DO_TEST_COND 1
25 #define DO_TEST_TIMEDCOND 1
27 /* Whether to help the scheduler through explicit sched_yield().
28 Uncomment this to see if the operating system has a fair scheduler. */
29 #define EXPLICIT_YIELD 1
31 /* Whether to print debugging messages. */
32 #define ENABLE_DEBUGGING 0
52 # define dbgprintf printf
54 # define dbgprintf if (0) printf
58 # define yield() sched_yield ()
67 static int cond_value
= 0;
68 static pthread_cond_t condtest
;
69 static pthread_mutex_t lockcond
;
72 pthread_cond_wait_routine (void *arg
)
74 ASSERT (pthread_mutex_lock (&lockcond
) == 0);
77 ASSERT (pthread_cond_wait (&condtest
, &lockcond
) == 0);
79 ASSERT (pthread_mutex_unlock (&lockcond
) == 0);
87 test_pthread_cond_wait ()
89 struct timespec remain
;
98 ASSERT (pthread_create (&thread
, NULL
, pthread_cond_wait_routine
, NULL
) == 0);
102 ret
= nanosleep (&remain
, &remain
);
105 while (ret
== -1 && (remain
.tv_sec
!= 0 || remain
.tv_nsec
!= 0));
107 /* signal condition */
108 ASSERT (pthread_mutex_lock (&lockcond
) == 0);
110 ASSERT (pthread_cond_signal (&condtest
) == 0);
111 ASSERT (pthread_mutex_unlock (&lockcond
) == 0);
113 ASSERT (pthread_join (thread
, NULL
) == 0);
121 * Timed Condition check
123 static int cond_timeout
;
126 get_ts (struct timespec
*ts
)
130 gettimeofday (&now
, NULL
);
132 ts
->tv_sec
= now
.tv_sec
+ 1;
133 ts
->tv_nsec
= now
.tv_usec
* 1000;
137 pthread_cond_timedwait_routine (void *arg
)
142 ASSERT (pthread_mutex_lock (&lockcond
) == 0);
146 ret
= pthread_cond_timedwait (&condtest
, &lockcond
, &ts
);
147 if (ret
== ETIMEDOUT
)
150 ASSERT (pthread_mutex_unlock (&lockcond
) == 0);
156 test_pthread_cond_timedwait (void)
158 struct timespec remain
;
165 cond_value
= cond_timeout
= 0;
167 ASSERT (pthread_create (&thread
, NULL
, pthread_cond_timedwait_routine
, NULL
)
172 ret
= nanosleep (&remain
, &remain
);
175 while (ret
== -1 && (remain
.tv_sec
!= 0 || remain
.tv_nsec
!= 0));
177 /* signal condition */
178 ASSERT (pthread_mutex_lock (&lockcond
) == 0);
180 ASSERT (pthread_cond_signal (&condtest
) == 0);
181 ASSERT (pthread_mutex_unlock (&lockcond
) == 0);
183 ASSERT (pthread_join (thread
, NULL
) == 0);
193 /* Declare failure if test takes too long, by using default abort
194 caused by SIGALRM. */
195 int alarm_value
= 600;
196 signal (SIGALRM
, SIG_DFL
);
200 ASSERT (pthread_cond_init (&condtest
, NULL
) == 0);
203 pthread_mutexattr_t attr
;
205 ASSERT (pthread_mutexattr_init (&attr
) == 0);
206 ASSERT (pthread_mutexattr_settype (&attr
, PTHREAD_MUTEX_NORMAL
) == 0);
207 ASSERT (pthread_mutex_init (&lockcond
, &attr
) == 0);
208 ASSERT (pthread_mutexattr_destroy (&attr
) == 0);
212 printf ("Starting test_pthread_cond_wait ..."); fflush (stdout
);
213 test_pthread_cond_wait ();
214 printf (" OK\n"); fflush (stdout
);
216 #if DO_TEST_TIMEDCOND
217 printf ("Starting test_pthread_cond_timedwait ..."); fflush (stdout
);
218 test_pthread_cond_timedwait ();
219 printf (" OK\n"); fflush (stdout
);
227 /* No multithreading available. */
234 fputs ("Skipping test: multithreading not enabled\n", stderr
);