Changeset 58206 in webkit for trunk/JavaScriptCore/wtf/Threading.h
- Timestamp:
- Apr 23, 2010, 6:07:37 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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;
Note:
See TracChangeset
for help on using the changeset viewer.