usleep tests: Avoid failure due to known Cygwin 3.5.3 bug.
[gnulib.git] / tests / test-cond.c
bloba9b1e03406be2abc098eb91c0edd14df4933bcd8
1 /* Test of condition variables in multithreaded situations.
2 Copyright (C) 2008-2024 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/>. */
17 #include <config.h>
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
23 is enabled. */
24 #define DO_TEST_COND 1
25 #define DO_TEST_TIMEDCOND 1
28 /* Whether to help the scheduler through explicit yield().
29 Uncomment this to see if the operating system has a fair scheduler. */
30 #define EXPLICIT_YIELD 1
32 /* Whether to print debugging messages. */
33 #define ENABLE_DEBUGGING 0
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sys/time.h>
39 #include <unistd.h>
41 #include "glthread/cond.h"
42 #include "glthread/lock.h"
43 #include "glthread/thread.h"
44 #include "glthread/yield.h"
46 #if ENABLE_DEBUGGING
47 # define dbgprintf printf
48 #else
49 # define dbgprintf if (0) printf
50 #endif
52 #if EXPLICIT_YIELD
53 # define yield() gl_thread_yield ()
54 #else
55 # define yield()
56 #endif
60 * Condition check
62 static int cond_value = 0;
63 gl_cond_define_initialized(static, condtest)
64 gl_lock_define_initialized(static, lockcond)
66 static void *
67 cond_routine (void *arg)
69 gl_lock_lock (lockcond);
70 while (!cond_value)
72 gl_cond_wait (condtest, lockcond);
74 gl_lock_unlock (lockcond);
76 cond_value = 2;
78 return NULL;
81 static void
82 test_cond ()
84 int remain = 2;
85 gl_thread_t thread;
87 cond_value = 0;
89 thread = gl_thread_create (cond_routine, NULL);
92 yield ();
93 remain = sleep (remain);
95 while (remain);
97 /* signal condition */
98 gl_lock_lock (lockcond);
99 cond_value = 1;
100 gl_cond_signal (condtest);
101 gl_lock_unlock (lockcond);
103 gl_thread_join (thread, NULL);
105 if (cond_value != 2)
106 abort ();
111 * Timed Condition check
113 static int cond_timeout;
115 static void
116 get_ts (struct timespec *ts)
118 struct timeval now;
120 gettimeofday (&now, NULL);
122 ts->tv_sec = now.tv_sec + 1;
123 ts->tv_nsec = now.tv_usec * 1000;
126 static void *
127 timedcond_routine (void *arg)
129 int ret;
130 struct timespec ts;
132 gl_lock_lock (lockcond);
133 while (!cond_value)
135 get_ts (&ts);
136 ret = glthread_cond_timedwait (&condtest, &lockcond, &ts);
137 if (ret == ETIMEDOUT)
138 cond_timeout = 1;
140 gl_lock_unlock (lockcond);
142 return NULL;
145 static void
146 test_timedcond (void)
148 int remain = 2;
149 gl_thread_t thread;
151 cond_value = cond_timeout = 0;
153 thread = gl_thread_create (timedcond_routine, NULL);
156 yield ();
157 remain = sleep (remain);
159 while (remain);
161 /* signal condition */
162 gl_lock_lock (lockcond);
163 cond_value = 1;
164 gl_cond_signal (condtest);
165 gl_lock_unlock (lockcond);
167 gl_thread_join (thread, NULL);
169 if (!cond_timeout)
170 abort ();
174 main ()
176 #if DO_TEST_COND
177 printf ("Starting test_cond ..."); fflush (stdout);
178 test_cond ();
179 printf (" OK\n"); fflush (stdout);
180 #endif
181 #if DO_TEST_TIMEDCOND
182 printf ("Starting test_timedcond ..."); fflush (stdout);
183 test_timedcond ();
184 printf (" OK\n"); fflush (stdout);
185 #endif
187 return 0;
190 #else
192 /* No multithreading available. */
194 #include <stdio.h>
197 main ()
199 fputs ("Skipping test: multithreading not enabled\n", stderr);
200 return 77;
203 #endif