- if (res != 0) {
- PLOCKSTAT_MUTEX_ERROR(omutex, res);
- }
- return res;
-}
-
-PTHREAD_ALWAYS_INLINE
-static inline int
-_pthread_mutex_check_init(pthread_mutex_t *omutex)
-{
- int res = 0;
- _pthread_mutex *mutex = (_pthread_mutex *)omutex;
-
- if (!_pthread_mutex_check_signature(mutex)) {
- return _pthread_mutex_check_init_slow(omutex);
- }
- return res;
-}
-
-PTHREAD_NOINLINE
-int
-_pthread_mutex_lock_wait(pthread_mutex_t *omutex, uint64_t newval64, uint64_t oldtid)
-{
- _pthread_mutex *mutex = (_pthread_mutex *)omutex;
- uint32_t lgenval = (uint32_t)newval64;
- uint32_t ugenval = (uint32_t)(newval64 >> 32);
-
- volatile uint64_t *tidaddr;
- MUTEX_GETTID_ADDR(mutex, &tidaddr);
- uint64_t selfid = _pthread_selfid_direct();
-
- PLOCKSTAT_MUTEX_BLOCK(omutex);
- do {
- uint32_t updateval;
- do {
- updateval = __psynch_mutexwait(omutex, lgenval, ugenval, oldtid, mutex->mtxopts.value);
- oldtid = *tidaddr;
- } while (updateval == (uint32_t)-1);
-
- // returns 0 on succesful update; in firstfit it may fail with 1
- } while (_pthread_mutex_lock_updatebits(mutex, selfid) == 1);
- PLOCKSTAT_MUTEX_BLOCKED(omutex, BLOCK_SUCCESS_PLOCKSTAT);
-
- return 0;
-}
-
-int
-_pthread_mutex_lock_slow(pthread_mutex_t *omutex, bool trylock)
-{
- int res;
- _pthread_mutex *mutex = (_pthread_mutex *)omutex;
-
- res = _pthread_mutex_check_init(omutex);
- if (res != 0) {
- return res;
- }
-
- uint64_t oldtid;
- volatile uint64_t *tidaddr;
- MUTEX_GETTID_ADDR(mutex, &tidaddr);
- uint64_t selfid = _pthread_selfid_direct();
-
- if (mutex->mtxopts.options.type != PTHREAD_MUTEX_NORMAL) {
- if (*tidaddr == selfid) {
- if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE) {
- if (mutex->mtxopts.options.lock_count < USHRT_MAX) {
- mutex->mtxopts.options.lock_count++;
- PLOCKSTAT_MUTEX_ACQUIRE(omutex, 1, 0);
- res = 0;
- } else {
- res = EAGAIN;
- PLOCKSTAT_MUTEX_ERROR(omutex, res);
- }
- } else if (trylock) { /* PTHREAD_MUTEX_ERRORCHECK */
- // <rdar://problem/16261552> as per OpenGroup, trylock cannot
- // return EDEADLK on a deadlock, it should return EBUSY.
- res = EBUSY;
- PLOCKSTAT_MUTEX_ERROR(omutex, res);
- } else { /* PTHREAD_MUTEX_ERRORCHECK */
- res = EDEADLK;
- PLOCKSTAT_MUTEX_ERROR(omutex, res);
- }
- return res;
- }
- }
-
- uint64_t oldval64, newval64;
- volatile uint64_t *seqaddr;
- MUTEX_GETSEQ_ADDR(mutex, &seqaddr);
-
- uint32_t lgenval, ugenval;
- bool gotlock = false;