Changeset 58206 in webkit for trunk/JavaScriptCore/wtf/ThreadingPrimitives.h
- Timestamp:
- Apr 23, 2010, 6:07:37 PM (15 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
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.