maint: update copyright
[gnulib.git] / tests / test-cond.c
1 /* Test of condition variables in multithreaded situations.
2    Copyright (C) 2008-2014 Free Software Foundation, Inc.
3
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.
8
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.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16
17 #include <config.h>
18
19 #if USE_POSIX_THREADS || USE_SOLARIS_THREADS || USE_PTH_THREADS || USE_WINDOWS_THREADS
20
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
26
27
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
31
32 /* Whether to print debugging messages.  */
33 #define ENABLE_DEBUGGING 0
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sys/time.h>
39
40 #include "glthread/cond.h"
41 #include "glthread/lock.h"
42 #include "glthread/thread.h"
43 #include "glthread/yield.h"
44
45 #if ENABLE_DEBUGGING
46 # define dbgprintf printf
47 #else
48 # define dbgprintf if (0) printf
49 #endif
50
51 #if EXPLICIT_YIELD
52 # define yield() gl_thread_yield ()
53 #else
54 # define yield()
55 #endif
56
57
58 /*
59  * Condition check
60  */
61 #include <unistd.h>
62 static int cond_value = 0;
63 gl_cond_define_initialized(static, condtest)
64 gl_lock_define_initialized(static, lockcond)
65
66 static void *
67 cond_routine (void *arg)
68 {
69   gl_lock_lock (lockcond);
70   while (!cond_value)
71     {
72       gl_cond_wait (condtest, lockcond);
73     }
74   gl_lock_unlock (lockcond);
75
76   cond_value = 2;
77
78   return NULL;
79 }
80
81 void
82 test_cond ()
83 {
84   int remain = 2;
85   gl_thread_t thread;
86
87   cond_value = 0;
88
89   thread = gl_thread_create (cond_routine, NULL);
90   do
91     {
92       yield ();
93       remain = sleep (remain);
94     }
95   while (remain);
96
97   /* signal condition */
98   gl_lock_lock (lockcond);
99   cond_value = 1;
100   gl_cond_signal (condtest);
101   gl_lock_unlock (lockcond);
102
103   gl_thread_join (thread, NULL);
104
105   if (cond_value != 2)
106     abort ();
107 }
108
109
110 /*
111  * Timed Condition check
112  */
113 static int cond_timeout;
114
115 static void
116 get_ts (struct timespec *ts)
117 {
118   struct timeval now;
119
120   gettimeofday (&now, NULL);
121
122   ts->tv_sec = now.tv_sec + 1;
123   ts->tv_nsec = now.tv_usec * 1000;
124 }
125
126 static void *
127 timedcond_routine (void *arg)
128 {
129   int ret;
130   struct timespec ts;
131
132   gl_lock_lock (lockcond);
133   while (!cond_value)
134     {
135       get_ts (&ts);
136       ret = glthread_cond_timedwait (&condtest, &lockcond, &ts);
137       if (ret == ETIMEDOUT)
138         cond_timeout = 1;
139     }
140   gl_lock_unlock (lockcond);
141
142   return NULL;
143 }
144
145 static void
146 test_timedcond (void)
147 {
148   int remain = 2;
149   gl_thread_t thread;
150
151   cond_value = cond_timeout = 0;
152
153   thread = gl_thread_create (timedcond_routine, NULL);
154
155   remain = 2;
156   do
157     {
158       yield ();
159       remain = sleep (remain);
160     }
161   while (remain);
162
163   /* signal condition */
164   gl_lock_lock (lockcond);
165   cond_value = 1;
166   gl_cond_signal (condtest);
167   gl_lock_unlock (lockcond);
168
169   gl_thread_join (thread, NULL);
170
171   if (!cond_timeout)
172     abort ();
173 }
174
175 int
176 main ()
177 {
178 #if TEST_PTH_THREADS
179   if (!pth_init ())
180     abort ();
181 #endif
182
183 #if DO_TEST_COND
184   printf ("Starting test_cond ..."); fflush (stdout);
185   test_cond ();
186   printf (" OK\n"); fflush (stdout);
187 #endif
188 #if DO_TEST_TIMEDCOND
189   printf ("Starting test_timedcond ..."); fflush (stdout);
190   test_timedcond ();
191   printf (" OK\n"); fflush (stdout);
192 #endif
193
194   return 0;
195 }
196
197 #else
198
199 /* No multithreading available.  */
200
201 #include <stdio.h>
202
203 int
204 main ()
205 {
206   fputs ("Skipping test: multithreading not enabled\n", stderr);
207   return 77;
208 }
209
210 #endif