Loading...
src/dyldLock.cpp dyld-43 dyld-832.7.3
--- dyld/dyld-43/src/dyldLock.cpp
+++ dyld/dyld-832.7.3/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-2012 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -26,262 +26,34 @@
 
 #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 = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
 
-//
-// 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
-//
-// 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 
-{
-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
-};
+// <rdar://problem/6361143> Need a way to determine if a gdb call to dlopen() would block
+int	__attribute__((visibility("hidden")))			_dyld_global_lock_held = 0;
 
 
-//
-// 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;
-	}
+LockHelper::LockHelper() 
+{ 
+	dyldGlobalLockAcquire();
 }
 
-RecursiveReaderWriterLock::RecursiveReaderWriterLock()
-{
-	initIfNeeded();
+LockHelper::~LockHelper() 
+{ 
+	dyldGlobalLockRelease();
 }
 
-void RecursiveReaderWriterLock::lockForSingleWritingThread()
+void dyldGlobalLockAcquire() 
 {
-	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
+	pthread_mutex_lock(&sGlobalMutex);
+	++_dyld_global_lock_held;
 }
 
-void RecursiveReaderWriterLock::unlockForSingleWritingThread()
+void dyldGlobalLockRelease() 
 {
-	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
+	--_dyld_global_lock_held;
+	pthread_mutex_unlock(&sGlobalMutex);
 }
 
 
-void RecursiveReaderWriterLock::lockForMultipleReadingThreads()
-{
-	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
-}
-
-
-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();
-}
-
-
-