X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/ba379fdc102753d6be2c4d937058fe40257329fe..14957cd040308e3eeec43d26bae5d76da13fcd85:/wtf/ThreadingPthreads.cpp?ds=inline diff --git a/wtf/ThreadingPthreads.cpp b/wtf/ThreadingPthreads.cpp index 0c6db2d..916aa36 100644 --- a/wtf/ThreadingPthreads.cpp +++ b/wtf/ThreadingPthreads.cpp @@ -37,13 +37,26 @@ #include "MainThread.h" #include "RandomNumberSeed.h" #include "StdLibExtras.h" +#include "ThreadIdentifierDataPthreads.h" +#include "ThreadSpecific.h" #include "UnusedParam.h" #include + +#if !COMPILER(MSVC) #include +#include #include +#endif + +#if OS(ANDROID) +#include "JNIUtility.h" +#include "ThreadFunctionInvocation.h" +#include +#include +#endif -#if PLATFORM(ANDROID) -#include "jni_utility.h" +#if OS(MAC_OS_X) && !defined(BUILDING_ON_LEOPARD) +#include #endif namespace WTF { @@ -52,7 +65,7 @@ typedef HashMap ThreadMap; static Mutex* atomicallyInitializedStaticMutex; -static ThreadIdentifier mainThreadIdentifier; // The thread that was the first to call initializeThreading(), which must be the main thread. +void clearPthreadHandleForIdentifier(ThreadIdentifier); static Mutex& threadMapMutex() { @@ -62,13 +75,12 @@ static Mutex& threadMapMutex() void initializeThreading() { - if (!atomicallyInitializedStaticMutex) { - atomicallyInitializedStaticMutex = new Mutex; - threadMapMutex(); - initializeRandomNumberGenerator(); - mainThreadIdentifier = currentThread(); - initializeMainThread(); - } + if (atomicallyInitializedStaticMutex) + return; + + atomicallyInitializedStaticMutex = new Mutex; + threadMapMutex(); + initializeRandomNumberGenerator(); } void lockAtomicallyInitializedStaticMutex() @@ -101,7 +113,7 @@ static ThreadIdentifier identifierByPthreadHandle(const pthread_t& pthreadHandle return 0; } -static ThreadIdentifier establishIdentifierForPthreadHandle(pthread_t& pthreadHandle) +static ThreadIdentifier establishIdentifierForPthreadHandle(const pthread_t& pthreadHandle) { ASSERT(!identifierByPthreadHandle(pthreadHandle)); @@ -121,7 +133,7 @@ static pthread_t pthreadHandleForIdentifier(ThreadIdentifier id) return threadMap().get(id); } -static void clearPthreadHandleForIdentifier(ThreadIdentifier id) +void clearPthreadHandleForIdentifier(ThreadIdentifier id) { MutexLocker locker(threadMapMutex()); @@ -130,38 +142,35 @@ static void clearPthreadHandleForIdentifier(ThreadIdentifier id) threadMap().remove(id); } -#if PLATFORM(ANDROID) -// On the Android platform, threads must be registered with the VM before they run. -struct ThreadData { - ThreadFunction entryPoint; - void* arg; -}; - +#if OS(ANDROID) static void* runThreadWithRegistration(void* arg) { - ThreadData* data = static_cast(arg); + OwnPtr invocation = adoptPtr(static_cast(arg)); JavaVM* vm = JSC::Bindings::getJavaVM(); JNIEnv* env; void* ret = 0; if (vm->AttachCurrentThread(&env, 0) == JNI_OK) { - ret = data->entryPoint(data->arg); + ret = invocation->function(invocation->data); vm->DetachCurrentThread(); } - delete data; return ret; } ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*) { pthread_t threadHandle; - ThreadData* threadData = new ThreadData(); - threadData->entryPoint = entryPoint; - threadData->arg = data; - if (pthread_create(&threadHandle, 0, runThreadWithRegistration, static_cast(threadData))) { + // On the Android platform, threads must be registered with the VM before they run. + OwnPtr invocation = adoptPtr(new ThreadFunctionInvocation(entryPoint, data)); + + if (pthread_create(&threadHandle, 0, runThreadWithRegistration, invocation.get())) { LOG_ERROR("Failed to create pthread at entry point %p with data %p", entryPoint, data); return 0; } + + // The thread will take ownership of invocation. + invocation.leakPtr(); + return establishIdentifierForPthreadHandle(threadHandle); } #else @@ -177,13 +186,23 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con } #endif -void setThreadNameInternal(const char* threadName) +void initializeCurrentThreadInternal(const char* threadName) { #if HAVE(PTHREAD_SETNAME_NP) pthread_setname_np(threadName); #else UNUSED_PARAM(threadName); #endif + +#if OS(MAC_OS_X) && !defined(BUILDING_ON_LEOPARD) + // All threads that potentially use APIs above the BSD layer must be registered with the Objective-C + // garbage collector in case API implementations use garbage-collected memory. + objc_registerThreadWithCollector(); +#endif + + ThreadIdentifier id = identifierByPthreadHandle(pthread_self()); + ASSERT(id); + ThreadIdentifierData::initialize(id); } int waitForThreadCompletion(ThreadIdentifier threadID, void** result) @@ -191,12 +210,13 @@ int waitForThreadCompletion(ThreadIdentifier threadID, void** result) ASSERT(threadID); pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID); + if (!pthreadHandle) + return 0; int joinResult = pthread_join(pthreadHandle, result); if (joinResult == EDEADLK) LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID); - clearPthreadHandleForIdentifier(threadID); return joinResult; } @@ -205,28 +225,38 @@ void detachThread(ThreadIdentifier threadID) ASSERT(threadID); pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID); + if (!pthreadHandle) + return; pthread_detach(pthreadHandle); +} - clearPthreadHandleForIdentifier(threadID); +void yield() +{ + sched_yield(); } ThreadIdentifier currentThread() { - pthread_t currentThread = pthread_self(); - if (ThreadIdentifier id = identifierByPthreadHandle(currentThread)) + ThreadIdentifier id = ThreadIdentifierData::identifier(); + if (id) return id; - return establishIdentifierForPthreadHandle(currentThread); -} -bool isMainThread() -{ - return currentThread() == mainThreadIdentifier; + // Not a WTF-created thread, ThreadIdentifier is not established yet. + id = establishIdentifierForPthreadHandle(pthread_self()); + ThreadIdentifierData::initialize(id); + return id; } Mutex::Mutex() { - pthread_mutex_init(&m_mutex, NULL); + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); + + pthread_mutex_init(&m_mutex, &attr); + + pthread_mutexattr_destroy(&attr); } Mutex::~Mutex() @@ -259,7 +289,7 @@ void Mutex::unlock() ASSERT_UNUSED(result, !result); } - +#if HAVE(PTHREAD_RWLOCK) ReadWriteLock::ReadWriteLock() { pthread_rwlock_init(&m_readWriteLock, NULL); @@ -313,6 +343,7 @@ void ReadWriteLock::unlock() int result = pthread_rwlock_unlock(&m_readWriteLock); ASSERT_UNUSED(result, !result); } +#endif // HAVE(PTHREAD_RWLOCK) ThreadCondition::ThreadCondition() {