exp2l: Work around a NetBSD 10.0/i386 bug.
[gnulib.git] / lib / cnd.c
blobc531660a9c186a8d312a5e5bc1910e83e1670b53
1 /* ISO C 11 condition variables for multithreading.
2 Copyright (C) 2008-2024 Free Software Foundation, Inc.
4 This file is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2.1 of the
7 License, or (at your option) any later version.
9 This file 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 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 /* Written by Yoann Vandoorselaere <yoann@prelude-ids.org>, 2008,
18 and Bruno Haible <bruno@clisp.org>, 2008, 2019. */
20 #include <config.h>
22 #include <threads.h>
24 #include <errno.h>
25 #include <stdlib.h>
27 #if defined _WIN32 && ! defined __CYGWIN__
28 /* Use Windows threads. */
30 # define WIN32_LEAN_AND_MEAN /* avoid including junk */
31 # include <windows.h>
33 # include "windows-mutex.h"
34 # include "windows-recmutex.h"
35 # include "windows-timedmutex.h"
36 # include "windows-timedrecmutex.h"
38 #else
39 /* Use POSIX threads. */
41 # include <pthread.h>
43 #endif
45 #if defined _WIN32 && ! defined __CYGWIN__
46 /* Use Windows threads. */
48 int
49 cnd_init (cnd_t *cond)
51 int err = glwthread_cond_init (cond);
52 return (err == 0 ? thrd_success :
53 err == ENOMEM ? thrd_nomem :
54 thrd_error);
57 static int
58 mutex_lock (mtx_t *mutex)
60 switch (mutex->type)
62 case mtx_plain:
63 return glwthread_mutex_lock (&mutex->u.u_mutex);
64 case mtx_plain | mtx_recursive:
65 return glwthread_recmutex_lock (&mutex->u.u_recmutex);
66 case mtx_timed:
67 return glwthread_timedmutex_lock (&mutex->u.u_timedmutex);
68 case mtx_timed | mtx_recursive:
69 return glwthread_timedrecmutex_lock (&mutex->u.u_timedrecmutex);
70 default:
71 abort ();
75 static int
76 mutex_unlock (mtx_t *mutex)
78 switch (mutex->type)
80 case mtx_plain:
81 return glwthread_mutex_unlock (&mutex->u.u_mutex);
82 case mtx_plain | mtx_recursive:
83 return glwthread_recmutex_unlock (&mutex->u.u_recmutex);
84 case mtx_timed:
85 return glwthread_timedmutex_unlock (&mutex->u.u_timedmutex);
86 case mtx_timed | mtx_recursive:
87 return glwthread_timedrecmutex_unlock (&mutex->u.u_timedrecmutex);
88 default:
89 abort ();
93 int
94 cnd_wait (cnd_t *cond, mtx_t *mutex)
96 int err = glwthread_cond_wait (cond, mutex,
97 (int (*) (void *)) mutex_lock,
98 (int (*) (void *)) mutex_unlock);
99 return (err == 0 ? thrd_success : thrd_error);
103 cnd_timedwait (cnd_t *cond, mtx_t *mutex, const struct timespec *abstime)
105 int err = glwthread_cond_timedwait (cond, mutex,
106 (int (*) (void *)) mutex_lock,
107 (int (*) (void *)) mutex_unlock,
108 abstime);
109 return (err == 0 ? thrd_success :
110 err == ETIMEDOUT ? thrd_timedout :
111 thrd_error);
115 cnd_signal (cnd_t *cond)
117 int err = glwthread_cond_signal (cond);
118 return (err == 0 ? thrd_success :
119 err == ENOMEM ? thrd_nomem :
120 thrd_error);
124 cnd_broadcast (cnd_t *cond)
126 int err = glwthread_cond_broadcast (cond);
127 return (err == 0 ? thrd_success : thrd_error);
130 void
131 cnd_destroy (cnd_t *cond)
133 glwthread_cond_destroy (cond);
136 #else
137 /* Use POSIX threads. */
140 cnd_init (cnd_t *cond)
142 int err = pthread_cond_init (cond, NULL);
143 return (err == 0 ? thrd_success :
144 err == ENOMEM ? thrd_nomem :
145 thrd_error);
149 cnd_wait (cnd_t *cond, mtx_t *mutex)
151 int err = pthread_cond_wait (cond, mutex);
152 return (err == 0 ? thrd_success : thrd_error);
156 cnd_timedwait (cnd_t *cond, mtx_t *mutex, const struct timespec *abstime)
158 int err = pthread_cond_timedwait (cond, mutex, abstime);
159 return (err == 0 ? thrd_success :
160 err == ETIMEDOUT ? thrd_timedout :
161 thrd_error);
165 cnd_signal (cnd_t *cond)
167 int err = pthread_cond_signal (cond);
168 return (err == 0 ? thrd_success :
169 err == ENOMEM ? thrd_nomem :
170 thrd_error);
174 cnd_broadcast (cnd_t *cond)
176 int err = pthread_cond_broadcast (cond);
177 return (err == 0 ? thrd_success : thrd_error);
180 void
181 cnd_destroy (cnd_t *cond)
183 pthread_cond_destroy (cond);
186 #endif