source: webkit/trunk/JavaScriptCore/wtf/ThreadingPthreads.cpp@ 31048

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

Reviewed by eseidel. Landed by eseidel

  • pcre/pcre_exec.cpp: Fix misnamed variable, allowing -DDEBUG build to succeed.
  • wtf/ThreadingPthreads.cpp: #include <sys/time.h> for gettimeofday in non-pch build.
  • Property svn:eol-style set to native
File size: 6.0 KB
Line 
1/*
2 * Copyright (C) 2007 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#include "config.h"
30#include "Threading.h"
31
32#include <wtf/HashMap.h>
33
34#include <errno.h>
35#include <sys/time.h>
36
37namespace WTF {
38
39Mutex* atomicallyInitializedStaticMutex;
40
41static Mutex& threadMapMutex()
42{
43 static Mutex mutex;
44 return mutex;
45}
46
47static HashMap<ThreadIdentifier, pthread_t>& threadMap()
48{
49 static HashMap<ThreadIdentifier, pthread_t> map;
50 return map;
51}
52
53static ThreadIdentifier establishIdentifierForPthreadHandle(pthread_t& pthreadHandle)
54{
55 MutexLocker locker(threadMapMutex());
56
57 static ThreadIdentifier identifierCount = 1;
58
59 threadMap().add(identifierCount, pthreadHandle);
60
61 return identifierCount++;
62}
63
64static ThreadIdentifier identifierByPthreadHandle(const pthread_t& pthreadHandle)
65{
66 MutexLocker locker(threadMapMutex());
67
68 HashMap<ThreadIdentifier, pthread_t>::iterator i = threadMap().begin();
69 for (; i != threadMap().end(); ++i) {
70 if (pthread_equal(i->second, pthreadHandle))
71 return i->first;
72 }
73
74 return 0;
75}
76
77static pthread_t pthreadHandleForIdentifier(ThreadIdentifier id)
78{
79 MutexLocker locker(threadMapMutex());
80
81 return threadMap().get(id);
82}
83
84static void clearPthreadHandleForIdentifier(ThreadIdentifier id)
85{
86 MutexLocker locker(threadMapMutex());
87
88 ASSERT(threadMap().contains(id));
89
90 threadMap().remove(id);
91}
92
93ThreadIdentifier createThread(ThreadFunction entryPoint, void* data)
94{
95 pthread_t threadHandle;
96 if (pthread_create(&threadHandle, NULL, entryPoint, data)) {
97 LOG_ERROR("Failed to create pthread at entry point %p with data %p", entryPoint, data);
98 return 0;
99 }
100
101 ThreadIdentifier threadID = establishIdentifierForPthreadHandle(threadHandle);
102 return threadID;
103}
104
105int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
106{
107 ASSERT(threadID);
108
109 pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID);
110
111 int joinResult = pthread_join(pthreadHandle, result);
112 if (joinResult == EDEADLK)
113 LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID);
114
115 clearPthreadHandleForIdentifier(threadID);
116 return joinResult;
117}
118
119void detachThread(ThreadIdentifier threadID)
120{
121 ASSERT(threadID);
122
123 pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID);
124
125 pthread_detach(pthreadHandle);
126
127 clearPthreadHandleForIdentifier(threadID);
128}
129
130ThreadIdentifier currentThread()
131{
132 pthread_t currentThread = pthread_self();
133 if (ThreadIdentifier id = identifierByPthreadHandle(currentThread))
134 return id;
135 return establishIdentifierForPthreadHandle(currentThread);
136}
137
138Mutex::Mutex()
139{
140 pthread_mutex_init(&m_mutex, NULL);
141}
142
143Mutex::~Mutex()
144{
145 pthread_mutex_destroy(&m_mutex);
146}
147
148void Mutex::lock()
149{
150 if (pthread_mutex_lock(&m_mutex) != 0)
151 ASSERT(false);
152}
153
154bool Mutex::tryLock()
155{
156 int result = pthread_mutex_trylock(&m_mutex);
157
158 if (result == 0)
159 return true;
160 else if (result == EBUSY)
161 return false;
162
163 ASSERT(false);
164 return false;
165}
166
167void Mutex::unlock()
168{
169 if (pthread_mutex_unlock(&m_mutex) != 0)
170 ASSERT(false);
171}
172
173ThreadCondition::ThreadCondition()
174{
175 pthread_cond_init(&m_condition, NULL);
176}
177
178ThreadCondition::~ThreadCondition()
179{
180 pthread_cond_destroy(&m_condition);
181}
182
183void ThreadCondition::wait(Mutex& mutex)
184{
185 if (pthread_cond_wait(&m_condition, &mutex.impl()) != 0)
186 ASSERT(false);
187}
188
189bool ThreadCondition::timedWait(Mutex& mutex, double interval)
190{
191 if (interval < 0.0) {
192 wait(mutex);
193 return true;
194 }
195
196 int intervalSeconds = static_cast<int>(interval);
197 int intervalMicroseconds = static_cast<int>((interval - intervalSeconds) * 1000000.0);
198
199 // Current time comes in sec/microsec
200 timeval currentTime;
201 gettimeofday(&currentTime, NULL);
202
203 // Target time comes in sec/nanosec
204 timespec targetTime;
205 targetTime.tv_sec = currentTime.tv_sec + intervalSeconds;
206 targetTime.tv_nsec = (currentTime.tv_usec + intervalMicroseconds) * 1000;
207 if (targetTime.tv_nsec > 1000000000) {
208 targetTime.tv_nsec -= 1000000000;
209 targetTime.tv_sec++;
210 }
211
212 return pthread_cond_timedwait(&m_condition, &mutex.impl(), &targetTime) == 0;
213}
214
215void ThreadCondition::signal()
216{
217 if (pthread_cond_signal(&m_condition) != 0)
218 ASSERT(false);
219}
220
221void ThreadCondition::broadcast()
222{
223 if (pthread_cond_broadcast(&m_condition) != 0)
224 ASSERT(false);
225}
226
227} // namespace WTF
Note: See TracBrowser for help on using the repository browser.