OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. |
3 * Copyright (C) 2009 Google Inc. All rights reserved. | 3 * Copyright (C) 2009 Google Inc. All rights reserved. |
4 * Copyright (C) 2009 Torch Mobile, Inc. All rights reserved. | 4 * Copyright (C) 2009 Torch Mobile, Inc. All rights reserved. |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * | 9 * |
10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
(...skipping 11 matching lines...) Expand all Loading... | |
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY | 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 /* | 31 /* |
32 * There are numerous academic and practical works on how to implement pthread_c ond_wait/pthread_cond_signal/pthread_cond_broadcast | 32 * There are numerous academic and practical works on how to implement |
33 * functions on Win32. Here is one example: http://www.cs.wustl.edu/~schmidt/win 32-cv-1.html which is widely credited as a 'starting point' | 33 * pthread_cond_wait/pthread_cond_signal/pthread_cond_broadcast |
34 * of modern attempts. There are several more or less proven implementations, on e in Boost C++ library (http://www.boost.org) and another | 34 * functions on Win32. Here is one example: |
35 * http://www.cs.wustl.edu/~schmidt/win32-cv-1.html which is widely credited as | |
36 * a 'starting point' of modern attempts. There are several more or less proven | |
37 * implementations, one in Boost C++ library (http://www.boost.org) and another | |
35 * in pthreads-win32 (http://sourceware.org/pthreads-win32/). | 38 * in pthreads-win32 (http://sourceware.org/pthreads-win32/). |
36 * | 39 * |
37 * The number of articles and discussions is the evidence of significant difficu lties in implementing these primitives correctly. | 40 * The number of articles and discussions is the evidence of significant |
38 * The brief search of revisions, ChangeLog entries, discussions in comp.program ming.threads and other places clearly documents | 41 * difficulties in implementing these primitives correctly. The brief search |
39 * numerous pitfalls and performance problems the authors had to overcome to arr ive to the suitable implementations. | 42 * of revisions, ChangeLog entries, discussions in comp.programming.threads and |
40 * Optimally, WebKit would use one of those supported/tested libraries directly. To roll out our own implementation is impractical, | 43 * other places clearly documents numerous pitfalls and performance problems |
41 * if even for the lack of sufficient testing. However, a faithful reproduction of the code from one of the popular supported | 44 * the authors had to overcome to arrive to the suitable implementations. |
42 * libraries seems to be a good compromise. | 45 * Optimally, WebKit would use one of those supported/tested libraries |
46 * directly. To roll out our own implementation is impractical, if even for | |
47 * the lack of sufficient testing. However, a faithful reproduction of the code | |
48 * from one of the popular supported libraries seems to be a good compromise. | |
43 * | 49 * |
44 * The early Boost implementation (http://www.boxbackup.org/trac/browser/box/nic k/win/lib/win32/boost_1_32_0/libs/thread/src/condition.cpp?rev=30) | 50 * The early Boost implementation |
45 * is identical to pthreads-win32 (http://sourceware.org/cgi-bin/cvsweb.cgi/pthr eads/pthread_cond_wait.c?rev=1.10&content-type=text/x-cvsweb-markup&cvsroot=pthr eads-win32). | 51 * (http://www.boxbackup.org/trac/browser/box/nick/win/lib/win32/boost_1_32_0/li bs/thread/src/condition.cpp?rev=30) |
46 * Current Boost uses yet another (although seemingly equivalent) algorithm whic h came from their 'thread rewrite' effort. | 52 * is identical to pthreads-win32 |
53 * (http://sourceware.org/cgi-bin/cvsweb.cgi/pthreads/pthread_cond_wait.c?rev=1. 10&content-type=text/x-cvsweb-markup&cvsroot=pthreads-win32). | |
54 * Current Boost uses yet another (although seemingly equivalent) algorithm | |
55 * which came from their 'thread rewrite' effort. | |
47 * | 56 * |
48 * This file includes timedWait/signal/broadcast implementations translated to W ebKit coding style from the latest algorithm by | 57 * This file includes timedWait/signal/broadcast implementations translated to |
49 * Alexander Terekhov and Louis Thomas, as captured here: http://sourceware.org/ cgi-bin/cvsweb.cgi/pthreads/pthread_cond_wait.c?rev=1.10&content-type=text/x-cvs web-markup&cvsroot=pthreads-win32 | 58 * WebKit coding style from the latest algorithm by Alexander Terekhov and |
50 * It replaces the implementation of their previous algorithm, also documented i n the same source above. | 59 * Louis Thomas, as captured here: |
51 * The naming and comments are left very close to original to enable easy cross- check. | 60 * http://sourceware.org/cgi-bin/cvsweb.cgi/pthreads/pthread_cond_wait.c?rev=1.1 0&content-type=text/x-cvsweb-markup&cvsroot=pthreads-win32 |
61 * It replaces the implementation of their previous algorithm, also documented | |
62 * in the same source above. The naming and comments are left very close to | |
63 * original to enable easy cross-check. | |
52 * | 64 * |
53 * The corresponding Pthreads-win32 License is included below, and CONTRIBUTORS file which it refers to is added to | 65 * The corresponding Pthreads-win32 License is included below, and CONTRIBUTORS |
66 * file which it refers to is added to | |
54 * source directory (as CONTRIBUTORS.pthreads-win32). | 67 * source directory (as CONTRIBUTORS.pthreads-win32). |
dcheng
2016/10/01 19:58:17
Nit: merge into previous line
Nico
2016/10/02 00:49:28
Done.
| |
55 */ | 68 */ |
56 | 69 |
57 /* | 70 /* |
58 * Pthreads-win32 - POSIX Threads Library for Win32 | 71 * Pthreads-win32 - POSIX Threads Library for Win32 |
59 * Copyright(C) 1998 John E. Bossom | 72 * Copyright(C) 1998 John E. Bossom |
60 * Copyright(C) 1999,2005 Pthreads-win32 contributors | 73 * Copyright(C) 1999,2005 Pthreads-win32 contributors |
61 * | 74 * |
62 * Contact Email: rpj@callisto.canberra.edu.au | 75 * Contact Email: rpj@callisto.canberra.edu.au |
63 * | 76 * |
64 * The current list of contributors is contained | 77 * The current list of contributors is contained |
(...skipping 29 matching lines...) Expand all Loading... | |
94 #include "wtf/ThreadSpecific.h" | 107 #include "wtf/ThreadSpecific.h" |
95 #include "wtf/ThreadingPrimitives.h" | 108 #include "wtf/ThreadingPrimitives.h" |
96 #include "wtf/WTFThreadData.h" | 109 #include "wtf/WTFThreadData.h" |
97 #include "wtf/dtoa/double-conversion.h" | 110 #include "wtf/dtoa/double-conversion.h" |
98 #include <errno.h> | 111 #include <errno.h> |
99 #include <process.h> | 112 #include <process.h> |
100 #include <windows.h> | 113 #include <windows.h> |
101 | 114 |
102 namespace WTF { | 115 namespace WTF { |
103 | 116 |
104 // THREADNAME_INFO comes from <http://msdn.microsoft.com/en-us/library/xcb2z8hs. aspx>. | 117 // THREADNAME_INFO comes from |
118 // <http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx>. | |
105 #pragma pack(push, 8) | 119 #pragma pack(push, 8) |
106 typedef struct tagTHREADNAME_INFO { | 120 typedef struct tagTHREADNAME_INFO { |
107 DWORD dwType; // must be 0x1000 | 121 DWORD dwType; // must be 0x1000 |
108 LPCSTR szName; // pointer to name (in user addr space) | 122 LPCSTR szName; // pointer to name (in user addr space) |
109 DWORD dwThreadID; // thread ID (-1=caller thread) | 123 DWORD dwThreadID; // thread ID (-1=caller thread) |
110 DWORD dwFlags; // reserved for future use, must be zero | 124 DWORD dwFlags; // reserved for future use, must be zero |
111 } THREADNAME_INFO; | 125 } THREADNAME_INFO; |
112 #pragma pack(pop) | 126 #pragma pack(pop) |
113 | 127 |
114 static Mutex* atomicallyInitializedStaticMutex; | 128 static Mutex* atomicallyInitializedStaticMutex; |
115 | 129 |
116 void lockAtomicallyInitializedStaticMutex() { | 130 void lockAtomicallyInitializedStaticMutex() { |
117 ASSERT(atomicallyInitializedStaticMutex); | 131 ASSERT(atomicallyInitializedStaticMutex); |
118 atomicallyInitializedStaticMutex->lock(); | 132 atomicallyInitializedStaticMutex->lock(); |
119 } | 133 } |
120 | 134 |
121 void unlockAtomicallyInitializedStaticMutex() { | 135 void unlockAtomicallyInitializedStaticMutex() { |
122 atomicallyInitializedStaticMutex->unlock(); | 136 atomicallyInitializedStaticMutex->unlock(); |
123 } | 137 } |
124 | 138 |
125 void initializeThreading() { | 139 void initializeThreading() { |
126 // This should only be called once. | 140 // This should only be called once. |
127 ASSERT(!atomicallyInitializedStaticMutex); | 141 ASSERT(!atomicallyInitializedStaticMutex); |
128 | 142 |
129 // StringImpl::empty() does not construct its static string in a threadsafe fa shion, | 143 // StringImpl::empty() does not construct its static string in a threadsafe |
130 // so ensure it has been initialized from here. | 144 // fashion, so ensure it has been initialized from here. |
131 StringImpl::empty(); | 145 StringImpl::empty(); |
132 StringImpl::empty16Bit(); | 146 StringImpl::empty16Bit(); |
133 atomicallyInitializedStaticMutex = new Mutex; | 147 atomicallyInitializedStaticMutex = new Mutex; |
134 wtfThreadData(); | 148 wtfThreadData(); |
135 initializeDates(); | 149 initializeDates(); |
136 // Force initialization of static DoubleToStringConverter converter variable | 150 // Force initialization of static DoubleToStringConverter converter variable |
137 // inside EcmaScriptConverter function while we are in single thread mode. | 151 // inside EcmaScriptConverter function while we are in single thread mode. |
138 double_conversion::DoubleToStringConverter::EcmaScriptConverter(); | 152 double_conversion::DoubleToStringConverter::EcmaScriptConverter(); |
139 } | 153 } |
140 | 154 |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
337 } | 351 } |
338 | 352 |
339 void ThreadCondition::wait(MutexBase& mutex) { | 353 void ThreadCondition::wait(MutexBase& mutex) { |
340 m_condition.timedWait(mutex.impl(), INFINITE); | 354 m_condition.timedWait(mutex.impl(), INFINITE); |
341 } | 355 } |
342 | 356 |
343 bool ThreadCondition::timedWait(MutexBase& mutex, double absoluteTime) { | 357 bool ThreadCondition::timedWait(MutexBase& mutex, double absoluteTime) { |
344 DWORD interval = absoluteTimeToWaitTimeoutInterval(absoluteTime); | 358 DWORD interval = absoluteTimeToWaitTimeoutInterval(absoluteTime); |
345 | 359 |
346 if (!interval) { | 360 if (!interval) { |
347 // Consider the wait to have timed out, even if our condition has already be en signaled, to | 361 // Consider the wait to have timed out, even if our condition has already |
348 // match the pthreads implementation. | 362 // been signaled, to match the pthreads implementation. |
349 return false; | 363 return false; |
350 } | 364 } |
351 | 365 |
352 return m_condition.timedWait(mutex.impl(), interval); | 366 return m_condition.timedWait(mutex.impl(), interval); |
353 } | 367 } |
354 | 368 |
355 void ThreadCondition::signal() { | 369 void ThreadCondition::signal() { |
356 m_condition.signal(false); // Unblock only 1 thread. | 370 m_condition.signal(false); // Unblock only 1 thread. |
357 } | 371 } |
358 | 372 |
359 void ThreadCondition::broadcast() { | 373 void ThreadCondition::broadcast() { |
360 m_condition.signal(true); // Unblock all threads. | 374 m_condition.signal(true); // Unblock all threads. |
361 } | 375 } |
362 | 376 |
363 DWORD absoluteTimeToWaitTimeoutInterval(double absoluteTime) { | 377 DWORD absoluteTimeToWaitTimeoutInterval(double absoluteTime) { |
364 double currentTime = WTF::currentTime(); | 378 double currentTime = WTF::currentTime(); |
365 | 379 |
366 // Time is in the past - return immediately. | 380 // Time is in the past - return immediately. |
367 if (absoluteTime < currentTime) | 381 if (absoluteTime < currentTime) |
368 return 0; | 382 return 0; |
369 | 383 |
370 // Time is too far in the future (and would overflow unsigned long) - wait for ever. | 384 // Time is too far in the future (and would overflow unsigned long) - wait |
385 // forever. | |
371 if (absoluteTime - currentTime > static_cast<double>(INT_MAX) / 1000.0) | 386 if (absoluteTime - currentTime > static_cast<double>(INT_MAX) / 1000.0) |
372 return INFINITE; | 387 return INFINITE; |
373 | 388 |
374 return static_cast<DWORD>((absoluteTime - currentTime) * 1000.0); | 389 return static_cast<DWORD>((absoluteTime - currentTime) * 1000.0); |
375 } | 390 } |
376 | 391 |
377 #if ENABLE(ASSERT) | 392 #if ENABLE(ASSERT) |
378 static bool s_threadCreated = false; | 393 static bool s_threadCreated = false; |
379 | 394 |
380 bool isAtomicallyInitializedStaticMutexLockHeld() { | 395 bool isAtomicallyInitializedStaticMutexLockHeld() { |
381 return atomicallyInitializedStaticMutex && | 396 return atomicallyInitializedStaticMutex && |
382 atomicallyInitializedStaticMutex->locked(); | 397 atomicallyInitializedStaticMutex->locked(); |
383 } | 398 } |
384 | 399 |
385 bool isBeforeThreadCreated() { | 400 bool isBeforeThreadCreated() { |
386 return !s_threadCreated; | 401 return !s_threadCreated; |
387 } | 402 } |
388 | 403 |
389 void willCreateThread() { | 404 void willCreateThread() { |
390 s_threadCreated = true; | 405 s_threadCreated = true; |
391 } | 406 } |
392 #endif | 407 #endif |
393 | 408 |
394 } // namespace WTF | 409 } // namespace WTF |
395 | 410 |
396 #endif // OS(WIN) | 411 #endif // OS(WIN) |
OLD | NEW |