Changeset 58206 in webkit for trunk/JavaScriptCore
- Timestamp:
- Apr 23, 2010, 6:07:37 PM (15 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 6 edited
- 3 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r58181 r58206 1 2010-04-23 Sam Weinig <[email protected]> 2 3 Reviewed by David Levin. 4 5 Fix for https://bugs.webkit.org/show_bug.cgi?id=38060 6 Split up Threading.h 7 8 Move bits for of Threading.h into 3 new files. 9 - Atomics.h for atomic operations. 10 - ThreadSafeShared.h for the ThreadSafeShared class. 11 - ThreadingPrimitives.h for the primitives and platform types. 12 13 Basic threading operations (creation, etc.) remain in Threading.h. 14 15 * GNUmakefile.am: 16 * JavaScriptCore.gypi: 17 * JavaScriptCore.vcproj/WTF/WTF.vcproj: 18 * JavaScriptCore.xcodeproj/project.pbxproj: 19 * wtf/Atomics.h: Copied from wtf/Threading.h. 20 * wtf/ThreadSafeShared.h: Copied from wtf/Threading.h. 21 * wtf/Threading.h: 22 * wtf/ThreadingPrimitives.h: Copied from wtf/Threading.h. 23 1 24 2010-04-23 Sam Weinig <[email protected]> 2 25 -
trunk/JavaScriptCore/GNUmakefile.am
r58136 r58206 225 225 JavaScriptCore/wtf/Assertions.cpp \ 226 226 JavaScriptCore/wtf/Assertions.h \ 227 JavaScriptCore/wtf/Atomics.h \ 227 228 JavaScriptCore/wtf/ByteArray.cpp \ 228 229 JavaScriptCore/wtf/ByteArray.h \ … … 284 285 JavaScriptCore/wtf/Threading.cpp \ 285 286 JavaScriptCore/wtf/Threading.h \ 287 JavaScriptCore/wtf/ThreadingPrimitives.h \ 286 288 JavaScriptCore/wtf/ThreadingPthreads.cpp \ 289 JavaScriptCore/wtf/ThreadSafeShared.h \ 287 290 JavaScriptCore/wtf/ThreadSpecific.h \ 288 291 JavaScriptCore/wtf/TypeTraits.cpp \ -
trunk/JavaScriptCore/JavaScriptCore.gypi
r58165 r58206 337 337 'wtf/Assertions.cpp', 338 338 'wtf/Assertions.h', 339 'wtf/Atomics.h', 339 340 'wtf/AVLTree.h', 340 341 'wtf/ByteArray.cpp', … … 415 416 'wtf/Threading.h', 416 417 'wtf/ThreadingNone.cpp', 418 'wtf/ThreadingPrimitives.h', 417 419 'wtf/ThreadingPthreads.cpp', 418 420 'wtf/ThreadingWin.cpp', 421 'wtf/ThreadSafeShared.h', 419 422 'wtf/ThreadSpecific.h', 420 423 'wtf/ThreadSpecificWin.cpp', -
trunk/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
r58165 r58206 262 262 </File> 263 263 <File 264 RelativePath="..\..\wtf\Atomics.h" 265 > 266 </File> 267 <File 264 268 RelativePath="..\..\wtf\ByteArray.cpp" 265 269 > … … 514 518 </File> 515 519 <File 520 RelativePath="..\..\wtf\ThreadingPrimitives.h" 521 > 522 </File> 523 <File 516 524 RelativePath="..\..\wtf\ThreadingWin.cpp" 525 > 526 </File> 527 <File 528 RelativePath="..\..\wtf\ThreadSafeShared.h" 517 529 > 518 530 </File> -
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r58136 r58206 462 462 BC3135640F302FA3003DFD3A /* DebuggerActivation.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3135620F302FA3003DFD3A /* DebuggerActivation.h */; settings = {ATTRIBUTES = (Private, ); }; }; 463 463 BC3135650F302FA3003DFD3A /* DebuggerActivation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC3135630F302FA3003DFD3A /* DebuggerActivation.cpp */; }; 464 BC5F7BBE11823B590052C02C /* Atomics.h in Headers */ = {isa = PBXBuildFile; fileRef = BC5F7BBB11823B590052C02C /* Atomics.h */; settings = {ATTRIBUTES = (Private, ); }; }; 465 BC5F7BBF11823B590052C02C /* ThreadingPrimitives.h in Headers */ = {isa = PBXBuildFile; fileRef = BC5F7BBC11823B590052C02C /* ThreadingPrimitives.h */; settings = {ATTRIBUTES = (Private, ); }; }; 466 BC5F7BC011823B590052C02C /* ThreadSafeShared.h in Headers */ = {isa = PBXBuildFile; fileRef = BC5F7BBD11823B590052C02C /* ThreadSafeShared.h */; settings = {ATTRIBUTES = (Private, ); }; }; 464 467 BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; 465 468 BC756FC90E2031B200DE7D12 /* JSGlobalObjectFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */; }; … … 957 960 BC337BDE0E1AF0B80076918A /* GetterSetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetterSetter.h; sourceTree = "<group>"; }; 958 961 BC337BEA0E1B00CB0076918A /* Error.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Error.cpp; sourceTree = "<group>"; }; 962 BC5F7BBB11823B590052C02C /* Atomics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Atomics.h; sourceTree = "<group>"; }; 963 BC5F7BBC11823B590052C02C /* ThreadingPrimitives.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadingPrimitives.h; sourceTree = "<group>"; }; 964 BC5F7BBD11823B590052C02C /* ThreadSafeShared.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadSafeShared.h; sourceTree = "<group>"; }; 959 965 BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClassInfo.h; sourceTree = "<group>"; }; 960 966 BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalObjectFunctions.cpp; sourceTree = "<group>"; }; … … 1368 1374 657EEBBF094E445E008C9C7B /* HashCountedSet.h */, 1369 1375 65DFC92A08EA173A00F7300B /* HashFunctions.h */, 1376 BC5F7BBB11823B590052C02C /* Atomics.h */, 1377 BC5F7BBC11823B590052C02C /* ThreadingPrimitives.h */, 1378 BC5F7BBD11823B590052C02C /* ThreadSafeShared.h */, 1370 1379 652246A40C8D7A0E007BDAF7 /* HashIterators.h */, 1371 1380 65DFC92B08EA173A00F7300B /* HashMap.h */, … … 2101 2110 86B99DA711800F8500DF5A90 /* AtomicStringTable.h in Headers */, 2102 2111 511FC4CB117EE2A800425272 /* MD5.h in Headers */, 2112 BC5F7BBE11823B590052C02C /* Atomics.h in Headers */, 2113 BC5F7BBF11823B590052C02C /* ThreadingPrimitives.h in Headers */, 2114 BC5F7BC011823B590052C02C /* ThreadSafeShared.h in Headers */, 2103 2115 ); 2104 2116 runOnlyForDeploymentPostprocessing = 0; -
trunk/JavaScriptCore/wtf/Atomics.h
r58179 r58206 1 1 /* 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.2 * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2007 Justin Haygood ([email protected]) 4 4 * … … 57 57 */ 58 58 59 #ifndef Threading_h60 #define Threading_h59 #ifndef Atomics_h 60 #define Atomics_h 61 61 62 62 #include "Platform.h" 63 63 64 #if OS(WINCE) 65 #include <windows.h> 66 #endif 67 68 #include <wtf/Assertions.h> 69 #include <wtf/Locker.h> 70 #include <wtf/MainThread.h> 71 #include <wtf/Noncopyable.h> 72 73 #if OS(WINDOWS) && !OS(WINCE) 64 #if OS(WINDOWS) 74 65 #include <windows.h> 75 66 #elif OS(DARWIN) … … 85 76 #endif 86 77 87 #if USE(PTHREADS)88 #include <pthread.h>89 #elif PLATFORM(GTK)90 #include "GOwnPtr.h"91 typedef struct _GMutex GMutex;92 typedef struct _GCond GCond;93 #endif94 95 #if PLATFORM(QT)96 #include <qglobal.h>97 QT_BEGIN_NAMESPACE98 class QMutex;99 class QWaitCondition;100 QT_END_NAMESPACE101 #endif102 103 #include <stdint.h>104 105 // For portability, we do not use thread-safe statics natively supported by some compilers (e.g. gcc).106 #define AtomicallyInitializedStatic(T, name) \107 WTF::lockAtomicallyInitializedStaticMutex(); \108 static T name; \109 WTF::unlockAtomicallyInitializedStaticMutex();110 111 78 namespace WTF { 112 113 typedef uint32_t ThreadIdentifier;114 typedef void* (*ThreadFunction)(void* argument);115 116 // Returns 0 if thread creation failed.117 // The thread name must be a literal since on some platforms it's passed in to the thread.118 ThreadIdentifier createThread(ThreadFunction, void*, const char* threadName);119 120 // Internal platform-specific createThread implementation.121 ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char* threadName);122 123 // Called in the thread during initialization.124 // Helpful for platforms where the thread name must be set from within the thread.125 void initializeCurrentThreadInternal(const char* threadName);126 127 ThreadIdentifier currentThread();128 int waitForThreadCompletion(ThreadIdentifier, void**);129 void detachThread(ThreadIdentifier);130 131 #if USE(PTHREADS)132 typedef pthread_mutex_t PlatformMutex;133 #if HAVE(PTHREAD_RWLOCK)134 typedef pthread_rwlock_t PlatformReadWriteLock;135 #else136 typedef void* PlatformReadWriteLock;137 #endif138 typedef pthread_cond_t PlatformCondition;139 #elif PLATFORM(GTK)140 typedef GOwnPtr<GMutex> PlatformMutex;141 typedef void* PlatformReadWriteLock; // FIXME: Implement.142 typedef GOwnPtr<GCond> PlatformCondition;143 #elif PLATFORM(QT)144 typedef QT_PREPEND_NAMESPACE(QMutex)* PlatformMutex;145 typedef void* PlatformReadWriteLock; // FIXME: Implement.146 typedef QT_PREPEND_NAMESPACE(QWaitCondition)* PlatformCondition;147 #elif OS(WINDOWS)148 struct PlatformMutex {149 CRITICAL_SECTION m_internalMutex;150 size_t m_recursionCount;151 };152 typedef void* PlatformReadWriteLock; // FIXME: Implement.153 struct PlatformCondition {154 size_t m_waitersGone;155 size_t m_waitersBlocked;156 size_t m_waitersToUnblock;157 HANDLE m_blockLock;158 HANDLE m_blockQueue;159 HANDLE m_unblockLock;160 161 bool timedWait(PlatformMutex&, DWORD durationMilliseconds);162 void signal(bool unblockAll);163 };164 #else165 typedef void* PlatformMutex;166 typedef void* PlatformReadWriteLock;167 typedef void* PlatformCondition;168 #endif169 170 class Mutex : public Noncopyable {171 public:172 Mutex();173 ~Mutex();174 175 void lock();176 bool tryLock();177 void unlock();178 179 public:180 PlatformMutex& impl() { return m_mutex; }181 private:182 PlatformMutex m_mutex;183 };184 185 typedef Locker<Mutex> MutexLocker;186 187 class ReadWriteLock : public Noncopyable {188 public:189 ReadWriteLock();190 ~ReadWriteLock();191 192 void readLock();193 bool tryReadLock();194 195 void writeLock();196 bool tryWriteLock();197 198 void unlock();199 200 private:201 PlatformReadWriteLock m_readWriteLock;202 };203 204 class ThreadCondition : public Noncopyable {205 public:206 ThreadCondition();207 ~ThreadCondition();208 209 void wait(Mutex& mutex);210 // Returns true if the condition was signaled before absoluteTime, false if the absoluteTime was reached or is in the past.211 // The absoluteTime is in seconds, starting on January 1, 1970. The time is assumed to use the same time zone as WTF::currentTime().212 bool timedWait(Mutex&, double absoluteTime);213 void signal();214 void broadcast();215 216 private:217 PlatformCondition m_condition;218 };219 79 220 80 #if OS(WINDOWS) … … 248 108 #endif 249 109 250 class ThreadSafeSharedBase : public Noncopyable {251 public:252 ThreadSafeSharedBase(int initialRefCount = 1)253 : m_refCount(initialRefCount)254 {255 }256 257 void ref()258 {259 #if USE(LOCKFREE_THREADSAFESHARED)260 atomicIncrement(&m_refCount);261 #else262 MutexLocker locker(m_mutex);263 ++m_refCount;264 #endif265 }266 267 bool hasOneRef()268 {269 return refCount() == 1;270 }271 272 int refCount() const273 {274 #if !USE(LOCKFREE_THREADSAFESHARED)275 MutexLocker locker(m_mutex);276 #endif277 return static_cast<int const volatile &>(m_refCount);278 }279 280 protected:281 // Returns whether the pointer should be freed or not.282 bool derefBase()283 {284 #if USE(LOCKFREE_THREADSAFESHARED)285 if (atomicDecrement(&m_refCount) <= 0)286 return true;287 #else288 int refCount;289 {290 MutexLocker locker(m_mutex);291 --m_refCount;292 refCount = m_refCount;293 }294 if (refCount <= 0)295 return true;296 #endif297 return false;298 }299 300 private:301 template<class T>302 friend class CrossThreadRefCounted;303 304 int m_refCount;305 #if !USE(LOCKFREE_THREADSAFESHARED)306 mutable Mutex m_mutex;307 #endif308 };309 310 template<class T> class ThreadSafeShared : public ThreadSafeSharedBase {311 public:312 ThreadSafeShared(int initialRefCount = 1)313 : ThreadSafeSharedBase(initialRefCount)314 {315 }316 317 void deref()318 {319 if (derefBase())320 delete static_cast<T*>(this);321 }322 };323 324 // This function must be called from the main thread. It is safe to call it repeatedly.325 // 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.326 void initializeThreading();327 328 void lockAtomicallyInitializedStaticMutex();329 void unlockAtomicallyInitializedStaticMutex();330 331 110 } // namespace WTF 332 333 using WTF::Mutex;334 using WTF::MutexLocker;335 using WTF::ThreadCondition;336 using WTF::ThreadIdentifier;337 using WTF::ThreadSafeShared;338 111 339 112 #if USE(LOCKFREE_THREADSAFESHARED) … … 342 115 #endif 343 116 344 using WTF::createThread; 345 using WTF::currentThread; 346 using WTF::detachThread; 347 using WTF::waitForThreadCompletion; 348 349 #endif // Threading_h 117 #endif // Atomics_h -
trunk/JavaScriptCore/wtf/ThreadSafeShared.h
r58179 r58206 1 1 /* 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.2 * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2007 Justin Haygood ([email protected]) 4 4 * … … 57 57 */ 58 58 59 #ifndef Thread ing_h60 #define Thread ing_h59 #ifndef ThreadSafeShared_h 60 #define ThreadSafeShared_h 61 61 62 62 #include "Platform.h" 63 63 64 #if OS(WINCE) 65 #include <windows.h> 66 #endif 67 68 #include <wtf/Assertions.h> 69 #include <wtf/Locker.h> 70 #include <wtf/MainThread.h> 64 #include <wtf/Atomics.h> 71 65 #include <wtf/Noncopyable.h> 72 73 #if OS(WINDOWS) && !OS(WINCE) 74 #include <windows.h> 75 #elif OS(DARWIN) 76 #include <libkern/OSAtomic.h> 77 #elif OS(ANDROID) 78 #include <cutils/atomic.h> 79 #elif COMPILER(GCC) && !OS(SYMBIAN) 80 #if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) 81 #include <ext/atomicity.h> 82 #else 83 #include <bits/atomicity.h> 84 #endif 85 #endif 86 87 #if USE(PTHREADS) 88 #include <pthread.h> 89 #elif PLATFORM(GTK) 90 #include "GOwnPtr.h" 91 typedef struct _GMutex GMutex; 92 typedef struct _GCond GCond; 93 #endif 94 95 #if PLATFORM(QT) 96 #include <qglobal.h> 97 QT_BEGIN_NAMESPACE 98 class QMutex; 99 class QWaitCondition; 100 QT_END_NAMESPACE 101 #endif 102 103 #include <stdint.h> 104 105 // For portability, we do not use thread-safe statics natively supported by some compilers (e.g. gcc). 106 #define AtomicallyInitializedStatic(T, name) \ 107 WTF::lockAtomicallyInitializedStaticMutex(); \ 108 static T name; \ 109 WTF::unlockAtomicallyInitializedStaticMutex(); 66 #include <wtf/ThreadingPrimitives.h> 110 67 111 68 namespace WTF { 112 113 typedef uint32_t ThreadIdentifier;114 typedef void* (*ThreadFunction)(void* argument);115 116 // Returns 0 if thread creation failed.117 // The thread name must be a literal since on some platforms it's passed in to the thread.118 ThreadIdentifier createThread(ThreadFunction, void*, const char* threadName);119 120 // Internal platform-specific createThread implementation.121 ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char* threadName);122 123 // Called in the thread during initialization.124 // Helpful for platforms where the thread name must be set from within the thread.125 void initializeCurrentThreadInternal(const char* threadName);126 127 ThreadIdentifier currentThread();128 int waitForThreadCompletion(ThreadIdentifier, void**);129 void detachThread(ThreadIdentifier);130 131 #if USE(PTHREADS)132 typedef pthread_mutex_t PlatformMutex;133 #if HAVE(PTHREAD_RWLOCK)134 typedef pthread_rwlock_t PlatformReadWriteLock;135 #else136 typedef void* PlatformReadWriteLock;137 #endif138 typedef pthread_cond_t PlatformCondition;139 #elif PLATFORM(GTK)140 typedef GOwnPtr<GMutex> PlatformMutex;141 typedef void* PlatformReadWriteLock; // FIXME: Implement.142 typedef GOwnPtr<GCond> PlatformCondition;143 #elif PLATFORM(QT)144 typedef QT_PREPEND_NAMESPACE(QMutex)* PlatformMutex;145 typedef void* PlatformReadWriteLock; // FIXME: Implement.146 typedef QT_PREPEND_NAMESPACE(QWaitCondition)* PlatformCondition;147 #elif OS(WINDOWS)148 struct PlatformMutex {149 CRITICAL_SECTION m_internalMutex;150 size_t m_recursionCount;151 };152 typedef void* PlatformReadWriteLock; // FIXME: Implement.153 struct PlatformCondition {154 size_t m_waitersGone;155 size_t m_waitersBlocked;156 size_t m_waitersToUnblock;157 HANDLE m_blockLock;158 HANDLE m_blockQueue;159 HANDLE m_unblockLock;160 161 bool timedWait(PlatformMutex&, DWORD durationMilliseconds);162 void signal(bool unblockAll);163 };164 #else165 typedef void* PlatformMutex;166 typedef void* PlatformReadWriteLock;167 typedef void* PlatformCondition;168 #endif169 170 class Mutex : public Noncopyable {171 public:172 Mutex();173 ~Mutex();174 175 void lock();176 bool tryLock();177 void unlock();178 179 public:180 PlatformMutex& impl() { return m_mutex; }181 private:182 PlatformMutex m_mutex;183 };184 185 typedef Locker<Mutex> MutexLocker;186 187 class ReadWriteLock : public Noncopyable {188 public:189 ReadWriteLock();190 ~ReadWriteLock();191 192 void readLock();193 bool tryReadLock();194 195 void writeLock();196 bool tryWriteLock();197 198 void unlock();199 200 private:201 PlatformReadWriteLock m_readWriteLock;202 };203 204 class ThreadCondition : public Noncopyable {205 public:206 ThreadCondition();207 ~ThreadCondition();208 209 void wait(Mutex& mutex);210 // Returns true if the condition was signaled before absoluteTime, false if the absoluteTime was reached or is in the past.211 // The absoluteTime is in seconds, starting on January 1, 1970. The time is assumed to use the same time zone as WTF::currentTime().212 bool timedWait(Mutex&, double absoluteTime);213 void signal();214 void broadcast();215 216 private:217 PlatformCondition m_condition;218 };219 220 #if OS(WINDOWS)221 #define WTF_USE_LOCKFREE_THREADSAFESHARED 1222 223 #if COMPILER(MINGW) || COMPILER(MSVC7) || OS(WINCE)224 inline int atomicIncrement(int* addend) { return InterlockedIncrement(reinterpret_cast<long*>(addend)); }225 inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast<long*>(addend)); }226 #else227 inline int atomicIncrement(int volatile* addend) { return InterlockedIncrement(reinterpret_cast<long volatile*>(addend)); }228 inline int atomicDecrement(int volatile* addend) { return InterlockedDecrement(reinterpret_cast<long volatile*>(addend)); }229 #endif230 231 #elif OS(DARWIN)232 #define WTF_USE_LOCKFREE_THREADSAFESHARED 1233 234 inline int atomicIncrement(int volatile* addend) { return OSAtomicIncrement32Barrier(const_cast<int*>(addend)); }235 inline int atomicDecrement(int volatile* addend) { return OSAtomicDecrement32Barrier(const_cast<int*>(addend)); }236 237 #elif OS(ANDROID)238 239 inline int atomicIncrement(int volatile* addend) { return android_atomic_inc(addend); }240 inline int atomicDecrement(int volatile* addend) { return android_atomic_dec(addend); }241 242 #elif COMPILER(GCC) && !CPU(SPARC64) && !OS(SYMBIAN) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc243 #define WTF_USE_LOCKFREE_THREADSAFESHARED 1244 245 inline int atomicIncrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, 1) + 1; }246 inline int atomicDecrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, -1) - 1; }247 248 #endif249 69 250 70 class ThreadSafeSharedBase : public Noncopyable { … … 322 142 }; 323 143 324 // This function must be called from the main thread. It is safe to call it repeatedly.325 // 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.326 void initializeThreading();327 328 void lockAtomicallyInitializedStaticMutex();329 void unlockAtomicallyInitializedStaticMutex();330 331 144 } // namespace WTF 332 145 333 using WTF::Mutex;334 using WTF::MutexLocker;335 using WTF::ThreadCondition;336 using WTF::ThreadIdentifier;337 146 using WTF::ThreadSafeShared; 338 147 339 #if USE(LOCKFREE_THREADSAFESHARED) 340 using WTF::atomicDecrement; 341 using WTF::atomicIncrement; 342 #endif 343 344 using WTF::createThread; 345 using WTF::currentThread; 346 using WTF::detachThread; 347 using WTF::waitForThreadCompletion; 348 349 #endif // Threading_h 148 #endif // ThreadSafeShared_h -
trunk/JavaScriptCore/wtf/Threading.h
r58179 r58206 1 1 /* 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.2 * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2007 Justin Haygood ([email protected]) 4 4 * … … 62 62 #include "Platform.h" 63 63 64 #if OS(WINCE) 65 #include <windows.h> 66 #endif 67 64 #include <stdint.h> 68 65 #include <wtf/Assertions.h> 66 #include <wtf/Atomics.h> 69 67 #include <wtf/Locker.h> 70 68 #include <wtf/MainThread.h> 71 69 #include <wtf/Noncopyable.h> 72 73 #if OS(WINDOWS) && !OS(WINCE) 74 #include <windows.h> 75 #elif OS(DARWIN) 76 #include <libkern/OSAtomic.h> 77 #elif OS(ANDROID) 78 #include <cutils/atomic.h> 79 #elif COMPILER(GCC) && !OS(SYMBIAN) 80 #if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) 81 #include <ext/atomicity.h> 82 #else 83 #include <bits/atomicity.h> 84 #endif 85 #endif 86 87 #if USE(PTHREADS) 88 #include <pthread.h> 89 #elif PLATFORM(GTK) 90 #include "GOwnPtr.h" 91 typedef struct _GMutex GMutex; 92 typedef struct _GCond GCond; 93 #endif 94 95 #if PLATFORM(QT) 96 #include <qglobal.h> 97 QT_BEGIN_NAMESPACE 98 class QMutex; 99 class QWaitCondition; 100 QT_END_NAMESPACE 101 #endif 102 103 #include <stdint.h> 70 #include <wtf/ThreadSafeShared.h> 71 #include <wtf/ThreadingPrimitives.h> 104 72 105 73 // For portability, we do not use thread-safe statics natively supported by some compilers (e.g. gcc). … … 129 97 void detachThread(ThreadIdentifier); 130 98 131 #if USE(PTHREADS)132 typedef pthread_mutex_t PlatformMutex;133 #if HAVE(PTHREAD_RWLOCK)134 typedef pthread_rwlock_t PlatformReadWriteLock;135 #else136 typedef void* PlatformReadWriteLock;137 #endif138 typedef pthread_cond_t PlatformCondition;139 #elif PLATFORM(GTK)140 typedef GOwnPtr<GMutex> PlatformMutex;141 typedef void* PlatformReadWriteLock; // FIXME: Implement.142 typedef GOwnPtr<GCond> PlatformCondition;143 #elif PLATFORM(QT)144 typedef QT_PREPEND_NAMESPACE(QMutex)* PlatformMutex;145 typedef void* PlatformReadWriteLock; // FIXME: Implement.146 typedef QT_PREPEND_NAMESPACE(QWaitCondition)* PlatformCondition;147 #elif OS(WINDOWS)148 struct PlatformMutex {149 CRITICAL_SECTION m_internalMutex;150 size_t m_recursionCount;151 };152 typedef void* PlatformReadWriteLock; // FIXME: Implement.153 struct PlatformCondition {154 size_t m_waitersGone;155 size_t m_waitersBlocked;156 size_t m_waitersToUnblock;157 HANDLE m_blockLock;158 HANDLE m_blockQueue;159 HANDLE m_unblockLock;160 161 bool timedWait(PlatformMutex&, DWORD durationMilliseconds);162 void signal(bool unblockAll);163 };164 #else165 typedef void* PlatformMutex;166 typedef void* PlatformReadWriteLock;167 typedef void* PlatformCondition;168 #endif169 170 class Mutex : public Noncopyable {171 public:172 Mutex();173 ~Mutex();174 175 void lock();176 bool tryLock();177 void unlock();178 179 public:180 PlatformMutex& impl() { return m_mutex; }181 private:182 PlatformMutex m_mutex;183 };184 185 typedef Locker<Mutex> MutexLocker;186 187 class ReadWriteLock : public Noncopyable {188 public:189 ReadWriteLock();190 ~ReadWriteLock();191 192 void readLock();193 bool tryReadLock();194 195 void writeLock();196 bool tryWriteLock();197 198 void unlock();199 200 private:201 PlatformReadWriteLock m_readWriteLock;202 };203 204 class ThreadCondition : public Noncopyable {205 public:206 ThreadCondition();207 ~ThreadCondition();208 209 void wait(Mutex& mutex);210 // Returns true if the condition was signaled before absoluteTime, false if the absoluteTime was reached or is in the past.211 // The absoluteTime is in seconds, starting on January 1, 1970. The time is assumed to use the same time zone as WTF::currentTime().212 bool timedWait(Mutex&, double absoluteTime);213 void signal();214 void broadcast();215 216 private:217 PlatformCondition m_condition;218 };219 220 #if OS(WINDOWS)221 #define WTF_USE_LOCKFREE_THREADSAFESHARED 1222 223 #if COMPILER(MINGW) || COMPILER(MSVC7) || OS(WINCE)224 inline int atomicIncrement(int* addend) { return InterlockedIncrement(reinterpret_cast<long*>(addend)); }225 inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast<long*>(addend)); }226 #else227 inline int atomicIncrement(int volatile* addend) { return InterlockedIncrement(reinterpret_cast<long volatile*>(addend)); }228 inline int atomicDecrement(int volatile* addend) { return InterlockedDecrement(reinterpret_cast<long volatile*>(addend)); }229 #endif230 231 #elif OS(DARWIN)232 #define WTF_USE_LOCKFREE_THREADSAFESHARED 1233 234 inline int atomicIncrement(int volatile* addend) { return OSAtomicIncrement32Barrier(const_cast<int*>(addend)); }235 inline int atomicDecrement(int volatile* addend) { return OSAtomicDecrement32Barrier(const_cast<int*>(addend)); }236 237 #elif OS(ANDROID)238 239 inline int atomicIncrement(int volatile* addend) { return android_atomic_inc(addend); }240 inline int atomicDecrement(int volatile* addend) { return android_atomic_dec(addend); }241 242 #elif COMPILER(GCC) && !CPU(SPARC64) && !OS(SYMBIAN) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc243 #define WTF_USE_LOCKFREE_THREADSAFESHARED 1244 245 inline int atomicIncrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, 1) + 1; }246 inline int atomicDecrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, -1) - 1; }247 248 #endif249 250 class ThreadSafeSharedBase : public Noncopyable {251 public:252 ThreadSafeSharedBase(int initialRefCount = 1)253 : m_refCount(initialRefCount)254 {255 }256 257 void ref()258 {259 #if USE(LOCKFREE_THREADSAFESHARED)260 atomicIncrement(&m_refCount);261 #else262 MutexLocker locker(m_mutex);263 ++m_refCount;264 #endif265 }266 267 bool hasOneRef()268 {269 return refCount() == 1;270 }271 272 int refCount() const273 {274 #if !USE(LOCKFREE_THREADSAFESHARED)275 MutexLocker locker(m_mutex);276 #endif277 return static_cast<int const volatile &>(m_refCount);278 }279 280 protected:281 // Returns whether the pointer should be freed or not.282 bool derefBase()283 {284 #if USE(LOCKFREE_THREADSAFESHARED)285 if (atomicDecrement(&m_refCount) <= 0)286 return true;287 #else288 int refCount;289 {290 MutexLocker locker(m_mutex);291 --m_refCount;292 refCount = m_refCount;293 }294 if (refCount <= 0)295 return true;296 #endif297 return false;298 }299 300 private:301 template<class T>302 friend class CrossThreadRefCounted;303 304 int m_refCount;305 #if !USE(LOCKFREE_THREADSAFESHARED)306 mutable Mutex m_mutex;307 #endif308 };309 310 template<class T> class ThreadSafeShared : public ThreadSafeSharedBase {311 public:312 ThreadSafeShared(int initialRefCount = 1)313 : ThreadSafeSharedBase(initialRefCount)314 {315 }316 317 void deref()318 {319 if (derefBase())320 delete static_cast<T*>(this);321 }322 };323 324 99 // This function must be called from the main thread. It is safe to call it repeatedly. 325 100 // 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. … … 331 106 } // namespace WTF 332 107 333 using WTF::Mutex;334 using WTF::MutexLocker;335 using WTF::ThreadCondition;336 108 using WTF::ThreadIdentifier; 337 using WTF::ThreadSafeShared;338 339 #if USE(LOCKFREE_THREADSAFESHARED)340 using WTF::atomicDecrement;341 using WTF::atomicIncrement;342 #endif343 344 109 using WTF::createThread; 345 110 using WTF::currentThread; -
trunk/JavaScriptCore/wtf/ThreadingPrimitives.h
r58179 r58206 1 1 /* 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.2 * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2007 Justin Haygood ([email protected]) 4 4 * … … 27 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 28 * 29 *30 * Note: The implementations of InterlockedIncrement and InterlockedDecrement are based31 * on atomic_increment and atomic_exchange_and_add from the Boost C++ Library. The license32 * is virtually identical to the Apple license above but is included here for completeness.33 *34 * Boost Software License - Version 1.0 - August 17th, 200335 *36 * Permission is hereby granted, free of charge, to any person or organization37 * obtaining a copy of the software and accompanying documentation covered by38 * this license (the "Software") to use, reproduce, display, distribute,39 * execute, and transmit the Software, and to prepare derivative works of the40 * Software, and to permit third-parties to whom the Software is furnished to41 * do so, all subject to the following:42 *43 * The copyright notices in the Software and this entire statement, including44 * the above license grant, this restriction and the following disclaimer,45 * must be included in all copies of the Software, in whole or in part, and46 * all derivative works of the Software, unless such copies or derivative47 * works are solely in the form of machine-executable object code generated by48 * a source language processor.49 *50 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR51 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,52 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT53 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE54 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,55 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER56 * DEALINGS IN THE SOFTWARE.57 29 */ 58 30 59 #ifndef Threading _h60 #define Threading _h31 #ifndef ThreadingPrimitives_h 32 #define ThreadingPrimitives_h 61 33 62 34 #include "Platform.h" 63 35 64 #if OS(WINCE)65 #include <windows.h>66 #endif67 68 36 #include <wtf/Assertions.h> 69 37 #include <wtf/Locker.h> 70 #include <wtf/MainThread.h>71 38 #include <wtf/Noncopyable.h> 72 39 73 #if OS(WINDOWS) && !OS(WINCE)40 #if OS(WINDOWS) 74 41 #include <windows.h> 75 #elif OS(DARWIN)76 #include <libkern/OSAtomic.h>77 #elif OS(ANDROID)78 #include <cutils/atomic.h>79 #elif COMPILER(GCC) && !OS(SYMBIAN)80 #if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2))81 #include <ext/atomicity.h>82 #else83 #include <bits/atomicity.h>84 #endif85 42 #endif 86 43 … … 101 58 #endif 102 59 103 #include <stdint.h>104 105 // For portability, we do not use thread-safe statics natively supported by some compilers (e.g. gcc).106 #define AtomicallyInitializedStatic(T, name) \107 WTF::lockAtomicallyInitializedStaticMutex(); \108 static T name; \109 WTF::unlockAtomicallyInitializedStaticMutex();110 111 60 namespace WTF { 112 113 typedef uint32_t ThreadIdentifier;114 typedef void* (*ThreadFunction)(void* argument);115 116 // Returns 0 if thread creation failed.117 // The thread name must be a literal since on some platforms it's passed in to the thread.118 ThreadIdentifier createThread(ThreadFunction, void*, const char* threadName);119 120 // Internal platform-specific createThread implementation.121 ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char* threadName);122 123 // Called in the thread during initialization.124 // Helpful for platforms where the thread name must be set from within the thread.125 void initializeCurrentThreadInternal(const char* threadName);126 127 ThreadIdentifier currentThread();128 int waitForThreadCompletion(ThreadIdentifier, void**);129 void detachThread(ThreadIdentifier);130 61 131 62 #if USE(PTHREADS) … … 218 149 }; 219 150 220 #if OS(WINDOWS)221 #define WTF_USE_LOCKFREE_THREADSAFESHARED 1222 223 #if COMPILER(MINGW) || COMPILER(MSVC7) || OS(WINCE)224 inline int atomicIncrement(int* addend) { return InterlockedIncrement(reinterpret_cast<long*>(addend)); }225 inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast<long*>(addend)); }226 #else227 inline int atomicIncrement(int volatile* addend) { return InterlockedIncrement(reinterpret_cast<long volatile*>(addend)); }228 inline int atomicDecrement(int volatile* addend) { return InterlockedDecrement(reinterpret_cast<long volatile*>(addend)); }229 #endif230 231 #elif OS(DARWIN)232 #define WTF_USE_LOCKFREE_THREADSAFESHARED 1233 234 inline int atomicIncrement(int volatile* addend) { return OSAtomicIncrement32Barrier(const_cast<int*>(addend)); }235 inline int atomicDecrement(int volatile* addend) { return OSAtomicDecrement32Barrier(const_cast<int*>(addend)); }236 237 #elif OS(ANDROID)238 239 inline int atomicIncrement(int volatile* addend) { return android_atomic_inc(addend); }240 inline int atomicDecrement(int volatile* addend) { return android_atomic_dec(addend); }241 242 #elif COMPILER(GCC) && !CPU(SPARC64) && !OS(SYMBIAN) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc243 #define WTF_USE_LOCKFREE_THREADSAFESHARED 1244 245 inline int atomicIncrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, 1) + 1; }246 inline int atomicDecrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, -1) - 1; }247 248 #endif249 250 class ThreadSafeSharedBase : public Noncopyable {251 public:252 ThreadSafeSharedBase(int initialRefCount = 1)253 : m_refCount(initialRefCount)254 {255 }256 257 void ref()258 {259 #if USE(LOCKFREE_THREADSAFESHARED)260 atomicIncrement(&m_refCount);261 #else262 MutexLocker locker(m_mutex);263 ++m_refCount;264 #endif265 }266 267 bool hasOneRef()268 {269 return refCount() == 1;270 }271 272 int refCount() const273 {274 #if !USE(LOCKFREE_THREADSAFESHARED)275 MutexLocker locker(m_mutex);276 #endif277 return static_cast<int const volatile &>(m_refCount);278 }279 280 protected:281 // Returns whether the pointer should be freed or not.282 bool derefBase()283 {284 #if USE(LOCKFREE_THREADSAFESHARED)285 if (atomicDecrement(&m_refCount) <= 0)286 return true;287 #else288 int refCount;289 {290 MutexLocker locker(m_mutex);291 --m_refCount;292 refCount = m_refCount;293 }294 if (refCount <= 0)295 return true;296 #endif297 return false;298 }299 300 private:301 template<class T>302 friend class CrossThreadRefCounted;303 304 int m_refCount;305 #if !USE(LOCKFREE_THREADSAFESHARED)306 mutable Mutex m_mutex;307 #endif308 };309 310 template<class T> class ThreadSafeShared : public ThreadSafeSharedBase {311 public:312 ThreadSafeShared(int initialRefCount = 1)313 : ThreadSafeSharedBase(initialRefCount)314 {315 }316 317 void deref()318 {319 if (derefBase())320 delete static_cast<T*>(this);321 }322 };323 324 // This function must be called from the main thread. It is safe to call it repeatedly.325 // 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.326 void initializeThreading();327 328 void lockAtomicallyInitializedStaticMutex();329 void unlockAtomicallyInitializedStaticMutex();330 331 151 } // namespace WTF 332 152 … … 334 154 using WTF::MutexLocker; 335 155 using WTF::ThreadCondition; 336 using WTF::ThreadIdentifier;337 using WTF::ThreadSafeShared;338 156 339 #if USE(LOCKFREE_THREADSAFESHARED) 340 using WTF::atomicDecrement; 341 using WTF::atomicIncrement; 342 #endif 343 344 using WTF::createThread; 345 using WTF::currentThread; 346 using WTF::detachThread; 347 using WTF::waitForThreadCompletion; 348 349 #endif // Threading_h 157 #endif // ThreadingPrimitives_h
Note:
See TracChangeset
for help on using the changeset viewer.