Add umutex APIs.

This commit is contained in:
davidxu 2006-08-28 04:47:27 +00:00
parent 3cac7b5ddb
commit 77e7cda2cf
2 changed files with 92 additions and 0 deletions

View File

@ -61,6 +61,52 @@ __thr_umtx_unlock(volatile umtx_t *mtx, long id)
return (errno);
}
int
__thr_umutex_lock(struct umutex *mtx, uint32_t id)
{
if (_umtx_op(mtx, UMTX_OP_MUTEX_LOCK, 0, 0, 0) == 0)
return 0;
return (errno);
}
int
__thr_umutex_timedlock(struct umutex *mtx, uint32_t id,
const struct timespec *timeout)
{
if (timeout && (timeout->tv_sec < 0 || (timeout->tv_sec == 0 &&
timeout->tv_nsec <= 0)))
return (ETIMEDOUT);
if (_umtx_op(mtx, UMTX_OP_MUTEX_LOCK, 0, 0,
__DECONST(void *, timeout)) == 0)
return (0);
return (errno);
}
int
__thr_umutex_unlock(struct umutex *mtx, uint32_t id)
{
if (_umtx_op(mtx, UMTX_OP_MUTEX_UNLOCK, 0, 0, 0) == 0)
return (0);
return (errno);
}
int
__thr_umutex_kern_trylock(struct umutex *mtx)
{
if (_umtx_op(mtx, UMTX_OP_MUTEX_TRYLOCK, 0, 0, 0) == 0)
return (0);
return (errno);
}
int
__thr_umutex_set_ceiling(struct umutex *mtx, uint32_t ceiling,
uint32_t *oldceiling)
{
if (_umtx_op(mtx, UMTX_OP_SET_CEILING, ceiling, oldceiling, 0) == 0)
return (0);
return (errno);
}
int
_thr_umtx_wait(volatile umtx_t *mtx, long id, const struct timespec *timeout)
{

View File

@ -33,11 +33,21 @@
typedef long umtx_t;
/* simple lock routines.*/
int __thr_umtx_lock(volatile umtx_t *mtx, long id) __hidden;
int __thr_umtx_timedlock(volatile umtx_t *mtx, long id,
const struct timespec *timeout) __hidden;
int __thr_umtx_unlock(volatile umtx_t *mtx, long id) __hidden;
/* POSIX semantic lock routines */
int __thr_umutex_lock(struct umutex *mtx, uint32_t id) __hidden;
int __thr_umutex_timedlock(struct umutex *mtx, uint32_t id,
const struct timespec *timeout) __hidden;
int __thr_umutex_unlock(struct umutex *mtx, uint32_t id) __hidden;
int __thr_umutex_kern_trylock(struct umutex *mtx) __hidden;
int __thr_umutex_set_ceiling(struct umutex *mtx, uint32_t ceiling,
uint32_t *oldceiling) __hidden;
static inline void
_thr_umtx_init(volatile umtx_t *mtx)
{
@ -84,4 +94,40 @@ _thr_umtx_unlock(volatile umtx_t *mtx, long id)
int _thr_umtx_wait(volatile umtx_t *mtx, umtx_t exp,
const struct timespec *timeout) __hidden;
int _thr_umtx_wake(volatile umtx_t *mtx, int count) __hidden;
static inline int
_thr_umutex_trylock(struct umutex *mtx, uint32_t id)
{
if (atomic_cmpset_acq_32(&mtx->m_owner, UMUTEX_UNOWNED, id))
return (0);
if ((mtx->m_flags & UMUTEX_PRIO_PROTECT) == 0)
return (EBUSY);
return (__thr_umutex_kern_trylock(mtx));
}
static inline int
_thr_umutex_lock(struct umutex *mtx, uint32_t id)
{
if (atomic_cmpset_acq_32(&mtx->m_owner, UMUTEX_UNOWNED, id))
return (0);
return (__thr_umutex_lock(mtx, id));
}
static inline int
_thr_umutex_timedlock(struct umutex *mtx, uint32_t id,
const struct timespec *timeout)
{
if (atomic_cmpset_acq_32(&mtx->m_owner, UMUTEX_UNOWNED, id))
return (0);
return (__thr_umutex_timedlock(mtx, id, timeout));
}
static inline int
_thr_umutex_unlock(struct umutex *mtx, uint32_t id)
{
if (atomic_cmpset_rel_32(&mtx->m_owner, id, UMUTEX_UNOWNED))
return (0);
return (__thr_umutex_unlock(mtx, id));
}
#endif