X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/bac41a7b9a0a9254fa30f8bb6e6038ab71a483e2..ce0ac947b4708d0bc1c7e6789b3e1f3bfc80d6e9:/cdsa/cdsa_utilities/threading.cpp diff --git a/cdsa/cdsa_utilities/threading.cpp b/cdsa/cdsa_utilities/threading.cpp index 8756095d..e1827f70 100644 --- a/cdsa/cdsa_utilities/threading.cpp +++ b/cdsa/cdsa_utilities/threading.cpp @@ -25,10 +25,9 @@ // Since we are planning to generate "stub" out of line code for threading methods, // we must force THREAD_NDEBUG to off while compiling our header. Trust me. // -#if !defined(THREAD_CLEAN_NDEBUG) -# define THREAD_MAKE_STUBS -#endif #include +#include +#include // @@ -57,18 +56,16 @@ ThreadStoreSlot::~ThreadStoreSlot() // #if _USE_THREADS == _USE_PTHREADS -#if !defined(THREAD_CLEAN_NDEBUG) - bool Mutex::debugHasInitialized; bool Mutex::loggingMutexi; -Mutex::Mutex(bool log) +inline void Mutex::init(Type type, bool log) { #if !defined(THREAD_NDEBUG) // this debug-setup code isn't interlocked, but it's idempotent // (don't worry, be happy) if (!debugHasInitialized) { - loggingMutexi = Debug::debugging("mutex"); + loggingMutexi = Debug::debugging("mutex") || Debug::debugging("mutex-c"); debugHasInitialized = true; } debugLog = log && loggingMutexi; @@ -76,14 +73,46 @@ Mutex::Mutex(bool log) #else debugLog = false; #endif //THREAD_NDEBUG +} + +struct Recursive : public pthread_mutexattr_t { + Recursive() + { + pthread_mutexattr_init(this); + pthread_mutexattr_settype(this, PTHREAD_MUTEX_RECURSIVE); + } +}; + + +Mutex::Mutex(bool log) +{ + init(normal, log); check(pthread_mutex_init(&me, NULL)); } +Mutex::Mutex(Type type, bool log) +{ + init(type, log); + switch (type) { + case normal: + check(pthread_mutex_init(&me, NULL)); + break; + case recursive: + static ModuleNexus recursive; + check(pthread_mutex_init(&me, &recursive())); + }; + } + Mutex::~Mutex() { #if !defined(THREAD_NDEBUG) - if (debugLog && (useCount > 100 || contentionCount > 0)) - debug("mutex", "%p destroyed after %ld/%ld locks/contentions", this, useCount, contentionCount); + if (debugLog) { + if (contentionCount > 0) + secdebug("mutex-c", "%p destroyed after %ld/%ld locks/contentions", + this, useCount, contentionCount); + else if (useCount > 100) + secdebug("mutex", "%p destroyed after %ld locks", this, useCount); + } #endif //THREAD_NDEBUG check(pthread_mutex_destroy(&me)); } @@ -98,16 +127,16 @@ void Mutex::lock() break; case EBUSY: if (debugLog) - debug("mutex", "%p contended (%ld of %ld)", this, ++contentionCount, useCount); + secdebug("mutex-c", "%p contended (%ld of %ld)", this, ++contentionCount, useCount); check(pthread_mutex_lock(&me)); break; default: UnixError::throwMe(err); } if (useCount % 100 == 0) - debug("mutex", "%p locked %ld", this, useCount); + secdebug("mutex", "%p locked %ld", this, useCount); else - debug("mutex", "%p locked", this); + secdebug("mutex", "%p locked", this); return; } #endif //THREAD_NDEBUG @@ -122,7 +151,7 @@ bool Mutex::tryLock() UnixError::throwMe(err); #if !defined(THREAD_NDEBUG) if (debugLog) - debug("mutex", "%p trylock contended (%ld of %ld)", + secdebug("mutex-c", "%p trylock contended (%ld of %ld)", this, ++contentionCount, useCount); #endif //THREAD_NDEBUG return false; @@ -130,9 +159,9 @@ bool Mutex::tryLock() #if !defined(THREAD_NDEBUG) if (debugLog) if (useCount % 100 == 0) - debug("mutex", "%p locked %ld", this, useCount); + secdebug("mutex", "%p locked %ld", this, useCount); else - debug("mutex", "%p locked", this); + secdebug("mutex", "%p locked", this); #endif //THREAD_NDEBUG return true; } @@ -141,12 +170,11 @@ void Mutex::unlock() { #if !defined(MUTEX_NDEBUG) if (debugLog) - debug("mutex", "%p unlocked", this); + secdebug("mutex", "%p unlocked", this); #endif //MUTEX_NDEBUG check(pthread_mutex_unlock(&me)); } -#endif //!THREAD_CLEAN_NDEBUG #endif //PTHREADS @@ -161,7 +189,7 @@ void CountingMutex::enter() { lock(); mCount++; - debug("mutex", "%p up to %d", this, mCount); + secdebug("mutex", "%p up to %d", this, mCount); unlock(); } @@ -170,7 +198,7 @@ bool CountingMutex::tryEnter() if (!tryLock()) return false; mCount++; - debug("mutex", "%p up to %d (was try)", this, mCount); + secdebug("mutex", "%p up to %d (was try)", this, mCount); unlock(); return true; } @@ -180,14 +208,14 @@ void CountingMutex::exit() lock(); assert(mCount > 0); mCount--; - debug("mutex", "%p down to %d", this, mCount); + secdebug("mutex", "%p down to %d", this, mCount); unlock(); } void CountingMutex::finishEnter() { mCount++; - debug("mutex", "%p finish up to %d", this, mCount); + secdebug("mutex", "%p finish up to %d", this, mCount); unlock(); } @@ -195,7 +223,7 @@ void CountingMutex::finishExit() { assert(mCount > 0); mCount--; - debug("mutex", "%p finish down to %d", this, mCount); + secdebug("mutex", "%p finish down to %d", this, mCount); unlock(); } @@ -214,7 +242,7 @@ void Thread::run() { if (int err = pthread_create(&self.mIdent, NULL, runner, this)) UnixError::throwMe(err); - debug("thread", "%p created", self.mIdent); + secdebug("thread", "%p created", self.mIdent); } void *Thread::runner(void *arg) @@ -222,9 +250,9 @@ void *Thread::runner(void *arg) Thread *me = static_cast(arg); if (int err = pthread_detach(me->self.mIdent)) UnixError::throwMe(err); - debug("thread", "%p starting", me->self.mIdent); + secdebug("thread", "%p starting", me->self.mIdent); me->action(); - debug("thread", "%p terminating", me->self.mIdent); + secdebug("thread", "%p terminating", me->self.mIdent); delete me; return NULL; } @@ -234,21 +262,21 @@ void Thread::yield() sched_yield(); } -#if !defined(NDEBUG) - -#include +// +// Make a more-or-less unique string representation of a thread id. +// This is meant FOR DEBUGGING ONLY. Don't use this in production code. +// void Thread::Identity::getIdString(char id[idLength]) { pthread_t current = pthread_self(); // We're not supposed to know what a pthread_t is. Just print the first few bytes... // (On MacOS X, it's a pointer to a pthread_t internal structure, so this works fine.) - void *p; - memcpy(&p, ¤t, sizeof(p)); - snprintf(id, idLength, "%lx", long(p)); + long ids; + memcpy(&ids, ¤t, sizeof(ids)); + snprintf(id, idLength, "%lx", ids); } -#endif // NDEBUG #endif // PTHREADS