Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: third_party/WebKit/Source/wtf/ThreadingPthreads.cpp

Issue 2767153004: Move files in wtf/ to platform/wtf/ (Part 12). (Closed)
Patch Set: Rebase. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
4 * Copyright (C) 2011 Research In Motion Limited. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "wtf/Threading.h"
32
33 #if OS(POSIX)
34
35 #include "wtf/CurrentTime.h"
36 #include "wtf/DateMath.h"
37 #include "wtf/HashMap.h"
38 #include "wtf/StdLibExtras.h"
39 #include "wtf/ThreadSpecific.h"
40 #include "wtf/ThreadingPrimitives.h"
41 #include "wtf/WTFThreadData.h"
42 #include "wtf/dtoa/double-conversion.h"
43 #include <errno.h>
44 #include <limits.h>
45 #include <sched.h>
46 #include <sys/time.h>
47
48 #if OS(MACOSX)
49 #include <objc/objc-auto.h>
50 #endif
51
52 #if OS(LINUX)
53 #include <sys/syscall.h>
54 #endif
55
56 #if OS(LINUX) || OS(ANDROID)
57 #include <unistd.h>
58 #endif
59
60 namespace WTF {
61
62 namespace internal {
63
64 ThreadIdentifier currentThreadSyscall() {
65 #if OS(MACOSX)
66 return pthread_mach_thread_np(pthread_self());
67 #elif OS(LINUX)
68 return syscall(__NR_gettid);
69 #elif OS(ANDROID)
70 return gettid();
71 #else
72 return reinterpret_cast<uintptr_t>(pthread_self());
73 #endif
74 }
75
76 } // namespace internal
77
78 void initializeThreading() {
79 // This should only be called once.
80 WTFThreadData::initialize();
81
82 initializeDates();
83 // Force initialization of static DoubleToStringConverter converter variable
84 // inside EcmaScriptConverter function while we are in single thread mode.
85 double_conversion::DoubleToStringConverter::EcmaScriptConverter();
86 }
87
88 namespace {
89 ThreadSpecificKey s_currentThreadKey;
90 bool s_currentThreadKeyInitialized = false;
91 } // namespace
92
93 void initializeCurrentThread() {
94 DCHECK(!s_currentThreadKeyInitialized);
95 threadSpecificKeyCreate(&s_currentThreadKey, [](void*) {});
96 s_currentThreadKeyInitialized = true;
97 }
98
99 ThreadIdentifier currentThread() {
100 // This doesn't use WTF::ThreadSpecific (e.g. WTFThreadData) because
101 // ThreadSpecific now depends on currentThread. It is necessary to avoid this
102 // or a similar loop:
103 //
104 // currentThread
105 // -> wtfThreadData
106 // -> ThreadSpecific::operator*
107 // -> isMainThread
108 // -> currentThread
109 static_assert(sizeof(ThreadIdentifier) <= sizeof(void*),
110 "ThreadIdentifier must fit in a void*.");
111 DCHECK(s_currentThreadKeyInitialized);
112 void* value = threadSpecificGet(s_currentThreadKey);
113 if (UNLIKELY(!value)) {
114 value = reinterpret_cast<void*>(
115 static_cast<intptr_t>(internal::currentThreadSyscall()));
116 DCHECK(value);
117 threadSpecificSet(s_currentThreadKey, value);
118 }
119 return reinterpret_cast<intptr_t>(threadSpecificGet(s_currentThreadKey));
120 }
121
122 MutexBase::MutexBase(bool recursive) {
123 pthread_mutexattr_t attr;
124 pthread_mutexattr_init(&attr);
125 pthread_mutexattr_settype(
126 &attr, recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL);
127
128 int result = pthread_mutex_init(&m_mutex.m_internalMutex, &attr);
129 DCHECK_EQ(result, 0);
130 #if DCHECK_IS_ON()
131 m_mutex.m_recursionCount = 0;
132 #endif
133
134 pthread_mutexattr_destroy(&attr);
135 }
136
137 MutexBase::~MutexBase() {
138 int result = pthread_mutex_destroy(&m_mutex.m_internalMutex);
139 DCHECK_EQ(result, 0);
140 }
141
142 void MutexBase::lock() {
143 int result = pthread_mutex_lock(&m_mutex.m_internalMutex);
144 DCHECK_EQ(result, 0);
145 #if DCHECK_IS_ON()
146 ++m_mutex.m_recursionCount;
147 #endif
148 }
149
150 void MutexBase::unlock() {
151 #if DCHECK_IS_ON()
152 DCHECK(m_mutex.m_recursionCount);
153 --m_mutex.m_recursionCount;
154 #endif
155 int result = pthread_mutex_unlock(&m_mutex.m_internalMutex);
156 DCHECK_EQ(result, 0);
157 }
158
159 // There is a separate tryLock implementation for the Mutex and the
160 // RecursiveMutex since on Windows we need to manually check if tryLock should
161 // succeed or not for the non-recursive mutex. On Linux the two implementations
162 // are equal except we can assert the recursion count is always zero for the
163 // non-recursive mutex.
164 bool Mutex::tryLock() {
165 int result = pthread_mutex_trylock(&m_mutex.m_internalMutex);
166 if (result == 0) {
167 #if DCHECK_IS_ON()
168 // The Mutex class is not recursive, so the recursionCount should be
169 // zero after getting the lock.
170 DCHECK(!m_mutex.m_recursionCount);
171 ++m_mutex.m_recursionCount;
172 #endif
173 return true;
174 }
175 if (result == EBUSY)
176 return false;
177
178 NOTREACHED();
179 return false;
180 }
181
182 bool RecursiveMutex::tryLock() {
183 int result = pthread_mutex_trylock(&m_mutex.m_internalMutex);
184 if (result == 0) {
185 #if DCHECK_IS_ON()
186 ++m_mutex.m_recursionCount;
187 #endif
188 return true;
189 }
190 if (result == EBUSY)
191 return false;
192
193 NOTREACHED();
194 return false;
195 }
196
197 ThreadCondition::ThreadCondition() {
198 pthread_cond_init(&m_condition, nullptr);
199 }
200
201 ThreadCondition::~ThreadCondition() {
202 pthread_cond_destroy(&m_condition);
203 }
204
205 void ThreadCondition::wait(MutexBase& mutex) {
206 PlatformMutex& platformMutex = mutex.impl();
207 int result = pthread_cond_wait(&m_condition, &platformMutex.m_internalMutex);
208 DCHECK_EQ(result, 0);
209 #if DCHECK_IS_ON()
210 ++platformMutex.m_recursionCount;
211 #endif
212 }
213
214 bool ThreadCondition::timedWait(MutexBase& mutex, double absoluteTime) {
215 if (absoluteTime < currentTime())
216 return false;
217
218 if (absoluteTime > INT_MAX) {
219 wait(mutex);
220 return true;
221 }
222
223 int timeSeconds = static_cast<int>(absoluteTime);
224 int timeNanoseconds = static_cast<int>((absoluteTime - timeSeconds) * 1E9);
225
226 timespec targetTime;
227 targetTime.tv_sec = timeSeconds;
228 targetTime.tv_nsec = timeNanoseconds;
229
230 PlatformMutex& platformMutex = mutex.impl();
231 int result = pthread_cond_timedwait(
232 &m_condition, &platformMutex.m_internalMutex, &targetTime);
233 #if DCHECK_IS_ON()
234 ++platformMutex.m_recursionCount;
235 #endif
236 return result == 0;
237 }
238
239 void ThreadCondition::signal() {
240 int result = pthread_cond_signal(&m_condition);
241 DCHECK_EQ(result, 0);
242 }
243
244 void ThreadCondition::broadcast() {
245 int result = pthread_cond_broadcast(&m_condition);
246 DCHECK_EQ(result, 0);
247 }
248
249 #if DCHECK_IS_ON()
250 static bool s_threadCreated = false;
251
252 bool isBeforeThreadCreated() {
253 return !s_threadCreated;
254 }
255
256 void willCreateThread() {
257 s_threadCreated = true;
258 }
259 #endif
260
261 } // namespace WTF
262
263 #endif // OS(POSIX)
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/ThreadSpecificWin.cpp ('k') | third_party/WebKit/Source/wtf/ThreadingWin.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698