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 /* Which tests to perform.
20 Uncomment some of these, to verify that all tests crash if no locking
22 #define DO_TEST_COND 1
23 #define DO_TEST_TIMEDCOND 1
26 /* Whether to help the scheduler through explicit thrd_yield().
27 Uncomment this to see if the operating system has a fair scheduler. */
28 #define EXPLICIT_YIELD 1
30 /* Whether to print debugging messages. */
31 #define ENABLE_DEBUGGING 0
47 # define dbgprintf printf
49 # define dbgprintf if (0) printf
53 # define yield() thrd_yield ()
62 static int cond_value
= 0;
63 static cnd_t condtest
;
64 static mtx_t lockcond
;
67 cnd_wait_routine (void *arg
)
69 ASSERT (mtx_lock (&lockcond
) == thrd_success
);
72 ASSERT (cnd_wait (&condtest
, &lockcond
) == thrd_success
);
74 ASSERT (mtx_unlock (&lockcond
) == thrd_success
);
84 struct timespec remain
;
93 ASSERT (thrd_create (&thread
, cnd_wait_routine
, NULL
) == thrd_success
);
97 ret
= thrd_sleep (&remain
, &remain
);
100 while (ret
== -1 && (remain
.tv_sec
!= 0 || remain
.tv_nsec
!= 0));
102 /* signal condition */
103 ASSERT (mtx_lock (&lockcond
) == thrd_success
);
105 ASSERT (cnd_signal (&condtest
) == thrd_success
);
106 ASSERT (mtx_unlock (&lockcond
) == thrd_success
);
108 ASSERT (thrd_join (thread
, NULL
) == thrd_success
);
116 * Timed Condition check
118 static int cond_timeout
;
121 get_ts (struct timespec
*ts
)
125 gettimeofday (&now
, NULL
);
127 ts
->tv_sec
= now
.tv_sec
+ 1;
128 ts
->tv_nsec
= now
.tv_usec
* 1000;
132 cnd_timedwait_routine (void *arg
)
137 ASSERT (mtx_lock (&lockcond
) == thrd_success
);
141 ret
= cnd_timedwait (&condtest
, &lockcond
, &ts
);
142 if (ret
== thrd_timedout
)
145 ASSERT (mtx_unlock (&lockcond
) == thrd_success
);
151 test_cnd_timedwait (void)
153 struct timespec remain
;
160 cond_value
= cond_timeout
= 0;
162 ASSERT (thrd_create (&thread
, cnd_timedwait_routine
, NULL
) == thrd_success
);
166 ret
= thrd_sleep (&remain
, &remain
);
169 while (ret
== -1 && (remain
.tv_sec
!= 0 || remain
.tv_nsec
!= 0));
171 /* signal condition */
172 ASSERT (mtx_lock (&lockcond
) == thrd_success
);
174 ASSERT (cnd_signal (&condtest
) == thrd_success
);
175 ASSERT (mtx_unlock (&lockcond
) == thrd_success
);
177 ASSERT (thrd_join (thread
, NULL
) == thrd_success
);
187 /* Declare failure if test takes too long, by using default abort
188 caused by SIGALRM. */
189 int alarm_value
= 600;
190 signal (SIGALRM
, SIG_DFL
);
194 ASSERT (cnd_init (&condtest
) == thrd_success
);
195 ASSERT (mtx_init (&lockcond
, mtx_plain
) == thrd_success
);
198 printf ("Starting test_cnd_wait ..."); fflush (stdout
);
200 printf (" OK\n"); fflush (stdout
);
202 #if DO_TEST_TIMEDCOND
203 printf ("Starting test_cnd_timedwait ..."); fflush (stdout
);
204 test_cnd_timedwait ();
205 printf (" OK\n"); fflush (stdout
);