thr_umtx.c revision 165370
1/* 2 * Copyright (c) 2005 David Xu <davidxu@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice unmodified, this list of conditions, and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * $FreeBSD: head/lib/libthr/thread/thr_umtx.c 165370 2006-12-20 04:43:34Z davidxu $ 27 * 28 */ 29 30#include "thr_private.h" 31#include "thr_umtx.h" 32 33void 34_thr_umutex_init(struct umutex *mtx) 35{ 36 static struct umutex default_mtx = DEFAULT_UMUTEX; 37 38 *mtx = default_mtx; 39 mtx->m_spincount = _thr_adaptive_spin; 40} 41 42int 43__thr_umutex_lock(struct umutex *mtx) 44{ 45 if (_umtx_op(mtx, UMTX_OP_MUTEX_LOCK, 0, 0, 0) != -1) 46 return 0; 47 return (errno); 48} 49 50int 51__thr_umutex_timedlock(struct umutex *mtx, 52 const struct timespec *timeout) 53{ 54 if (timeout && (timeout->tv_sec < 0 || (timeout->tv_sec == 0 && 55 timeout->tv_nsec <= 0))) 56 return (ETIMEDOUT); 57 if (_umtx_op(mtx, UMTX_OP_MUTEX_LOCK, 0, 0, 58 __DECONST(void *, timeout)) != -1) 59 return (0); 60 return (errno); 61} 62 63int 64__thr_umutex_unlock(struct umutex *mtx) 65{ 66 if (_umtx_op(mtx, UMTX_OP_MUTEX_UNLOCK, 0, 0, 0) != -1) 67 return (0); 68 return (errno); 69} 70 71int 72__thr_umutex_trylock(struct umutex *mtx) 73{ 74 if (_umtx_op(mtx, UMTX_OP_MUTEX_TRYLOCK, 0, 0, 0) != -1) 75 return (0); 76 return (errno); 77} 78 79int 80__thr_umutex_set_ceiling(struct umutex *mtx, uint32_t ceiling, 81 uint32_t *oldceiling) 82{ 83 if (_umtx_op(mtx, UMTX_OP_SET_CEILING, ceiling, oldceiling, 0) != -1) 84 return (0); 85 return (errno); 86} 87 88int 89_thr_umtx_wait(volatile umtx_t *mtx, long id, const struct timespec *timeout) 90{ 91 if (timeout && (timeout->tv_sec < 0 || (timeout->tv_sec == 0 && 92 timeout->tv_nsec <= 0))) 93 return (ETIMEDOUT); 94 if (_umtx_op(__DEVOLATILE(void *, mtx), UMTX_OP_WAIT, id, 0, 95 __DECONST(void*, timeout)) != -1) 96 return (0); 97 return (errno); 98} 99 100int 101_thr_umtx_wake(volatile umtx_t *mtx, int nr_wakeup) 102{ 103 if (_umtx_op(__DEVOLATILE(void *, mtx), UMTX_OP_WAKE, 104 nr_wakeup, 0, 0) != -1) 105 return (0); 106 return (errno); 107} 108 109void 110_thr_ucond_init(struct ucond *cv) 111{ 112 bzero(cv, sizeof(struct ucond)); 113} 114 115int 116_thr_ucond_wait(struct ucond *cv, struct umutex *m, 117 const struct timespec *timeout, int check_unparking) 118{ 119 if (timeout && (timeout->tv_sec < 0 || (timeout->tv_sec == 0 && 120 timeout->tv_nsec <= 0))) { 121 __thr_umutex_unlock(m); 122 return (ETIMEDOUT); 123 } 124 if (_umtx_op(cv, UMTX_OP_CV_WAIT, 125 check_unparking ? UMTX_CHECK_UNPARKING : 0, 126 m, __DECONST(void*, timeout)) != -1) { 127 return (0); 128 } 129 return (errno); 130} 131 132int 133_thr_ucond_signal(struct ucond *cv) 134{ 135 if (!cv->c_has_waiters) 136 return (0); 137 if (_umtx_op(cv, UMTX_OP_CV_SIGNAL, 0, NULL, NULL) != -1) 138 return (0); 139 return (errno); 140} 141 142int 143_thr_ucond_broadcast(struct ucond *cv) 144{ 145 if (!cv->c_has_waiters) 146 return (0); 147 if (_umtx_op(cv, UMTX_OP_CV_BROADCAST, 0, NULL, NULL) != -1) 148 return (0); 149 return (errno); 150} 151