| OLD | NEW | 
|    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |    1 // Copyright (c) 2012 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/threading/platform_thread.h" |    5 #include "base/threading/platform_thread.h" | 
|    6  |    6  | 
|    7 #include "base/debug/alias.h" |    7 #include "base/debug/alias.h" | 
|    8 #include "base/debug/profiler.h" |    8 #include "base/debug/profiler.h" | 
|    9 #include "base/logging.h" |    9 #include "base/logging.h" | 
|   10 #include "base/threading/thread_local.h" |   10 #include "base/threading/thread_id_name_manager.h" | 
|   11 #include "base/threading/thread_restrictions.h" |   11 #include "base/threading/thread_restrictions.h" | 
|   12 #include "base/tracked_objects.h" |   12 #include "base/tracked_objects.h" | 
|   13  |   13  | 
|   14 #include "base/win/windows_version.h" |   14 #include "base/win/windows_version.h" | 
|   15  |   15  | 
|   16 namespace base { |   16 namespace base { | 
|   17  |   17  | 
|   18 namespace { |   18 namespace { | 
|   19  |   19  | 
|   20 static ThreadLocalPointer<char> current_thread_name; |  | 
|   21  |  | 
|   22 // The information on how to set the thread name comes from |   20 // The information on how to set the thread name comes from | 
|   23 // a MSDN article: http://msdn2.microsoft.com/en-us/library/xcb2z8hs.aspx |   21 // a MSDN article: http://msdn2.microsoft.com/en-us/library/xcb2z8hs.aspx | 
|   24 const DWORD kVCThreadNameException = 0x406D1388; |   22 const DWORD kVCThreadNameException = 0x406D1388; | 
|   25  |   23  | 
|   26 typedef struct tagTHREADNAME_INFO { |   24 typedef struct tagTHREADNAME_INFO { | 
|   27   DWORD dwType;  // Must be 0x1000. |   25   DWORD dwType;  // Must be 0x1000. | 
|   28   LPCSTR szName;  // Pointer to name (in user addr space). |   26   LPCSTR szName;  // Pointer to name (in user addr space). | 
|   29   DWORD dwThreadID;  // Thread ID (-1=caller thread). |   27   DWORD dwThreadID;  // Thread ID (-1=caller thread). | 
|   30   DWORD dwFlags;  // Reserved for future use, must be zero. |   28   DWORD dwFlags;  // Reserved for future use, must be zero. | 
|   31 } THREADNAME_INFO; |   29 } THREADNAME_INFO; | 
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  109   ::Sleep(0); |  107   ::Sleep(0); | 
|  110 } |  108 } | 
|  111  |  109  | 
|  112 // static |  110 // static | 
|  113 void PlatformThread::Sleep(TimeDelta duration) { |  111 void PlatformThread::Sleep(TimeDelta duration) { | 
|  114   ::Sleep(duration.InMillisecondsRoundedUp()); |  112   ::Sleep(duration.InMillisecondsRoundedUp()); | 
|  115 } |  113 } | 
|  116  |  114  | 
|  117 // static |  115 // static | 
|  118 void PlatformThread::SetName(const char* name) { |  116 void PlatformThread::SetName(const char* name) { | 
|  119   current_thread_name.Set(const_cast<char*>(name)); |  117   ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name); | 
|  120  |  118  | 
|  121   // On Windows only, we don't need to tell the profiler about the "BrokerEvent" |  119   // On Windows only, we don't need to tell the profiler about the "BrokerEvent" | 
|  122   // thread, as it exists only in the chrome.exe image, and never spawns or runs |  120   // thread, as it exists only in the chrome.exe image, and never spawns or runs | 
|  123   // tasks (items which could be profiled).  This test avoids the notification, |  121   // tasks (items which could be profiled).  This test avoids the notification, | 
|  124   // which would also (as a side effect) initialize the profiler in this unused |  122   // which would also (as a side effect) initialize the profiler in this unused | 
|  125   // context, including setting up thread local storage, etc.  The performance |  123   // context, including setting up thread local storage, etc.  The performance | 
|  126   // impact is not terrible, but there is no reason to do initialize it. |  124   // impact is not terrible, but there is no reason to do initialize it. | 
|  127   if (0 != strcmp(name, "BrokerEvent")) |  125   if (0 != strcmp(name, "BrokerEvent")) | 
|  128     tracked_objects::ThreadData::InitializeThreadContext(name); |  126     tracked_objects::ThreadData::InitializeThreadContext(name); | 
|  129  |  127  | 
|  130   // The debugger needs to be around to catch the name in the exception.  If |  128   // The debugger needs to be around to catch the name in the exception.  If | 
|  131   // there isn't a debugger, we are just needlessly throwing an exception. |  129   // there isn't a debugger, we are just needlessly throwing an exception. | 
|  132   // If this image file is instrumented, we raise the exception anyway |  130   // If this image file is instrumented, we raise the exception anyway | 
|  133   // to provide the profiler with human-readable thread names. |  131   // to provide the profiler with human-readable thread names. | 
|  134   if (!::IsDebuggerPresent() && !base::debug::IsBinaryInstrumented()) |  132   if (!::IsDebuggerPresent() && !base::debug::IsBinaryInstrumented()) | 
|  135     return; |  133     return; | 
|  136  |  134  | 
|  137   SetNameInternal(CurrentId(), name); |  135   SetNameInternal(CurrentId(), name); | 
|  138 } |  136 } | 
|  139  |  137  | 
|  140 // static |  138 // static | 
|  141 const char* PlatformThread::GetName() { |  139 const char* PlatformThread::GetName() { | 
|  142   return current_thread_name.Get(); |  140   return ThreadIdNameManager::GetInstance()->GetName(CurrentId()); | 
|  143 } |  141 } | 
|  144  |  142  | 
|  145 // static |  143 // static | 
|  146 bool PlatformThread::Create(size_t stack_size, Delegate* delegate, |  144 bool PlatformThread::Create(size_t stack_size, Delegate* delegate, | 
|  147                             PlatformThreadHandle* thread_handle) { |  145                             PlatformThreadHandle* thread_handle) { | 
|  148   DCHECK(thread_handle); |  146   DCHECK(thread_handle); | 
|  149   return CreateThreadInternal(stack_size, delegate, thread_handle); |  147   return CreateThreadInternal(stack_size, delegate, thread_handle); | 
|  150 } |  148 } | 
|  151  |  149  | 
|  152 // static |  150 // static | 
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  198     case kThreadPriority_Normal: |  196     case kThreadPriority_Normal: | 
|  199       ::SetThreadPriority(handle, THREAD_PRIORITY_NORMAL); |  197       ::SetThreadPriority(handle, THREAD_PRIORITY_NORMAL); | 
|  200       break; |  198       break; | 
|  201     case kThreadPriority_RealtimeAudio: |  199     case kThreadPriority_RealtimeAudio: | 
|  202       ::SetThreadPriority(handle, THREAD_PRIORITY_TIME_CRITICAL); |  200       ::SetThreadPriority(handle, THREAD_PRIORITY_TIME_CRITICAL); | 
|  203       break; |  201       break; | 
|  204   } |  202   } | 
|  205 } |  203 } | 
|  206  |  204  | 
|  207 }  // namespace base |  205 }  // namespace base | 
| OLD | NEW |