X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/9dae56ea45a0f5f8136a5c93d6f3a7f99399ca73..1df5f87f1309a8daa30dabdee855f48ae40d14ab:/wtf/Threading.h diff --git a/wtf/Threading.h b/wtf/Threading.h index 5e5f020..b6f8c24 100644 --- a/wtf/Threading.h +++ b/wtf/Threading.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved. * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) * * Redistribution and use in source and binary forms, with or without @@ -59,53 +59,16 @@ #ifndef Threading_h #define Threading_h -#include - -#if PLATFORM(WIN_CE) -#include -#endif +#include "Platform.h" +#include #include +#include #include +#include #include - -#if PLATFORM(WIN_OS) && !PLATFORM(WIN_CE) -#include -#elif PLATFORM(DARWIN) -#include -#elif COMPILER(GCC) -#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) -#include -#else -#include -#endif -#endif - -#if USE(PTHREADS) -#include -#elif PLATFORM(GTK) -#include -typedef struct _GMutex GMutex; -typedef struct _GCond GCond; -#endif - -#if USE(PTHREADS) && (PLATFORM(MAC) || PLATFORM(IPHONE)) -#ifdef __OBJC__ -@class NSThread; -#else -class NSThread; -#endif -#endif - -#if PLATFORM(QT) -#include -QT_BEGIN_NAMESPACE -class QMutex; -class QWaitCondition; -QT_END_NAMESPACE -#endif - -#include +#include +#include // For portability, we do not use thread-safe statics natively supported by some compilers (e.g. gcc). #define AtomicallyInitializedStatic(T, name) \ @@ -118,178 +81,38 @@ namespace WTF { typedef uint32_t ThreadIdentifier; typedef void* (*ThreadFunction)(void* argument); -// Returns 0 if thread creation failed +// This function must be called from the main thread. It is safe to call it repeatedly. +// Darwin is an exception to this rule: it is OK to call it from any thread, the only +// requirement is that the calls are not reentrant. +void initializeThreading(); + +// Returns 0 if thread creation failed. +// The thread name must be a literal since on some platforms it's passed in to the thread. ThreadIdentifier createThread(ThreadFunction, void*, const char* threadName); + +// Internal platform-specific createThread implementation. ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char* threadName); +// Called in the thread during initialization. +// Helpful for platforms where the thread name must be set from within the thread. +void initializeCurrentThreadInternal(const char* threadName); + ThreadIdentifier currentThread(); -bool isMainThread(); int waitForThreadCompletion(ThreadIdentifier, void**); void detachThread(ThreadIdentifier); -#if USE(PTHREADS) -typedef pthread_mutex_t PlatformMutex; -typedef pthread_cond_t PlatformCondition; -#elif PLATFORM(GTK) -typedef GOwnPtr PlatformMutex; -typedef GOwnPtr PlatformCondition; -#elif PLATFORM(QT) -typedef QT_PREPEND_NAMESPACE(QMutex)* PlatformMutex; -typedef QT_PREPEND_NAMESPACE(QWaitCondition)* PlatformCondition; -#elif PLATFORM(WIN_OS) -struct PlatformMutex { - CRITICAL_SECTION m_internalMutex; - size_t m_recursionCount; -}; -struct PlatformCondition { - size_t m_waitersGone; - size_t m_waitersBlocked; - size_t m_waitersToUnblock; - HANDLE m_blockLock; - HANDLE m_blockQueue; - HANDLE m_unblockLock; - - bool timedWait(PlatformMutex&, DWORD durationMilliseconds); - void signal(bool unblockAll); -}; -#else -typedef void* PlatformMutex; -typedef void* PlatformCondition; -#endif - -class Mutex : Noncopyable { -public: - Mutex(); - ~Mutex(); - - void lock(); - bool tryLock(); - void unlock(); - -public: - PlatformMutex& impl() { return m_mutex; } -private: - PlatformMutex m_mutex; -}; - -typedef Locker MutexLocker; - -class ThreadCondition : Noncopyable { -public: - ThreadCondition(); - ~ThreadCondition(); - - void wait(Mutex& mutex); - // Returns true if the condition was signaled before absoluteTime, false if the absoluteTime was reached or is in the past. - // The absoluteTime is in seconds, starting on January 1, 1970. The time is assumed to use the same time zone as WTF::currentTime(). - bool timedWait(Mutex&, double absoluteTime); - void signal(); - void broadcast(); - -private: - PlatformCondition m_condition; -}; +void yield(); -#if PLATFORM(WIN_OS) -#define WTF_USE_LOCKFREE_THREADSAFESHARED 1 - -#if COMPILER(MINGW) || COMPILER(MSVC7) || PLATFORM(WIN_CE) -inline void atomicIncrement(int* addend) { InterlockedIncrement(reinterpret_cast(addend)); } -inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast(addend)); } -#else -inline void atomicIncrement(int volatile* addend) { InterlockedIncrement(reinterpret_cast(addend)); } -inline int atomicDecrement(int volatile* addend) { return InterlockedDecrement(reinterpret_cast(addend)); } -#endif - -#elif PLATFORM(DARWIN) -#define WTF_USE_LOCKFREE_THREADSAFESHARED 1 - -inline void atomicIncrement(int volatile* addend) { OSAtomicIncrement32Barrier(const_cast(addend)); } -inline int atomicDecrement(int volatile* addend) { return OSAtomicDecrement32Barrier(const_cast(addend)); } - -#elif COMPILER(GCC) -#define WTF_USE_LOCKFREE_THREADSAFESHARED 1 - -inline void atomicIncrement(int volatile* addend) { __gnu_cxx::__atomic_add(addend, 1); } -inline int atomicDecrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, -1) - 1; } - -#endif - -template class ThreadSafeShared : Noncopyable { -public: - ThreadSafeShared(int initialRefCount = 1) - : m_refCount(initialRefCount) - { - } - - void ref() - { -#if USE(LOCKFREE_THREADSAFESHARED) - atomicIncrement(&m_refCount); -#else - MutexLocker locker(m_mutex); - ++m_refCount; -#endif - } - - void deref() - { -#if USE(LOCKFREE_THREADSAFESHARED) - if (atomicDecrement(&m_refCount) <= 0) -#else - { - MutexLocker locker(m_mutex); - --m_refCount; - } - if (m_refCount <= 0) -#endif - delete static_cast(this); - } - - bool hasOneRef() - { - return refCount() == 1; - } - - int refCount() const - { -#if !USE(LOCKFREE_THREADSAFESHARED) - MutexLocker locker(m_mutex); -#endif - return static_cast(m_refCount); - } - -private: - int m_refCount; -#if !USE(LOCKFREE_THREADSAFESHARED) - mutable Mutex m_mutex; -#endif -}; - -// This function must be called from the main thread. It is safe to call it repeatedly. -// Darwin is an exception to this rule: it is OK to call it from any thread, the only requirement is that the calls are not reentrant. -void initializeThreading(); - -#if USE(PTHREADS) && (PLATFORM(MAC) || PLATFORM(IPHONE)) -void initializeMainNSThread(); -NSThread *mainNSThread(); -#endif - void lockAtomicallyInitializedStaticMutex(); void unlockAtomicallyInitializedStaticMutex(); } // namespace WTF -using WTF::Mutex; -using WTF::MutexLocker; -using WTF::ThreadCondition; using WTF::ThreadIdentifier; -using WTF::ThreadSafeShared; - using WTF::createThread; using WTF::currentThread; -using WTF::isMainThread; using WTF::detachThread; using WTF::waitForThreadCompletion; +using WTF::yield; #endif // Threading_h