| Index: base/threading/platform_thread_win.cc
|
| diff --git a/base/threading/platform_thread_win.cc b/base/threading/platform_thread_win.cc
|
| deleted file mode 100644
|
| index 395fc9e20173ad00797c85248584a9d7d1826d7d..0000000000000000000000000000000000000000
|
| --- a/base/threading/platform_thread_win.cc
|
| +++ /dev/null
|
| @@ -1,288 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "base/threading/platform_thread.h"
|
| -
|
| -#include "base/debug/alias.h"
|
| -#include "base/debug/profiler.h"
|
| -#include "base/logging.h"
|
| -#include "base/threading/thread_id_name_manager.h"
|
| -#include "base/threading/thread_restrictions.h"
|
| -#include "base/tracked_objects.h"
|
| -#include "base/win/scoped_handle.h"
|
| -#include "base/win/windows_version.h"
|
| -
|
| -namespace base {
|
| -
|
| -namespace {
|
| -
|
| -// The information on how to set the thread name comes from
|
| -// a MSDN article: http://msdn2.microsoft.com/en-us/library/xcb2z8hs.aspx
|
| -const DWORD kVCThreadNameException = 0x406D1388;
|
| -
|
| -typedef struct tagTHREADNAME_INFO {
|
| - DWORD dwType; // Must be 0x1000.
|
| - LPCSTR szName; // Pointer to name (in user addr space).
|
| - DWORD dwThreadID; // Thread ID (-1=caller thread).
|
| - DWORD dwFlags; // Reserved for future use, must be zero.
|
| -} THREADNAME_INFO;
|
| -
|
| -// This function has try handling, so it is separated out of its caller.
|
| -void SetNameInternal(PlatformThreadId thread_id, const char* name) {
|
| - THREADNAME_INFO info;
|
| - info.dwType = 0x1000;
|
| - info.szName = name;
|
| - info.dwThreadID = thread_id;
|
| - info.dwFlags = 0;
|
| -
|
| - __try {
|
| - RaiseException(kVCThreadNameException, 0, sizeof(info)/sizeof(DWORD),
|
| - reinterpret_cast<DWORD_PTR*>(&info));
|
| - } __except(EXCEPTION_CONTINUE_EXECUTION) {
|
| - }
|
| -}
|
| -
|
| -struct ThreadParams {
|
| - PlatformThread::Delegate* delegate;
|
| - bool joinable;
|
| -};
|
| -
|
| -DWORD __stdcall ThreadFunc(void* params) {
|
| - ThreadParams* thread_params = static_cast<ThreadParams*>(params);
|
| - PlatformThread::Delegate* delegate = thread_params->delegate;
|
| - if (!thread_params->joinable)
|
| - base::ThreadRestrictions::SetSingletonAllowed(false);
|
| -
|
| - // Retrieve a copy of the thread handle to use as the key in the
|
| - // thread name mapping.
|
| - PlatformThreadHandle::Handle platform_handle;
|
| - BOOL did_dup = DuplicateHandle(GetCurrentProcess(),
|
| - GetCurrentThread(),
|
| - GetCurrentProcess(),
|
| - &platform_handle,
|
| - 0,
|
| - FALSE,
|
| - DUPLICATE_SAME_ACCESS);
|
| -
|
| - win::ScopedHandle scoped_platform_handle;
|
| -
|
| - if (did_dup) {
|
| - scoped_platform_handle.Set(platform_handle);
|
| - ThreadIdNameManager::GetInstance()->RegisterThread(
|
| - scoped_platform_handle.Get(),
|
| - PlatformThread::CurrentId());
|
| - }
|
| -
|
| - delete thread_params;
|
| - delegate->ThreadMain();
|
| -
|
| - if (did_dup) {
|
| - ThreadIdNameManager::GetInstance()->RemoveName(
|
| - scoped_platform_handle.Get(),
|
| - PlatformThread::CurrentId());
|
| - }
|
| -
|
| - return NULL;
|
| -}
|
| -
|
| -// CreateThreadInternal() matches PlatformThread::Create(), except that
|
| -// |out_thread_handle| may be NULL, in which case a non-joinable thread is
|
| -// created.
|
| -bool CreateThreadInternal(size_t stack_size,
|
| - PlatformThread::Delegate* delegate,
|
| - PlatformThreadHandle* out_thread_handle) {
|
| - unsigned int flags = 0;
|
| - if (stack_size > 0 && base::win::GetVersion() >= base::win::VERSION_XP) {
|
| - flags = STACK_SIZE_PARAM_IS_A_RESERVATION;
|
| - } else {
|
| - stack_size = 0;
|
| - }
|
| -
|
| - ThreadParams* params = new ThreadParams;
|
| - params->delegate = delegate;
|
| - params->joinable = out_thread_handle != NULL;
|
| -
|
| - // Using CreateThread here vs _beginthreadex makes thread creation a bit
|
| - // faster and doesn't require the loader lock to be available. Our code will
|
| - // have to work running on CreateThread() threads anyway, since we run code
|
| - // on the Windows thread pool, etc. For some background on the difference:
|
| - // http://www.microsoft.com/msj/1099/win32/win321099.aspx
|
| - PlatformThreadId thread_id;
|
| - void* thread_handle = CreateThread(
|
| - NULL, stack_size, ThreadFunc, params, flags, &thread_id);
|
| - if (!thread_handle) {
|
| - delete params;
|
| - return false;
|
| - }
|
| -
|
| - if (out_thread_handle)
|
| - *out_thread_handle = PlatformThreadHandle(thread_handle, thread_id);
|
| - else
|
| - CloseHandle(thread_handle);
|
| - return true;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -// static
|
| -PlatformThreadId PlatformThread::CurrentId() {
|
| - return ::GetCurrentThreadId();
|
| -}
|
| -
|
| -// static
|
| -PlatformThreadRef PlatformThread::CurrentRef() {
|
| - return PlatformThreadRef(::GetCurrentThreadId());
|
| -}
|
| -
|
| -// static
|
| -PlatformThreadHandle PlatformThread::CurrentHandle() {
|
| - return PlatformThreadHandle(::GetCurrentThread());
|
| -}
|
| -
|
| -// static
|
| -void PlatformThread::YieldCurrentThread() {
|
| - ::Sleep(0);
|
| -}
|
| -
|
| -// static
|
| -void PlatformThread::Sleep(TimeDelta duration) {
|
| - // When measured with a high resolution clock, Sleep() sometimes returns much
|
| - // too early. We may need to call it repeatedly to get the desired duration.
|
| - TimeTicks end = TimeTicks::Now() + duration;
|
| - for (TimeTicks now = TimeTicks::Now(); now < end; now = TimeTicks::Now())
|
| - ::Sleep(static_cast<DWORD>((end - now).InMillisecondsRoundedUp()));
|
| -}
|
| -
|
| -// static
|
| -void PlatformThread::SetName(const std::string& name) {
|
| - ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name);
|
| -
|
| - // On Windows only, we don't need to tell the profiler about the "BrokerEvent"
|
| - // thread, as it exists only in the chrome.exe image, and never spawns or runs
|
| - // tasks (items which could be profiled). This test avoids the notification,
|
| - // which would also (as a side effect) initialize the profiler in this unused
|
| - // context, including setting up thread local storage, etc. The performance
|
| - // impact is not terrible, but there is no reason to do initialize it.
|
| - if (name != "BrokerEvent")
|
| - tracked_objects::ThreadData::InitializeThreadContext(name);
|
| -
|
| - // The debugger needs to be around to catch the name in the exception. If
|
| - // there isn't a debugger, we are just needlessly throwing an exception.
|
| - // If this image file is instrumented, we raise the exception anyway
|
| - // to provide the profiler with human-readable thread names.
|
| - if (!::IsDebuggerPresent() && !base::debug::IsBinaryInstrumented())
|
| - return;
|
| -
|
| - SetNameInternal(CurrentId(), name.c_str());
|
| -}
|
| -
|
| -// static
|
| -const char* PlatformThread::GetName() {
|
| - return ThreadIdNameManager::GetInstance()->GetName(CurrentId());
|
| -}
|
| -
|
| -// static
|
| -bool PlatformThread::Create(size_t stack_size, Delegate* delegate,
|
| - PlatformThreadHandle* thread_handle) {
|
| - DCHECK(thread_handle);
|
| - return CreateThreadInternal(stack_size, delegate, thread_handle);
|
| -}
|
| -
|
| -// static
|
| -bool PlatformThread::CreateWithPriority(size_t stack_size, Delegate* delegate,
|
| - PlatformThreadHandle* thread_handle,
|
| - ThreadPriority priority) {
|
| - bool result = Create(stack_size, delegate, thread_handle);
|
| - if (result)
|
| - SetThreadPriority(*thread_handle, priority);
|
| - return result;
|
| -}
|
| -
|
| -// static
|
| -bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) {
|
| - return CreateThreadInternal(stack_size, delegate, NULL);
|
| -}
|
| -
|
| -// static
|
| -void PlatformThread::Join(PlatformThreadHandle thread_handle) {
|
| - DCHECK(thread_handle.platform_handle());
|
| - // TODO(willchan): Enable this check once I can get it to work for Windows
|
| - // shutdown.
|
| - // Joining another thread may block the current thread for a long time, since
|
| - // the thread referred to by |thread_handle| may still be running long-lived /
|
| - // blocking tasks.
|
| -#if 0
|
| - base::ThreadRestrictions::AssertIOAllowed();
|
| -#endif
|
| -
|
| - // Wait for the thread to exit. It should already have terminated but make
|
| - // sure this assumption is valid.
|
| - DWORD result = WaitForSingleObject(thread_handle.platform_handle(), INFINITE);
|
| - if (result != WAIT_OBJECT_0) {
|
| - // Debug info for bug 127931.
|
| - DWORD error = GetLastError();
|
| - debug::Alias(&error);
|
| - debug::Alias(&result);
|
| - CHECK(false);
|
| - }
|
| -
|
| - CloseHandle(thread_handle.platform_handle());
|
| -}
|
| -
|
| -// static
|
| -void PlatformThread::SetThreadPriority(PlatformThreadHandle handle,
|
| - ThreadPriority priority) {
|
| - DCHECK(!handle.is_null());
|
| -
|
| - int desired_priority = THREAD_PRIORITY_ERROR_RETURN;
|
| - switch (priority) {
|
| - case ThreadPriority::BACKGROUND:
|
| - desired_priority = THREAD_PRIORITY_LOWEST;
|
| - break;
|
| - case ThreadPriority::NORMAL:
|
| - desired_priority = THREAD_PRIORITY_NORMAL;
|
| - break;
|
| - case ThreadPriority::DISPLAY:
|
| - desired_priority = THREAD_PRIORITY_ABOVE_NORMAL;
|
| - break;
|
| - case ThreadPriority::REALTIME_AUDIO:
|
| - desired_priority = THREAD_PRIORITY_TIME_CRITICAL;
|
| - break;
|
| - default:
|
| - NOTREACHED() << "Unknown priority.";
|
| - break;
|
| - }
|
| - DCHECK_NE(desired_priority, THREAD_PRIORITY_ERROR_RETURN);
|
| -
|
| -#ifndef NDEBUG
|
| - const BOOL success =
|
| -#endif
|
| - ::SetThreadPriority(handle.platform_handle(), desired_priority);
|
| - DPLOG_IF(ERROR, !success) << "Failed to set thread priority to "
|
| - << desired_priority;
|
| -}
|
| -
|
| -// static
|
| -ThreadPriority PlatformThread::GetThreadPriority(PlatformThreadHandle handle) {
|
| - DCHECK(!handle.is_null());
|
| -
|
| - int priority = ::GetThreadPriority(handle.platform_handle());
|
| - switch (priority) {
|
| - case THREAD_PRIORITY_LOWEST:
|
| - return ThreadPriority::BACKGROUND;
|
| - case THREAD_PRIORITY_NORMAL:
|
| - return ThreadPriority::NORMAL;
|
| - case THREAD_PRIORITY_ABOVE_NORMAL:
|
| - return ThreadPriority::DISPLAY;
|
| - case THREAD_PRIORITY_TIME_CRITICAL:
|
| - return ThreadPriority::REALTIME_AUDIO;
|
| - case THREAD_PRIORITY_ERROR_RETURN:
|
| - DPCHECK(false) << "GetThreadPriority error"; // Falls through.
|
| - default:
|
| - NOTREACHED() << "Unexpected priority: " << priority;
|
| - return ThreadPriority::NORMAL;
|
| - }
|
| -}
|
| -
|
| -} // namespace base
|
|
|