Index: thread/thr_mutex.c =================================================================== RCS file: /home/ncvs/src/lib/libthr/thread/thr_mutex.c,v retrieving revision 1.73 diff -u -u -r1.73 thr_mutex.c --- thread/thr_mutex.c 26 Apr 2008 13:19:07 -0000 1.73 +++ thread/thr_mutex.c 8 May 2008 03:00:15 -0000 @@ -418,7 +418,8 @@ count = m->m_spinloops; while (count--) { - if (m->m_lock.m_owner == UMUTEX_UNOWNED) { + if (m->m_lock.m_owner == UMUTEX_UNOWNED || + m->m_lock.m_owner == (int32_t)UMUTEX_CONTESTED) { ret = _thr_umutex_trylock2(&m->m_lock, id); if (ret == 0) goto done; @@ -437,7 +438,7 @@ sleep_in_kernel: if (abstime == NULL) { - ret = __thr_umutex_lock(&m->m_lock); + ret = __thr_umutex_lock(&m->m_lock, id); } else if (__predict_false( abstime->tv_sec < 0 || abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) { Index: thread/thr_umtx.c =================================================================== RCS file: /home/ncvs/src/lib/libthr/thread/thr_umtx.c,v retrieving revision 1.16 diff -u -u -r1.16 thr_umtx.c --- thread/thr_umtx.c 29 Apr 2008 03:58:18 -0000 1.16 +++ thread/thr_umtx.c 8 May 2008 03:00:15 -0000 @@ -48,9 +48,23 @@ } int -__thr_umutex_lock(struct umutex *mtx) +__thr_umutex_lock(struct umutex *mtx, uint32_t id) { - return _umtx_op_err(mtx, UMTX_OP_MUTEX_LOCK, 0, 0, 0); + if ((mtx->m_flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT)) == 0) { + for (;;) { + /* wait in kernel */ + _umtx_op_err(mtx, UMTX_OP_MUTEX_WAIT, 0, 0, 0); + + /* now try to lock it */ + if (atomic_cmpset_acq_32(&mtx->m_owner, UMUTEX_UNOWNED, id) || + atomic_cmpset_acq_32(&mtx->m_owner, UMUTEX_CONTESTED, + id | UMUTEX_CONTESTED)) { + return (0); + } + } + } + + return _umtx_op_err(mtx, UMTX_OP_MUTEX_LOCK, 0, 0, 0); } int @@ -65,8 +79,12 @@ } int -__thr_umutex_unlock(struct umutex *mtx) +__thr_umutex_unlock(struct umutex *mtx, uint32_t id) { + if ((mtx->m_flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT)) == 0) { + atomic_cmpset_rel_32(&mtx->m_owner, id | UMUTEX_CONTESTED, UMUTEX_CONTESTED); + return _umtx_op_err(mtx, UMTX_OP_MUTEX_WAKE, 0, 0, 0); + } return _umtx_op_err(mtx, UMTX_OP_MUTEX_UNLOCK, 0, 0, 0); } @@ -123,7 +141,8 @@ { if (timeout && (timeout->tv_sec < 0 || (timeout->tv_sec == 0 && timeout->tv_nsec <= 0))) { - __thr_umutex_unlock(m); + struct pthread *curthread = _get_curthread(); + _thr_umutex_unlock(m, TID(curthread)); return (ETIMEDOUT); } return _umtx_op_err(cv, UMTX_OP_CV_WAIT, Index: thread/thr_umtx.h =================================================================== RCS file: /home/ncvs/src/lib/libthr/thread/thr_umtx.h,v retrieving revision 1.13 diff -u -u -r1.13 thr_umtx.h --- thread/thr_umtx.h 29 Apr 2008 03:58:18 -0000 1.13 +++ thread/thr_umtx.h 8 May 2008 03:00:15 -0000 @@ -34,10 +34,10 @@ #define DEFAULT_UMUTEX {0,0, {0,0},{0,0,0,0}} -int __thr_umutex_lock(struct umutex *mtx) __hidden; +int __thr_umutex_lock(struct umutex *mtx, uint32_t id) __hidden; int __thr_umutex_timedlock(struct umutex *mtx, const struct timespec *timeout) __hidden; -int __thr_umutex_unlock(struct umutex *mtx) __hidden; +int __thr_umutex_unlock(struct umutex *mtx, uint32_t id) __hidden; int __thr_umutex_trylock(struct umutex *mtx) __hidden; int __thr_umutex_set_ceiling(struct umutex *mtx, uint32_t ceiling, uint32_t *oldceiling) __hidden; @@ -63,6 +63,9 @@ { if (atomic_cmpset_acq_32(&mtx->m_owner, UMUTEX_UNOWNED, id)) return (0); + if ((mtx->m_flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT)) == 0 && + atomic_cmpset_acq_32(&mtx->m_owner, UMUTEX_CONTESTED, id | UMUTEX_CONTESTED)) + return (0); if ((mtx->m_flags & UMUTEX_PRIO_PROTECT) == 0) return (EBUSY); return (__thr_umutex_trylock(mtx)); @@ -73,22 +76,25 @@ { if (atomic_cmpset_acq_32(&mtx->m_owner, UMUTEX_UNOWNED, id)) return (0); + if ((mtx->m_flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT)) == 0 && + atomic_cmpset_acq_32(&mtx->m_owner, UMUTEX_CONTESTED, id | UMUTEX_CONTESTED)) + return (0); return (EBUSY); } static inline int _thr_umutex_lock(struct umutex *mtx, uint32_t id) { - if (atomic_cmpset_acq_32(&mtx->m_owner, UMUTEX_UNOWNED, id)) + if (_thr_umutex_trylock2(mtx, id) == 0) return (0); - return (__thr_umutex_lock(mtx)); + 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)) + if (_thr_umutex_trylock2(mtx, id) == 0) return (0); return (__thr_umutex_timedlock(mtx, timeout)); } @@ -98,7 +104,7 @@ { if (atomic_cmpset_rel_32(&mtx->m_owner, id, UMUTEX_UNOWNED)) return (0); - return (__thr_umutex_unlock(mtx)); + return (__thr_umutex_unlock(mtx, id)); } static inline int