X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/ed6778a32ecff23bc2dfb6ca452badd0c68774a0..563f4f96f568bcdc0a04a82f89cafe3bebbe43f1:/cdsa/cdsa_utilities/threading.cpp diff --git a/cdsa/cdsa_utilities/threading.cpp b/cdsa/cdsa_utilities/threading.cpp deleted file mode 100644 index e1827f70..00000000 --- a/cdsa/cdsa_utilities/threading.cpp +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS - * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT - * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the - * specific language governing rights and limitations under the License. - */ - - -// -// threading - generic thread support -// - - -// -// 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. -// -#include -#include -#include - - -// -// Thread-local storage primitive -// -#if _USE_THREADS == _USE_PTHREADS - -ThreadStoreSlot::ThreadStoreSlot(Destructor *destructor) -{ - if (int err = pthread_key_create(&mKey, destructor)) - UnixError::throwMe(err); -} - -ThreadStoreSlot::~ThreadStoreSlot() -{ - //@@@ if we wanted to dispose of pending task objects, we'd have - //@@@ to keep a set of them and delete them explicitly here - pthread_key_delete(mKey); -} - -#endif - - -// -// Mutex implementation -// -#if _USE_THREADS == _USE_PTHREADS - -bool Mutex::debugHasInitialized; -bool Mutex::loggingMutexi; - -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") || Debug::debugging("mutex-c"); - debugHasInitialized = true; - } - debugLog = log && loggingMutexi; - useCount = contentionCount = 0; -#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) { - 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)); -} - -void Mutex::lock() -{ -#if !defined(THREAD_NDEBUG) - useCount++; - if (debugLog) { - switch (int err = pthread_mutex_trylock(&me)) { - case 0: - break; - case EBUSY: - if (debugLog) - 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) - secdebug("mutex", "%p locked %ld", this, useCount); - else - secdebug("mutex", "%p locked", this); - return; - } -#endif //THREAD_NDEBUG - check(pthread_mutex_lock(&me)); -} - -bool Mutex::tryLock() -{ - useCount++; - if (int err = pthread_mutex_trylock(&me)) { - if (err != EBUSY) - UnixError::throwMe(err); -#if !defined(THREAD_NDEBUG) - if (debugLog) - secdebug("mutex-c", "%p trylock contended (%ld of %ld)", - this, ++contentionCount, useCount); -#endif //THREAD_NDEBUG - return false; - } -#if !defined(THREAD_NDEBUG) - if (debugLog) - if (useCount % 100 == 0) - secdebug("mutex", "%p locked %ld", this, useCount); - else - secdebug("mutex", "%p locked", this); -#endif //THREAD_NDEBUG - return true; -} - -void Mutex::unlock() -{ -#if !defined(MUTEX_NDEBUG) - if (debugLog) - secdebug("mutex", "%p unlocked", this); -#endif //MUTEX_NDEBUG - check(pthread_mutex_unlock(&me)); -} - -#endif //PTHREADS - - -// -// CountingMutex implementation. -// Note that this is a generic implementation based on a specific Mutex type. -// In other words, it should work no matter how Mutex is implemented. -// Also note that CountingMutex is expected to interlock properly with Mutex, -// so you canNOT just use an AtomicCounter here. -// -void CountingMutex::enter() -{ - lock(); - mCount++; - secdebug("mutex", "%p up to %d", this, mCount); - unlock(); -} - -bool CountingMutex::tryEnter() -{ - if (!tryLock()) - return false; - mCount++; - secdebug("mutex", "%p up to %d (was try)", this, mCount); - unlock(); - return true; -} - -void CountingMutex::exit() -{ - lock(); - assert(mCount > 0); - mCount--; - secdebug("mutex", "%p down to %d", this, mCount); - unlock(); -} - -void CountingMutex::finishEnter() -{ - mCount++; - secdebug("mutex", "%p finish up to %d", this, mCount); - unlock(); -} - -void CountingMutex::finishExit() -{ - assert(mCount > 0); - mCount--; - secdebug("mutex", "%p finish down to %d", this, mCount); - unlock(); -} - - - -// -// Threads implementation -// -#if _USE_THREADS == _USE_PTHREADS - -Thread::~Thread() -{ -} - -void Thread::run() -{ - if (int err = pthread_create(&self.mIdent, NULL, runner, this)) - UnixError::throwMe(err); - secdebug("thread", "%p created", self.mIdent); -} - -void *Thread::runner(void *arg) -{ - Thread *me = static_cast(arg); - if (int err = pthread_detach(me->self.mIdent)) - UnixError::throwMe(err); - secdebug("thread", "%p starting", me->self.mIdent); - me->action(); - secdebug("thread", "%p terminating", me->self.mIdent); - delete me; - return NULL; -} - -void Thread::yield() -{ - sched_yield(); -} - - -// -// 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.) - long ids; - memcpy(&ids, ¤t, sizeof(ids)); - snprintf(id, idLength, "%lx", ids); -} - - -#endif // PTHREADS - - -// -// ThreadRunner implementation -// -ThreadRunner::ThreadRunner(Action *todo) -{ - mAction = todo; - run(); -} - -void ThreadRunner::action() -{ - mAction(); -} - - -// -// Nesting Mutexi. -// This implementation uses mWait as a "sloppy" wait blocker (only). -// It should be a semaphore of course, but we don't have a semaphore -// abstraction right now. The authoritative locking protocol is based on mLock. -// -NestingMutex::NestingMutex() : mCount(0) -{ } - -void NestingMutex::lock() -{ - while (!tryLock()) { - mWait.lock(); - mWait.unlock(); - } -} - -bool NestingMutex::tryLock() -{ - StLock _(mLock); - if (mCount == 0) { // initial lock - mCount = 1; - mIdent = Thread::Identity::current(); - mWait.lock(); - return true; - } else if (mIdent == Thread::Identity::current()) { // recursive lock - mCount++; - return true; - } else { // locked by another thread - return false; - } -} - -void NestingMutex::unlock() -{ - StLock _(mLock); - assert(mCount > 0 && mIdent == Thread::Identity::current()); - if (--mCount == 0) // last recursive unlock - mWait.unlock(); -}