source: webkit/trunk/JavaScriptCore/wtf/Threading.h@ 36124

Last change on this file since 36124 was 35487, checked in by [email protected], 17 years ago

Second attempt at Windows/wx build fix. Instead of avoiding inclusion of windows.h, use defines, etc. to avoid conflicts in each affected file.

  • Property svn:eol-style set to native
File size: 8.3 KB
Line 
1/*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2007 Justin Haygood ([email protected])
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 *
30 * Note: The implementations of InterlockedIncrement and InterlockedDecrement are based
31 * on atomic_increment and atomic_exchange_and_add from the Boost C++ Library. The license
32 * is virtually identical to the Apple license above but is included here for completeness.
33 *
34 * Boost Software License - Version 1.0 - August 17th, 2003
35 *
36 * Permission is hereby granted, free of charge, to any person or organization
37 * obtaining a copy of the software and accompanying documentation covered by
38 * this license (the "Software") to use, reproduce, display, distribute,
39 * execute, and transmit the Software, and to prepare derivative works of the
40 * Software, and to permit third-parties to whom the Software is furnished to
41 * do so, all subject to the following:
42 *
43 * The copyright notices in the Software and this entire statement, including
44 * 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, and
46 * all derivative works of the Software, unless such copies or derivative
47 * works are solely in the form of machine-executable object code generated by
48 * a source language processor.
49 *
50 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
51 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
52 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
53 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
54 * 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 OTHER
56 * DEALINGS IN THE SOFTWARE.
57 */
58
59#ifndef Threading_h
60#define Threading_h
61
62#include <wtf/Assertions.h>
63#include <wtf/Locker.h>
64#include <wtf/Noncopyable.h>
65
66#if PLATFORM(WIN_OS)
67#include <windows.h>
68#elif PLATFORM(DARWIN)
69#include <libkern/OSAtomic.h>
70#elif COMPILER(GCC)
71#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2))
72#include <ext/atomicity.h>
73#else
74#include <bits/atomicity.h>
75#endif
76#endif
77
78#if USE(PTHREADS)
79#include <pthread.h>
80#endif
81
82#if PLATFORM(GTK)
83typedef struct _GMutex GMutex;
84typedef struct _GCond GCond;
85#endif
86
87#if PLATFORM(QT)
88class QMutex;
89class QWaitCondition;
90#endif
91
92#include <stdint.h>
93
94// For portability, we do not use thread-safe statics natively supported by some compilers (e.g. gcc).
95#define AtomicallyInitializedStatic(T, name) \
96 WTF::atomicallyInitializedStaticMutex->lock(); \
97 static T name; \
98 WTF::atomicallyInitializedStaticMutex->unlock();
99
100namespace WTF {
101
102typedef uint32_t ThreadIdentifier;
103typedef void* (*ThreadFunction)(void* argument);
104
105// Returns 0 if thread creation failed
106ThreadIdentifier createThread(ThreadFunction, void*, const char* threadName);
107
108ThreadIdentifier currentThread();
109bool isMainThread();
110int waitForThreadCompletion(ThreadIdentifier, void**);
111void detachThread(ThreadIdentifier);
112
113#if USE(PTHREADS)
114typedef pthread_mutex_t PlatformMutex;
115typedef pthread_cond_t PlatformCondition;
116#elif PLATFORM(GTK)
117typedef GMutex* PlatformMutex;
118typedef GCond* PlatformCondition;
119#elif PLATFORM(QT)
120typedef QMutex* PlatformMutex;
121typedef QWaitCondition* PlatformCondition;
122#elif PLATFORM(WIN_OS)
123struct PlatformMutex {
124 CRITICAL_SECTION m_internalMutex;
125 size_t m_recursionCount;
126};
127struct PlatformCondition {
128 size_t m_timedOut;
129 size_t m_blocked;
130 size_t m_waitingForRemoval;
131 HANDLE m_gate;
132 HANDLE m_queue;
133 HANDLE m_mutex;
134};
135#else
136typedef void* PlatformMutex;
137typedef void* PlatformCondition;
138#endif
139
140class Mutex : Noncopyable {
141public:
142 Mutex();
143 ~Mutex();
144
145 void lock();
146 bool tryLock();
147 void unlock();
148
149public:
150 PlatformMutex& impl() { return m_mutex; }
151private:
152 PlatformMutex m_mutex;
153};
154
155typedef Locker<Mutex> MutexLocker;
156
157class ThreadCondition : Noncopyable {
158public:
159 ThreadCondition();
160 ~ThreadCondition();
161
162 void wait(Mutex& mutex);
163 // Returns true if the condition was signaled before the timeout, false if the timeout was reached
164 bool timedWait(Mutex&, double interval);
165 void signal();
166 void broadcast();
167
168private:
169 PlatformCondition m_condition;
170};
171
172#if PLATFORM(WIN_OS)
173#define WTF_USE_LOCKFREE_THREADSAFESHARED 1
174
175#if COMPILER(MINGW) || COMPILER(MSVC7)
176inline void atomicIncrement(int* addend) { InterlockedIncrement(reinterpret_cast<long*>(addend)); }
177inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast<long*>(addend)); }
178#else
179inline void atomicIncrement(int volatile* addend) { InterlockedIncrement(reinterpret_cast<long volatile*>(addend)); }
180inline int atomicDecrement(int volatile* addend) { return InterlockedDecrement(reinterpret_cast<long volatile*>(addend)); }
181#endif
182
183#elif PLATFORM(DARWIN)
184#define WTF_USE_LOCKFREE_THREADSAFESHARED 1
185
186inline void atomicIncrement(int volatile* addend) { OSAtomicIncrement32Barrier(const_cast<int*>(addend)); }
187inline int atomicDecrement(int volatile* addend) { return OSAtomicDecrement32Barrier(const_cast<int*>(addend)); }
188
189#elif COMPILER(GCC)
190#define WTF_USE_LOCKFREE_THREADSAFESHARED 1
191
192inline void atomicIncrement(int volatile* addend) { __gnu_cxx::__atomic_add(addend, 1); }
193inline int atomicDecrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, -1) - 1; }
194
195#endif
196
197template<class T> class ThreadSafeShared : Noncopyable {
198public:
199 ThreadSafeShared(int initialRefCount = 1)
200 : m_refCount(initialRefCount)
201 {
202 }
203
204 void ref()
205 {
206#if USE(LOCKFREE_THREADSAFESHARED)
207 atomicIncrement(&m_refCount);
208#else
209 MutexLocker locker(m_mutex);
210 ++m_refCount;
211#endif
212 }
213
214 void deref()
215 {
216#if USE(LOCKFREE_THREADSAFESHARED)
217 if (atomicDecrement(&m_refCount) <= 0)
218#else
219 {
220 MutexLocker locker(m_mutex);
221 --m_refCount;
222 }
223 if (m_refCount <= 0)
224#endif
225 delete static_cast<T*>(this);
226 }
227
228 bool hasOneRef()
229 {
230 return refCount() == 1;
231 }
232
233 int refCount() const
234 {
235#if !USE(LOCKFREE_THREADSAFESHARED)
236 MutexLocker locker(m_mutex);
237#endif
238 return static_cast<int const volatile &>(m_refCount);
239 }
240
241private:
242 int m_refCount;
243#if !USE(LOCKFREE_THREADSAFESHARED)
244 mutable Mutex m_mutex;
245#endif
246};
247
248// This function must be called from the main thread. It is safe to call it repeatedly.
249// 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.
250void initializeThreading();
251
252extern Mutex* atomicallyInitializedStaticMutex;
253
254} // namespace WTF
255
256using WTF::Mutex;
257using WTF::MutexLocker;
258using WTF::ThreadCondition;
259using WTF::ThreadIdentifier;
260using WTF::ThreadSafeShared;
261
262using WTF::createThread;
263using WTF::currentThread;
264using WTF::isMainThread;
265using WTF::detachThread;
266using WTF::waitForThreadCompletion;
267
268#endif // Threading_h
Note: See TracBrowser for help on using the repository browser.