]> git.saurik.com Git - apple/javascriptcore.git/blame - wtf/gtk/ThreadingGtk.cpp
JavaScriptCore-554.1.tar.gz
[apple/javascriptcore.git] / wtf / gtk / ThreadingGtk.cpp
CommitLineData
9dae56ea
A
1/*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
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 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#include "config.h"
31#include "Threading.h"
32
33#if !USE(PTHREADS)
34
35#include "CurrentTime.h"
36#include "HashMap.h"
37#include "MainThread.h"
38#include "RandomNumberSeed.h"
39
40#include <glib.h>
41#include <limits.h>
42
43namespace WTF {
44
45static Mutex* atomicallyInitializedStaticMutex;
46
47static ThreadIdentifier mainThreadIdentifier;
48
49static Mutex& threadMapMutex()
50{
51 static Mutex mutex;
52 return mutex;
53}
54
55void initializeThreading()
56{
57 if (!g_thread_supported())
58 g_thread_init(NULL);
59 ASSERT(g_thread_supported());
60
61 if (!atomicallyInitializedStaticMutex) {
62 atomicallyInitializedStaticMutex = new Mutex;
63 threadMapMutex();
64 initializeRandomNumberGenerator();
65 mainThreadIdentifier = currentThread();
66 initializeMainThread();
67 }
68}
69
70void lockAtomicallyInitializedStaticMutex()
71{
72 ASSERT(atomicallyInitializedStaticMutex);
73 atomicallyInitializedStaticMutex->lock();
74}
75
76void unlockAtomicallyInitializedStaticMutex()
77{
78 atomicallyInitializedStaticMutex->unlock();
79}
80
81static HashMap<ThreadIdentifier, GThread*>& threadMap()
82{
83 static HashMap<ThreadIdentifier, GThread*> map;
84 return map;
85}
86
87static ThreadIdentifier identifierByGthreadHandle(GThread*& thread)
88{
89 MutexLocker locker(threadMapMutex());
90
91 HashMap<ThreadIdentifier, GThread*>::iterator i = threadMap().begin();
92 for (; i != threadMap().end(); ++i) {
93 if (i->second == thread)
94 return i->first;
95 }
96
97 return 0;
98}
99
100static ThreadIdentifier establishIdentifierForThread(GThread*& thread)
101{
102 ASSERT(!identifierByGthreadHandle(thread));
103
104 MutexLocker locker(threadMapMutex());
105
106 static ThreadIdentifier identifierCount = 1;
107
108 threadMap().add(identifierCount, thread);
109
110 return identifierCount++;
111}
112
113static GThread* threadForIdentifier(ThreadIdentifier id)
114{
115 MutexLocker locker(threadMapMutex());
116
117 return threadMap().get(id);
118}
119
120static void clearThreadForIdentifier(ThreadIdentifier id)
121{
122 MutexLocker locker(threadMapMutex());
123
124 ASSERT(threadMap().contains(id));
125
126 threadMap().remove(id);
127}
128
129ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
130{
131 GThread* thread;
132 if (!(thread = g_thread_create(entryPoint, data, TRUE, 0))) {
133 LOG_ERROR("Failed to create thread at entry point %p with data %p", entryPoint, data);
134 return 0;
135 }
136
137 ThreadIdentifier threadID = establishIdentifierForThread(thread);
138 return threadID;
139}
140
ba379fdc
A
141void setThreadNameInternal(const char*)
142{
143}
144
9dae56ea
A
145int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
146{
147 ASSERT(threadID);
148
149 GThread* thread = threadForIdentifier(threadID);
150
151 void* joinResult = g_thread_join(thread);
152 if (result)
153 *result = joinResult;
154
155 clearThreadForIdentifier(threadID);
156 return 0;
157}
158
159void detachThread(ThreadIdentifier)
160{
161}
162
163ThreadIdentifier currentThread()
164{
165 GThread* currentThread = g_thread_self();
166 if (ThreadIdentifier id = identifierByGthreadHandle(currentThread))
167 return id;
168 return establishIdentifierForThread(currentThread);
169}
170
171bool isMainThread()
172{
173 return currentThread() == mainThreadIdentifier;
174}
175
176Mutex::Mutex()
177 : m_mutex(g_mutex_new())
178{
179}
180
181Mutex::~Mutex()
182{
183}
184
185void Mutex::lock()
186{
187 g_mutex_lock(m_mutex.get());
188}
189
190bool Mutex::tryLock()
191{
192 return g_mutex_trylock(m_mutex.get());
193}
194
195void Mutex::unlock()
196{
197 g_mutex_unlock(m_mutex.get());
198}
199
200ThreadCondition::ThreadCondition()
201 : m_condition(g_cond_new())
202{
203}
204
205ThreadCondition::~ThreadCondition()
206{
207}
208
209void ThreadCondition::wait(Mutex& mutex)
210{
211 g_cond_wait(m_condition.get(), mutex.impl().get());
212}
213
214bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
215{
216 // Time is in the past - return right away.
217 if (absoluteTime < currentTime())
218 return false;
219
220 // Time is too far in the future for g_cond_timed_wait - wait forever.
221 if (absoluteTime > INT_MAX) {
222 wait(mutex);
223 return true;
224 }
225
226 int timeSeconds = static_cast<int>(absoluteTime);
227 int timeMicroseconds = static_cast<int>((absoluteTime - timeSeconds) * 1000000.0);
228
229 GTimeVal targetTime;
230 targetTime.tv_sec = timeSeconds;
231 targetTime.tv_usec = timeMicroseconds;
232
233 return g_cond_timed_wait(m_condition.get(), mutex.impl().get(), &targetTime);
234}
235
236void ThreadCondition::signal()
237{
238 g_cond_signal(m_condition.get());
239}
240
241void ThreadCondition::broadcast()
242{
243 g_cond_broadcast(m_condition.get());
244}
245
246
247}
248
249#endif // !USE(PTHREADS)