xref: /openbsd/lib/librthread/synch.h (revision 2e686a7f)
1*2e686a7fScheloha /*	$OpenBSD: synch.h,v 1.10 2024/01/07 19:44:28 cheloha Exp $ */
24b11781bSpirofti /*
34b11781bSpirofti  * Copyright (c) 2017 Martin Pieuchot
44b11781bSpirofti  *
54b11781bSpirofti  * Permission to use, copy, modify, and distribute this software for any
64b11781bSpirofti  * purpose with or without fee is hereby granted, provided that the above
74b11781bSpirofti  * copyright notice and this permission notice appear in all copies.
84b11781bSpirofti  *
94b11781bSpirofti  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
104b11781bSpirofti  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
114b11781bSpirofti  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
124b11781bSpirofti  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
134b11781bSpirofti  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
144b11781bSpirofti  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
154b11781bSpirofti  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
164b11781bSpirofti  */
174b11781bSpirofti 
184b11781bSpirofti #include <sys/atomic.h>
194b11781bSpirofti #include <sys/time.h>
204b11781bSpirofti #include <sys/futex.h>
214b11781bSpirofti 
224b11781bSpirofti static inline int
_wake(volatile uint32_t * p,int n)234b11781bSpirofti _wake(volatile uint32_t *p, int n)
244b11781bSpirofti {
25bc52b28aSsthen 	return futex(p, FUTEX_WAKE, n, NULL, NULL);
26bc52b28aSsthen }
27bc52b28aSsthen 
284b11781bSpirofti static inline int
_twait(volatile uint32_t * p,int val,clockid_t clockid,const struct timespec * abs)294b11781bSpirofti _twait(volatile uint32_t *p, int val, clockid_t clockid, const struct timespec *abs)
304b11781bSpirofti {
31*2e686a7fScheloha 	struct timespec now, rel;
3296f2311eSkettenis 	int saved_errno = errno;
33173afbacSkettenis 	int error;
344b11781bSpirofti 
35173afbacSkettenis 	if (abs == NULL) {
36173afbacSkettenis 		error = futex(p, FUTEX_WAIT, val, NULL, NULL);
3796f2311eSkettenis 		if (error == -1) {
38173afbacSkettenis 			error = errno;
3996f2311eSkettenis 			errno = saved_errno;
4096f2311eSkettenis 		}
41173afbacSkettenis 		return error;
42173afbacSkettenis 	}
434b11781bSpirofti 
44*2e686a7fScheloha 	if (!timespecisvalid(abs) || clock_gettime(clockid, &now))
45173afbacSkettenis 		return EINVAL;
464b11781bSpirofti 
47*2e686a7fScheloha 	if (timespeccmp(abs, &now, <=))
48173afbacSkettenis 		return ETIMEDOUT;
49*2e686a7fScheloha 	timespecsub(abs, &now, &rel);
504b11781bSpirofti 
51173afbacSkettenis 	error = futex(p, FUTEX_WAIT, val, &rel, NULL);
5296f2311eSkettenis 	if (error == -1) {
53173afbacSkettenis 		error = errno;
5496f2311eSkettenis 		errno = saved_errno;
5596f2311eSkettenis 	}
56173afbacSkettenis 	return error;
574b11781bSpirofti }
584b11781bSpirofti 
594b11781bSpirofti static inline int
_requeue(volatile uint32_t * p,int n,int m,volatile uint32_t * q)604b11781bSpirofti _requeue(volatile uint32_t *p, int n, int m, volatile uint32_t *q)
614b11781bSpirofti {
62bc52b28aSsthen 	return futex(p, FUTEX_REQUEUE, n, (void *)(long)m, q);
634b11781bSpirofti }
64