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