Loading...
--- dyld/dyld-44.2/src/dyldLock.cpp
+++ dyld/dyld-96.2/src/dyldLock.cpp
@@ -1,6 +1,6 @@
/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
*
- * Copyright (c) 2004-2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2004-2007 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
@@ -26,262 +26,42 @@
#include "dyldLock.h"
-// until the reader/writer locks are fully tested, we just use a simple recursive mutex
-#define REAL_READER_WRITER_LOCK 0
+
+static pthread_mutex_t sGlobalMutex;
//
-// This class implements a recursive reader/writer lock.
-// Recursive means a thread that has already aquired the lock can re-acquire it.
-// The lock allows either:
-// a) one "writer" thread to hold lock
-// b) multiple "reader" threads to hold
+// This initializer can go away once the following is available:
+// <rdar://problem/4927311> implement PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
//
-// A thread with the writer can acquire a reader lock.
-// A thread with a reader lock can acquire a writer lock iff it is the only thread with a reader lock
-//
-class RecursiveReaderWriterLock
+void dyldGlobalLockInitialize()
{
-public:
- RecursiveReaderWriterLock() __attribute__((visibility("hidden")));
- void initIfNeeded();
-
-
- void lockForSingleWritingThread() __attribute__((visibility("hidden")));
- void unlockForSingleWritingThread() __attribute__((visibility("hidden")));
-
- void lockForMultipleReadingThreads() __attribute__((visibility("hidden")));
- void unlockForMultipleReadingThreads() __attribute__((visibility("hidden")));
-
-private:
-#if REAL_READER_WRITER_LOCK
- struct ThreadRecursionCount {
- pthread_t fThread;
- uint32_t fCount;
- };
- bool writerThreadIsAnyThreadBut(pthread_t thread);
- void writerThreadRetain(pthread_t thread);
- bool writerThreadRelease(pthread_t thread);
-
- enum { kMaxReaderThreads = 4 };
- bool readerThreadSetRetain(pthread_t thread);
- bool readerThreadSetRelease(pthread_t thread);
- bool readerThreadSetContainsAnotherThread(pthread_t thread);
-
- ThreadRecursionCount fWriterThread;
- ThreadRecursionCount fReaderThreads[kMaxReaderThreads];
- pthread_cond_t fLockFree;
- pthread_mutex_t fMutex;
-#else
- pthread_mutex_t fMutex;
-#endif
- bool fInitialized; // assumes this is statically initialized to false because sLock is static
-};
-
-
-//
-// initIfNeeded() is a hack so that when libSystem_debug.dylb is useable.
-// The problem is that Objective-C +load methods are called before C++ initialziers are run
-// If +load method makes a call into dyld, sLock is not initialized.
-//
-// The long term solution is for objc and dyld to work more closely together so that instead
-// of running all +load methods before all initializers, we run each image's +load then its
-// initializers all in bottom up order.
-//
-// This lazy initialization is not thread safe, but as long as someone does not create a
-// new thread in a +load method, the C++ constructor for sLock will be called before main()
-// so there will only be one thead.
-//
-void RecursiveReaderWriterLock::initIfNeeded()
-{
- if ( ! fInitialized ) {
- pthread_mutexattr_t recursiveMutexAttr;
- pthread_mutexattr_init(&recursiveMutexAttr);
- pthread_mutexattr_settype(&recursiveMutexAttr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&fMutex, &recursiveMutexAttr);
- #if REAL_READER_WRITER_LOCK
- pthread_cond_init(&fLockFree, NULL);
- fWriterThread.fThread = NULL;
- fWriterThread.fCount = 0;
- for (int i=0; i < kMaxReaderThreads; ++i) {
- fReaderThreads[i].fThread = NULL;
- fReaderThreads[i].fCount = 0;
- }
- #endif
- fInitialized = true;
- }
-}
-
-RecursiveReaderWriterLock::RecursiveReaderWriterLock()
-{
- initIfNeeded();
-}
-
-void RecursiveReaderWriterLock::lockForSingleWritingThread()
-{
- this->initIfNeeded();
-#if REAL_READER_WRITER_LOCK
- pthread_mutex_lock(&fMutex);
- pthread_t thisThread = pthread_self();
- // wait as long as there is another writer or any readers on a different thread
- while ( writerThreadIsAnyThreadBut(thisThread) || readerThreadSetContainsAnotherThread(thisThread) ) {
- pthread_cond_wait(&fLockFree, &fMutex);
- }
- writerThreadRetain(thisThread);
- pthread_mutex_unlock(&fMutex);
-#else
- pthread_mutex_lock(&fMutex);
-#endif
-}
-
-void RecursiveReaderWriterLock::unlockForSingleWritingThread()
-{
- this->initIfNeeded();
-#if REAL_READER_WRITER_LOCK
- pthread_mutex_lock(&fMutex);
- if ( writerThreadRelease(pthread_self()) ) {
- pthread_cond_broadcast(&fLockFree);
- }
- pthread_mutex_unlock(&fMutex);
-#else
- pthread_mutex_unlock(&fMutex);
-#endif
+ pthread_mutexattr_t recursiveMutexAttr;
+ pthread_mutexattr_init(&recursiveMutexAttr);
+ pthread_mutexattr_settype(&recursiveMutexAttr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&sGlobalMutex, &recursiveMutexAttr);
}
-void RecursiveReaderWriterLock::lockForMultipleReadingThreads()
+LockHelper::LockHelper()
+{
+ pthread_mutex_lock(&sGlobalMutex);
+}
+
+LockHelper::~LockHelper()
+{
+ pthread_mutex_unlock(&sGlobalMutex);
+}
+
+void dyldGlobalLockAcquire()
{
- this->initIfNeeded();
-#if REAL_READER_WRITER_LOCK
- pthread_mutex_lock(&fMutex);
- pthread_t thisThread = pthread_self();
- // wait as long as there is a writer on another thread or too many readers already
- while ( writerThreadIsAnyThreadBut(thisThread) || !readerThreadSetRetain(thisThread) ) {
- pthread_cond_wait(&fLockFree, &fMutex);
- }
- pthread_mutex_unlock(&fMutex);
-#else
- pthread_mutex_lock(&fMutex);
-#endif
+ pthread_mutex_lock(&sGlobalMutex);
+}
+
+void dyldGlobalLockRelease()
+{
+ pthread_mutex_unlock(&sGlobalMutex);
}
-void RecursiveReaderWriterLock::unlockForMultipleReadingThreads()
-{
- this->initIfNeeded();
-#if REAL_READER_WRITER_LOCK
- pthread_mutex_lock(&fMutex);
- if ( readerThreadSetRelease(pthread_self()) ) {
- pthread_cond_broadcast(&fLockFree);
- }
- pthread_mutex_unlock(&fMutex);
-#else
- pthread_mutex_unlock(&fMutex);
-#endif
-}
-
-#if REAL_READER_WRITER_LOCK
-bool RecursiveReaderWriterLock::writerThreadIsAnyThreadBut(pthread_t thread)
-{
- return ( (fWriterThread.fThread != NULL) && (fWriterThread.fThread != thread) );
-}
-
-void RecursiveReaderWriterLock::writerThreadRetain(pthread_t thread)
-{
- ++fWriterThread.fCount;
-}
-
-bool RecursiveReaderWriterLock::writerThreadRelease(pthread_t thread)
-{
- return ( --fWriterThread.fCount == 0 );
-}
-
-
-bool RecursiveReaderWriterLock::readerThreadSetRetain(pthread_t thread)
-{
- // if thread is already in set, bump its count
- for (int i=0; i < kMaxReaderThreads; ++i) {
- if ( fReaderThreads[i].fThread == thread ) {
- ++fReaderThreads[i].fCount;
- return true;
- }
- }
- // find empty slot in set
- for (int i=0; i < kMaxReaderThreads; ++i) {
- if ( fReaderThreads[i].fThread == NULL ) {
- fReaderThreads[i].fThread = thread;
- fReaderThreads[i].fCount = 1;
- return true;
- }
- }
-
- // all reader slots full
- return false;
-}
-
-bool RecursiveReaderWriterLock::readerThreadSetRelease(pthread_t thread)
-{
- for (int i=0; i < kMaxReaderThreads; ++i) {
- if ( fReaderThreads[i].fThread == thread ) {
- if ( --fReaderThreads[i].fCount == 0 ) {
- fReaderThreads[i].fThread = NULL;
- return true;
- }
- return false;
- }
- }
- // should never get here
- return false;
-}
-
-bool RecursiveReaderWriterLock::readerThreadSetContainsAnotherThread(pthread_t thread)
-{
- for (int i=0; i < kMaxReaderThreads; ++i) {
- if ( (fReaderThreads[i].fThread != NULL) && (fReaderThreads[i].fThread != thread) )
- return true;
- }
- return false;
-}
-#endif
-
-
-// dyld's global reader/writer lock
-static RecursiveReaderWriterLock sLock;
-
-
-LockReaderHelper::LockReaderHelper()
-{
- sLock.lockForMultipleReadingThreads();
-}
-
-LockReaderHelper::~LockReaderHelper()
-{
- sLock.unlockForMultipleReadingThreads();
-}
-
-
-LockWriterHelper::LockWriterHelper()
-{
- sLock.lockForSingleWritingThread();
-}
-
-LockWriterHelper::~LockWriterHelper()
-{
- sLock.unlockForSingleWritingThread();
-}
-
-
-// needed by lazy binding
-void lockForLazyBinding()
-{
- sLock.lockForMultipleReadingThreads();
-}
-
-void unlockForLazyBinding()
-{
- sLock.unlockForMultipleReadingThreads();
-}
-
-
-