xref: /freebsd/lib/libthr/thread/thr_umtx.c (revision cf13ecda6a65b6d6606659f152e2ad244c837765)
1a091d823SDavid Xu /*
2a091d823SDavid Xu  * Copyright (c) 2005 David Xu <davidxu@freebsd.org>
3a091d823SDavid Xu  * All rights reserved.
4a091d823SDavid Xu  *
5a091d823SDavid Xu  * Redistribution and use in source and binary forms, with or without
6a091d823SDavid Xu  * modification, are permitted provided that the following conditions
7a091d823SDavid Xu  * are met:
8a091d823SDavid Xu  * 1. Redistributions of source code must retain the above copyright
9a091d823SDavid Xu  *    notice unmodified, this list of conditions, and the following
10a091d823SDavid Xu  *    disclaimer.
11a091d823SDavid Xu  * 2. Redistributions in binary form must reproduce the above copyright
12a091d823SDavid Xu  *    notice, this list of conditions and the following disclaimer in the
13a091d823SDavid Xu  *    documentation and/or other materials provided with the distribution.
14a091d823SDavid Xu  *
15a091d823SDavid Xu  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16a091d823SDavid Xu  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17a091d823SDavid Xu  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18a091d823SDavid Xu  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19a091d823SDavid Xu  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20a091d823SDavid Xu  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21a091d823SDavid Xu  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22a091d823SDavid Xu  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23a091d823SDavid Xu  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24a091d823SDavid Xu  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25a091d823SDavid Xu  *
26a091d823SDavid Xu  * $FreeBSD$
27a091d823SDavid Xu  *
28a091d823SDavid Xu  */
29a091d823SDavid Xu 
30a091d823SDavid Xu #include "thr_private.h"
31a091d823SDavid Xu #include "thr_umtx.h"
32a091d823SDavid Xu 
33a091d823SDavid Xu int
34a091d823SDavid Xu __thr_umtx_lock(volatile umtx_t *mtx, long id)
35a091d823SDavid Xu {
3637a6356bSDavid Xu 	 while (_umtx_op(__DEVOLATILE(struct umtx *, mtx),
3737a6356bSDavid Xu 		UMTX_OP_LOCK, id, 0, 0))
38a091d823SDavid Xu 		;
39a091d823SDavid Xu 	return (0);
40a091d823SDavid Xu }
41a091d823SDavid Xu 
42a091d823SDavid Xu int
43a091d823SDavid Xu __thr_umtx_timedlock(volatile umtx_t *mtx, long id,
44a091d823SDavid Xu 	const struct timespec *timeout)
45a091d823SDavid Xu {
46a091d823SDavid Xu 	if (timeout && (timeout->tv_sec < 0 || (timeout->tv_sec == 0 &&
47a091d823SDavid Xu 		timeout->tv_nsec <= 0)))
48a091d823SDavid Xu 		return (ETIMEDOUT);
4937a6356bSDavid Xu 	if (_umtx_op(__DEVOLATILE(struct umtx *, mtx), UMTX_OP_LOCK, id, 0,
5037a6356bSDavid Xu 		__DECONST(void *, timeout)) == 0)
51a091d823SDavid Xu 		return (0);
52a091d823SDavid Xu 	return (errno);
53a091d823SDavid Xu }
54a091d823SDavid Xu 
55a091d823SDavid Xu int
56a091d823SDavid Xu __thr_umtx_unlock(volatile umtx_t *mtx, long id)
57a091d823SDavid Xu {
5837a6356bSDavid Xu 	if (_umtx_op(__DEVOLATILE(struct umtx *, mtx), UMTX_OP_UNLOCK,
5937a6356bSDavid Xu 		id, 0, 0) == 0)
60a091d823SDavid Xu 		return (0);
61a091d823SDavid Xu 	return (errno);
62a091d823SDavid Xu }
63a091d823SDavid Xu 
64a091d823SDavid Xu int
65cf13ecdaSDavid Xu __thr_umutex_lock(struct umutex *mtx, uint32_t id)
66cf13ecdaSDavid Xu {
67cf13ecdaSDavid Xu 	if (_umtx_op(mtx, UMTX_OP_MUTEX_LOCK, 0, 0, 0) == 0)
68cf13ecdaSDavid Xu 		return 0;
69cf13ecdaSDavid Xu 	return (errno);
70cf13ecdaSDavid Xu }
71cf13ecdaSDavid Xu 
72cf13ecdaSDavid Xu int
73cf13ecdaSDavid Xu __thr_umutex_timedlock(struct umutex *mtx, uint32_t id,
74cf13ecdaSDavid Xu 	const struct timespec *timeout)
75cf13ecdaSDavid Xu {
76cf13ecdaSDavid Xu 	if (timeout && (timeout->tv_sec < 0 || (timeout->tv_sec == 0 &&
77cf13ecdaSDavid Xu 		timeout->tv_nsec <= 0)))
78cf13ecdaSDavid Xu 		return (ETIMEDOUT);
79cf13ecdaSDavid Xu 	if (_umtx_op(mtx, UMTX_OP_MUTEX_LOCK, 0, 0,
80cf13ecdaSDavid Xu 		__DECONST(void *, timeout)) == 0)
81cf13ecdaSDavid Xu 		return (0);
82cf13ecdaSDavid Xu 	return (errno);
83cf13ecdaSDavid Xu }
84cf13ecdaSDavid Xu 
85cf13ecdaSDavid Xu int
86cf13ecdaSDavid Xu __thr_umutex_unlock(struct umutex *mtx, uint32_t id)
87cf13ecdaSDavid Xu {
88cf13ecdaSDavid Xu 	if (_umtx_op(mtx, UMTX_OP_MUTEX_UNLOCK, 0, 0, 0) == 0)
89cf13ecdaSDavid Xu 		return (0);
90cf13ecdaSDavid Xu 	return (errno);
91cf13ecdaSDavid Xu }
92cf13ecdaSDavid Xu 
93cf13ecdaSDavid Xu int
94cf13ecdaSDavid Xu __thr_umutex_kern_trylock(struct umutex *mtx)
95cf13ecdaSDavid Xu {
96cf13ecdaSDavid Xu 	if (_umtx_op(mtx, UMTX_OP_MUTEX_TRYLOCK, 0, 0, 0) == 0)
97cf13ecdaSDavid Xu 		return (0);
98cf13ecdaSDavid Xu 	return (errno);
99cf13ecdaSDavid Xu }
100cf13ecdaSDavid Xu 
101cf13ecdaSDavid Xu int
102cf13ecdaSDavid Xu __thr_umutex_set_ceiling(struct umutex *mtx, uint32_t ceiling,
103cf13ecdaSDavid Xu 	uint32_t *oldceiling)
104cf13ecdaSDavid Xu {
105cf13ecdaSDavid Xu 	if (_umtx_op(mtx, UMTX_OP_SET_CEILING, ceiling, oldceiling, 0) == 0)
106cf13ecdaSDavid Xu 		return (0);
107cf13ecdaSDavid Xu 	return (errno);
108cf13ecdaSDavid Xu }
109cf13ecdaSDavid Xu 
110cf13ecdaSDavid Xu int
111a091d823SDavid Xu _thr_umtx_wait(volatile umtx_t *mtx, long id, const struct timespec *timeout)
112a091d823SDavid Xu {
113a091d823SDavid Xu 	if (timeout && (timeout->tv_sec < 0 || (timeout->tv_sec == 0 &&
114a091d823SDavid Xu 		timeout->tv_nsec <= 0)))
115a091d823SDavid Xu 		return (ETIMEDOUT);
11637a6356bSDavid Xu 	if (_umtx_op(__DEVOLATILE(struct umtx *, mtx), UMTX_OP_WAIT, id, 0,
11737a6356bSDavid Xu 		__DECONST(void*, timeout)) == 0)
118a091d823SDavid Xu 		return (0);
119a091d823SDavid Xu 	return (errno);
120a091d823SDavid Xu }
121a091d823SDavid Xu 
122a091d823SDavid Xu int
123a091d823SDavid Xu _thr_umtx_wake(volatile umtx_t *mtx, int nr_wakeup)
124a091d823SDavid Xu {
12537a6356bSDavid Xu 	if (_umtx_op(__DEVOLATILE(struct umtx *, mtx), UMTX_OP_WAKE,
12637a6356bSDavid Xu 		nr_wakeup, 0, 0) == 0)
127a091d823SDavid Xu 		return (0);
128a091d823SDavid Xu 	return (errno);
129a091d823SDavid Xu }
130