1 /* POSIX condition variables.
2 Copyright (C) 2010-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 2, or (at your option)
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 /* Written by Paul Eggert, 2010, and Bruno Haible <bruno@clisp.org>, 2019. */
24 #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS
25 # include "windows-thread.h"
29 # include <sys/time.h>
33 #if ((defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS) || !HAVE_PTHREAD_H
36 pthread_condattr_init (pthread_condattr_t
*attr
)
43 pthread_condattr_destroy (pthread_condattr_t
*attr _GL_UNUSED
)
50 #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS
51 /* Use Windows threads. */
54 pthread_cond_init (pthread_cond_t
*cond
,
55 const pthread_condattr_t
*attr _GL_UNUSED
)
57 return glwthread_cond_init (cond
);
61 pthread_cond_wait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
)
63 return glwthread_cond_wait (cond
, mutex
,
64 (int (*) (void *)) pthread_mutex_lock
,
65 (int (*) (void *)) pthread_mutex_unlock
);
69 pthread_cond_timedwait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
,
70 const struct timespec
*abstime
)
72 return glwthread_cond_timedwait (cond
, mutex
,
73 (int (*) (void *)) pthread_mutex_lock
,
74 (int (*) (void *)) pthread_mutex_unlock
,
79 pthread_cond_signal (pthread_cond_t
*cond
)
81 return glwthread_cond_signal (cond
);
85 pthread_cond_broadcast (pthread_cond_t
*cond
)
87 return glwthread_cond_broadcast (cond
);
91 pthread_cond_destroy (pthread_cond_t
*cond
)
93 return glwthread_cond_destroy (cond
);
97 /* Provide workarounds for POSIX threads. */
100 /* Provide a dummy implementation for single-threaded applications. */
103 pthread_cond_init (pthread_cond_t
*cond _GL_UNUSED
,
104 const pthread_condattr_t
*attr _GL_UNUSED
)
106 /* COND is never seriously used. */
111 pthread_cond_wait (pthread_cond_t
*cond _GL_UNUSED
,
112 pthread_mutex_t
*mutex _GL_UNUSED
)
114 /* No other thread can signal this condition variable.
118 struct timespec duration
;
120 duration
.tv_sec
= 86400;
121 duration
.tv_usec
= 0;
122 nanosleep (&duration
, NULL
);
127 pthread_cond_timedwait (pthread_cond_t
*cond _GL_UNUSED
,
128 pthread_mutex_t
*mutex _GL_UNUSED
,
129 const struct timespec
*abstime
)
131 /* No other thread can signal this condition variable.
132 Wait until ABSTIME is reached. */
135 struct timeval currtime
;
136 unsigned long remaining
;
137 struct timespec duration
;
139 gettimeofday (&currtime
, NULL
);
141 if (currtime
.tv_sec
> abstime
->tv_sec
)
145 unsigned long seconds
= abstime
->tv_sec
- currtime
.tv_sec
;
146 remaining
= seconds
* 1000000000;
147 if (remaining
/ 1000000000 != seconds
) /* overflow? */
148 remaining
= ULONG_MAX
;
152 abstime
->tv_nsec
- currtime
.tv_usec
* 1000;
153 if (nanoseconds
>= 0)
155 remaining
+= nanoseconds
;
156 if (remaining
< nanoseconds
) /* overflow? */
157 remaining
= ULONG_MAX
;
161 if (remaining
>= - nanoseconds
)
162 remaining
-= (- nanoseconds
);
171 /* Sleep up to REMAINING ns. */
172 duration
.tv_sec
= remaining
/ 1000000000;
173 duration
.tv_nsec
= remaining
% 1000000000;
174 nanosleep (&duration
, NULL
);
179 pthread_cond_signal (pthread_cond_t
*cond _GL_UNUSED
)
181 /* No threads can currently be blocked on COND. */
186 pthread_cond_broadcast (pthread_cond_t
*cond _GL_UNUSED
)
188 /* No threads can currently be blocked on COND. */
193 pthread_cond_destroy (pthread_cond_t
*cond _GL_UNUSED
)
195 /* COND is never seriously used. */