OLD | NEW |
---|---|
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/platform_thread.h" | 5 #include "base/platform_thread.h" |
6 | 6 |
7 #include <process.h> | 7 #include <process.h> |
cpu_(ooo_6.6-7.5)
2008/11/04 03:07:58
remove this include
| |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/win_util.h" | 10 #include "base/win_util.h" |
11 | 11 |
12 namespace { | 12 namespace { |
13 | 13 |
14 // The information on how to set the thread name comes from | 14 // The information on how to set the thread name comes from |
15 // a MSDN article: http://msdn2.microsoft.com/en-us/library/xcb2z8hs.aspx | 15 // a MSDN article: http://msdn2.microsoft.com/en-us/library/xcb2z8hs.aspx |
16 const DWORD kVCThreadNameException = 0x406D1388; | 16 const DWORD kVCThreadNameException = 0x406D1388; |
17 | 17 |
18 typedef struct tagTHREADNAME_INFO { | 18 typedef struct tagTHREADNAME_INFO { |
19 DWORD dwType; // Must be 0x1000. | 19 DWORD dwType; // Must be 0x1000. |
20 LPCSTR szName; // Pointer to name (in user addr space). | 20 LPCSTR szName; // Pointer to name (in user addr space). |
21 DWORD dwThreadID; // Thread ID (-1=caller thread). | 21 DWORD dwThreadID; // Thread ID (-1=caller thread). |
22 DWORD dwFlags; // Reserved for future use, must be zero. | 22 DWORD dwFlags; // Reserved for future use, must be zero. |
23 } THREADNAME_INFO; | 23 } THREADNAME_INFO; |
24 | 24 |
25 unsigned __stdcall ThreadFunc(void* closure) { | 25 DWORD __stdcall ThreadFunc(void* closure) { |
26 PlatformThread::Delegate* delegate = | 26 PlatformThread::Delegate* delegate = |
27 static_cast<PlatformThread::Delegate*>(closure); | 27 static_cast<PlatformThread::Delegate*>(closure); |
28 delegate->ThreadMain(); | 28 delegate->ThreadMain(); |
29 return NULL; | 29 return NULL; |
30 } | 30 } |
31 | 31 |
32 } // namespace | 32 } // namespace |
33 | 33 |
34 // static | 34 // static |
35 int PlatformThread::CurrentId() { | 35 int PlatformThread::CurrentId() { |
36 return GetCurrentThreadId(); | 36 return GetCurrentThreadId(); |
37 } | 37 } |
38 | 38 |
39 // static | 39 // static |
40 void PlatformThread::YieldCurrentThread() { | 40 void PlatformThread::YieldCurrentThread() { |
41 ::Sleep(0); | 41 ::Sleep(0); |
42 } | 42 } |
43 | 43 |
44 // static | 44 // static |
45 void PlatformThread::Sleep(int duration_ms) { | 45 void PlatformThread::Sleep(int duration_ms) { |
46 ::Sleep(duration_ms); | 46 ::Sleep(duration_ms); |
47 } | 47 } |
48 | 48 |
49 // static | 49 // static |
50 void PlatformThread::SetName(const char* name) { | 50 void PlatformThread::SetName(const char* name) { |
51 // The debugger needs to be around to catch the name in the exception. If | 51 // The debugger needs to be around to catch the name in the exception. If |
52 // there isn't a debugger, we are just needlessly throwing an exception. | 52 // there isn't a debugger, we are just needlessly throwing an exception. |
53 if (!::IsDebuggerPresent()) | 53 if (0 && !::IsDebuggerPresent()) |
Peter Kasting
2008/11/03 22:09:32
Did you mean this change to be part of this CL? L
| |
54 return; | 54 return; |
55 | 55 |
56 THREADNAME_INFO info; | 56 THREADNAME_INFO info; |
57 info.dwType = 0x1000; | 57 info.dwType = 0x1000; |
58 info.szName = name; | 58 info.szName = name; |
59 info.dwThreadID = CurrentId(); | 59 info.dwThreadID = CurrentId(); |
60 info.dwFlags = 0; | 60 info.dwFlags = 0; |
61 | 61 |
62 __try { | 62 __try { |
63 RaiseException(kVCThreadNameException, 0, sizeof(info)/sizeof(DWORD), | 63 RaiseException(kVCThreadNameException, 0, sizeof(info)/sizeof(DWORD), |
64 reinterpret_cast<DWORD_PTR*>(&info)); | 64 reinterpret_cast<DWORD_PTR*>(&info)); |
65 } __except(EXCEPTION_CONTINUE_EXECUTION) { | 65 } __except(EXCEPTION_CONTINUE_EXECUTION) { |
66 } | 66 } |
67 } | 67 } |
68 | 68 |
69 // static | 69 // static |
70 bool PlatformThread::Create(size_t stack_size, Delegate* delegate, | 70 bool PlatformThread::Create(size_t stack_size, Delegate* delegate, |
71 PlatformThreadHandle* thread_handle) { | 71 PlatformThreadHandle* thread_handle) { |
72 unsigned int flags = 0; | 72 unsigned int flags = 0; |
73 if (stack_size > 0 && win_util::GetWinVersion() >= win_util::WINVERSION_XP) { | 73 if (stack_size > 0 && win_util::GetWinVersion() >= win_util::WINVERSION_XP) { |
74 flags = STACK_SIZE_PARAM_IS_A_RESERVATION; | 74 flags = STACK_SIZE_PARAM_IS_A_RESERVATION; |
75 } else { | 75 } else { |
76 stack_size = 0; | 76 stack_size = 0; |
77 } | 77 } |
78 | 78 |
79 *thread_handle = reinterpret_cast<PlatformThreadHandle>(_beginthreadex( | 79 // Using CreateThread here vs _beginthreadex makes thread creation a bit |
80 NULL, stack_size, ThreadFunc, delegate, flags, NULL)); | 80 // faster and doesn't require holding the loader lock. Our code will have |
tommi (sloooow) - chröme
2008/11/30 05:29:33
hi... really late, drive by comment here. I notic
| |
81 // to work running on CreateThread() threads anyway, since we run code on | |
82 // the Windows thread pool, etc. For some background on the difference: | |
83 // http://www.microsoft.com/msj/1099/win32/win321099.aspx | |
M-A Ruel
2008/11/03 22:22:11
Add these links too:
http://msdn.microsoft.com/en-
| |
84 *thread_handle = CreateThread( | |
85 NULL, stack_size, ThreadFunc, delegate, flags, NULL); | |
81 return *thread_handle != NULL; | 86 return *thread_handle != NULL; |
82 } | 87 } |
83 | 88 |
84 // static | 89 // static |
85 void PlatformThread::Join(PlatformThreadHandle thread_handle) { | 90 void PlatformThread::Join(PlatformThreadHandle thread_handle) { |
86 DCHECK(thread_handle); | 91 DCHECK(thread_handle); |
87 | 92 |
88 // Wait for the thread to exit. It should already have terminated but make | 93 // Wait for the thread to exit. It should already have terminated but make |
89 // sure this assumption is valid. | 94 // sure this assumption is valid. |
90 DWORD result = WaitForSingleObject(thread_handle, INFINITE); | 95 DWORD result = WaitForSingleObject(thread_handle, INFINITE); |
91 DCHECK_EQ(WAIT_OBJECT_0, result); | 96 DCHECK_EQ(WAIT_OBJECT_0, result); |
92 | 97 |
93 CloseHandle(thread_handle); | 98 CloseHandle(thread_handle); |
94 } | 99 } |
95 | 100 |
OLD | NEW |