X-Git-Url: https://git.saurik.com/apple/libpthread.git/blobdiff_plain/964d3577b041867f776d8eb940bf4a1108ffb97c..a03d92013c2a24ebc4e02e5d1f575787f8467f6b:/src/pthread_mutex.c?ds=inline diff --git a/src/pthread_mutex.c b/src/pthread_mutex.c index d214739..5eaf689 100644 --- a/src/pthread_mutex.c +++ b/src/pthread_mutex.c @@ -55,8 +55,6 @@ #include "kern/kern_trace.h" #include -#include "os/atomic.h" - #ifdef PLOCKSTAT #include "plockstat.h" #else /* !PLOCKSTAT */ @@ -69,6 +67,8 @@ #define PLOCKSTAT_MUTEX_RELEASE(x, y) #endif /* PLOCKSTAT */ +#define PTHREAD_MUTEX_INIT_UNUSED 1 + extern int __unix_conforming; #ifndef BUILDING_VARIANT @@ -109,8 +109,9 @@ static inline void MUTEX_GETSEQ_ADDR(_pthread_mutex *mutex, volatile uint64_t **seqaddr) { - // addr of m_seq[1] for misaligned, m_seq[0] for aligned mutex struct - *seqaddr = (volatile uint64_t *)(((uintptr_t)&mutex->m_seq[1]) & ~0x7ul); + // 64-bit aligned address inside m_seq array (&m_seq[0] for aligned mutex) + // We don't require more than byte alignment on OS X. rdar://22278325 + *seqaddr = (volatile uint64_t*)(((uintptr_t)mutex->m_seq + 0x7ul) & ~0x7ul); } PTHREAD_ALWAYS_INLINE @@ -118,8 +119,9 @@ static inline void MUTEX_GETTID_ADDR(_pthread_mutex *mutex, volatile uint64_t **tidaddr) { - // addr of m_tid[1] for misaligned, m_tid[0] for aligned mutex struct - *tidaddr = (volatile uint64_t *)(((uintptr_t)&mutex->m_tid[1]) & ~0x7ul); + // 64-bit aligned address inside m_tid array (&m_tid[0] for aligned mutex) + // We don't require more than byte alignment on OS X. rdar://22278325 + *tidaddr = (volatile uint64_t*)(((uintptr_t)mutex->m_tid + 0x7ul) & ~0x7ul); } #ifndef BUILDING_VARIANT /* [ */ @@ -155,7 +157,7 @@ pthread_mutex_init(pthread_mutex_t *omutex, const pthread_mutexattr_t *attr) return EBUSY; #endif _pthread_mutex *mutex = (_pthread_mutex *)omutex; - LOCK_INIT(mutex->lock); + _PTHREAD_LOCK_INIT(mutex->lock); return (_pthread_mutex_init(mutex, attr, 0x7)); } @@ -165,10 +167,10 @@ pthread_mutex_getprioceiling(const pthread_mutex_t *omutex, int *prioceiling) int res = EINVAL; _pthread_mutex *mutex = (_pthread_mutex *)omutex; if (_pthread_mutex_check_signature(mutex)) { - LOCK(mutex->lock); + _PTHREAD_LOCK(mutex->lock); *prioceiling = mutex->prioceiling; res = 0; - UNLOCK(mutex->lock); + _PTHREAD_UNLOCK(mutex->lock); } return res; } @@ -179,13 +181,13 @@ pthread_mutex_setprioceiling(pthread_mutex_t *omutex, int prioceiling, int *old_ int res = EINVAL; _pthread_mutex *mutex = (_pthread_mutex *)omutex; if (_pthread_mutex_check_signature(mutex)) { - LOCK(mutex->lock); + _PTHREAD_LOCK(mutex->lock); if (prioceiling >= -999 || prioceiling <= 999) { *old_prioceiling = mutex->prioceiling; mutex->prioceiling = prioceiling; res = 0; } - UNLOCK(mutex->lock); + _PTHREAD_UNLOCK(mutex->lock); } return res; } @@ -623,7 +625,7 @@ _pthread_mutex_check_init_slow(pthread_mutex_t *omutex) _pthread_mutex *mutex = (_pthread_mutex *)omutex; if (_pthread_mutex_check_signature_init(mutex)) { - LOCK(mutex->lock); + _PTHREAD_LOCK(mutex->lock); if (_pthread_mutex_check_signature_init(mutex)) { // initialize a statically initialized mutex to provide // compatibility for misbehaving applications. @@ -632,7 +634,7 @@ _pthread_mutex_check_init_slow(pthread_mutex_t *omutex) } else if (_pthread_mutex_check_signature(mutex)) { res = 0; } - UNLOCK(mutex->lock); + _PTHREAD_UNLOCK(mutex->lock); } else if (_pthread_mutex_check_signature(mutex)) { res = 0; } @@ -994,8 +996,11 @@ pthread_mutex_unlock(pthread_mutex_t *omutex) static inline int -_pthread_mutex_init(_pthread_mutex *mutex, const pthread_mutexattr_t *attr, uint32_t static_type) +_pthread_mutex_init(_pthread_mutex *mutex, const pthread_mutexattr_t *attr, + uint32_t static_type) { + mutex->mtxopts.value = 0; + mutex->mtxopts.options.mutex = 1; if (attr) { if (attr->sig != _PTHREAD_MUTEX_ATTR_SIG) { return EINVAL; @@ -1031,27 +1036,21 @@ _pthread_mutex_init(_pthread_mutex *mutex, const pthread_mutexattr_t *attr, uint } mutex->mtxopts.options.pshared = _PTHREAD_DEFAULT_PSHARED; } - - mutex->mtxopts.options.notify = 0; - mutex->mtxopts.options.unused = 0; - mutex->mtxopts.options.hold = 0; - mutex->mtxopts.options.mutex = 1; - mutex->mtxopts.options.lock_count = 0; - - mutex->m_tid[0] = 0; - mutex->m_tid[1] = 0; - mutex->m_seq[0] = 0; - mutex->m_seq[1] = 0; - mutex->m_seq[2] = 0; - mutex->prioceiling = 0; mutex->priority = 0; - mutex->mtxopts.options.misalign = (((uintptr_t)&mutex->m_seq[0]) & 0x7ul) != 0; - if (mutex->mtxopts.options.misalign) { - mutex->m_tid[0] = ~0u; - } else { - mutex->m_seq[2] = ~0u; + volatile uint64_t *seqaddr; + MUTEX_GETSEQ_ADDR(mutex, &seqaddr); + volatile uint64_t *tidaddr; + MUTEX_GETTID_ADDR(mutex, &tidaddr); +#if PTHREAD_MUTEX_INIT_UNUSED + if ((uint32_t*)tidaddr != mutex->m_tid) { + mutex->mtxopts.options.misalign = 1; + __builtin_memset(mutex->m_tid, 0xff, sizeof(mutex->m_tid)); } + __builtin_memset(mutex->m_mis, 0xff, sizeof(mutex->m_mis)); +#endif // PTHREAD_MUTEX_INIT_UNUSED + *tidaddr = 0; + *seqaddr = 0; long sig = _PTHREAD_MUTEX_SIG; if (mutex->mtxopts.options.type == PTHREAD_MUTEX_NORMAL && @@ -1060,9 +1059,19 @@ _pthread_mutex_init(_pthread_mutex *mutex, const pthread_mutexattr_t *attr, uint sig = _PTHREAD_MUTEX_SIG_fast; } - // unused, purely for detecting copied mutexes and smashes during debugging: - mutex->reserved2[0] = ~(uintptr_t)mutex; // use ~ to hide from leaks - mutex->reserved2[1] = (uintptr_t)sig; +#if PTHREAD_MUTEX_INIT_UNUSED + // For detecting copied mutexes and smashes during debugging + uint32_t sig32 = (uint32_t)sig; +#if defined(__LP64__) + uintptr_t guard = ~(uintptr_t)mutex; // use ~ to hide from leaks + __builtin_memcpy(mutex->_reserved, &guard, sizeof(guard)); + mutex->_reserved[2] = sig32; + mutex->_reserved[3] = sig32; + mutex->_pad = sig32; +#else + mutex->_reserved[0] = sig32; +#endif +#endif // PTHREAD_MUTEX_INIT_UNUSED // Ensure all contents are properly set before setting signature. #if defined(__LP64__) @@ -1086,7 +1095,7 @@ pthread_mutex_destroy(pthread_mutex_t *omutex) int res = EINVAL; - LOCK(mutex->lock); + _PTHREAD_LOCK(mutex->lock); if (_pthread_mutex_check_signature(mutex)) { uint32_t lgenval, ugenval; uint64_t oldval64; @@ -1109,7 +1118,7 @@ pthread_mutex_destroy(pthread_mutex_t *omutex) mutex->sig = _PTHREAD_NO_SIG; res = 0; } - UNLOCK(mutex->lock); + _PTHREAD_UNLOCK(mutex->lock); return res; }