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