diff options
author | scottmg@chromium.org <scottmg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-21 03:57:12 +0000 |
---|---|---|
committer | scottmg@chromium.org <scottmg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-21 03:57:12 +0000 |
commit | 5686b177b4c9de40440ccd60546529b8a4522cd1 (patch) | |
tree | 5724cad21e7ee040c06bf3a68c67e55237fbf404 /base/threading | |
parent | 41cea7ac73afdc41854ddab97f8f1b00541e603d (diff) | |
download | chromium_src-5686b177b4c9de40440ccd60546529b8a4522cd1.zip chromium_src-5686b177b4c9de40440ccd60546529b8a4522cd1.tar.gz chromium_src-5686b177b4c9de40440ccd60546529b8a4522cd1.tar.bz2 |
Revert 201202 "base: Support setting thread priorities generically."
Broke "sizes" by adding may static initializers.
> base: Support setting thread priorities generically.
>
> This patch supports setting priorities across platforms
> at the PlatformThread level, by stashing thread id into the
> thread handle on linux/android.
>
> Since this adds more platform specific code, and #ifdefs
> were starting to get unwieldy, all platform specific code
> is moved into _platform.cc files, with the exception of the
> 'default' implementation, which stay in _posix.
>
> BUG=170549
>
> Review URL: https://chromiumcodereview.appspot.com/12741012
TBR=epenner@chromium.org
Review URL: https://codereview.chromium.org/15311004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@201215 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/threading')
-rw-r--r-- | base/threading/platform_thread.h | 66 | ||||
-rw-r--r-- | base/threading/platform_thread_android.cc | 105 | ||||
-rw-r--r-- | base/threading/platform_thread_linux.cc | 103 | ||||
-rw-r--r-- | base/threading/platform_thread_mac.mm | 48 | ||||
-rw-r--r-- | base/threading/platform_thread_posix.cc | 201 | ||||
-rw-r--r-- | base/threading/platform_thread_win.cc | 26 | ||||
-rw-r--r-- | base/threading/thread.cc | 7 | ||||
-rw-r--r-- | base/threading/thread.h | 3 | ||||
-rw-r--r-- | base/threading/thread_restrictions.h | 1 |
9 files changed, 163 insertions, 397 deletions
diff --git a/base/threading/platform_thread.h b/base/threading/platform_thread.h index 17e296e..576695a 100644 --- a/base/threading/platform_thread.h +++ b/base/threading/platform_thread.h @@ -23,68 +23,27 @@ namespace base { +// PlatformThreadHandle should not be assumed to be a numeric type, since the +// standard intends to allow pthread_t to be a structure. This means you +// should not initialize it to a value, like 0. If it's a member variable, the +// constructor can safely "value initialize" using () in the initializer list. #if defined(OS_WIN) typedef DWORD PlatformThreadId; +typedef void* PlatformThreadHandle; // HANDLE +const PlatformThreadHandle kNullThreadHandle = NULL; #elif defined(OS_POSIX) +typedef pthread_t PlatformThreadHandle; +const PlatformThreadHandle kNullThreadHandle = 0; typedef pid_t PlatformThreadId; #endif -class PlatformThreadHandle { - public: -#if defined(OS_WIN) - typedef void* Handle; -#elif defined(OS_POSIX) - typedef pthread_t Handle; -#endif - - PlatformThreadHandle() - : handle_(0), - id_(0) { - } - - explicit PlatformThreadHandle(Handle handle) - : handle_(handle), - id_(0) { - } - - PlatformThreadHandle(Handle handle, - PlatformThreadId id) - : handle_(handle), - id_(id) { - } - - bool is_equal(const PlatformThreadHandle& other) { - return handle_ == other.handle_; - } - - bool is_null() { - return !handle_; - } - - Handle platform_handle() { - return handle_; - } - - private: - friend class PlatformThread; - - Handle handle_; - PlatformThreadId id_; -}; - -const PlatformThreadHandle kNullThreadHandle(0); -const PlatformThreadId kInvalidThreadId(0); - +const PlatformThreadId kInvalidThreadId = 0; // Valid values for SetThreadPriority() enum ThreadPriority{ kThreadPriority_Normal, // Suitable for low-latency, glitch-resistant audio. - kThreadPriority_RealtimeAudio, - // Suitable for threads which generate data for the display (at ~60Hz). - kThreadPriority_Display, - // Suitable for threads that shouldn't disrupt high priority work. - kThreadPriority_Background + kThreadPriority_RealtimeAudio }; // A namespace for low-level thread functions. @@ -103,9 +62,6 @@ class BASE_EXPORT PlatformThread { // Gets the current thread id, which may be useful for logging purposes. static PlatformThreadId CurrentId(); - // Get the current handle. - static PlatformThreadHandle CurrentHandle(); - // Yield the current thread so another thread can be scheduled. static void YieldCurrentThread(); @@ -150,6 +106,8 @@ class BASE_EXPORT PlatformThread { // |thread_handle|. static void Join(PlatformThreadHandle thread_handle); + // Sets the priority of the thread specified in |handle| to |priority|. + // This does not work on Linux, use CreateWithPriority() instead. static void SetThreadPriority(PlatformThreadHandle handle, ThreadPriority priority); diff --git a/base/threading/platform_thread_android.cc b/base/threading/platform_thread_android.cc deleted file mode 100644 index 2802635..0000000 --- a/base/threading/platform_thread_android.cc +++ /dev/null @@ -1,105 +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 <errno.h> -#include <sys/resource.h> - -#include "base/android/jni_android.h" -#include "base/android/thread_utils.h" -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/threading/thread_id_name_manager.h" -#include "base/tracked_objects.h" -#include "jni/ThreadUtils_jni.h" - -namespace base { - -namespace { -int ThreadNiceValue(ThreadPriority priority) { - // These nice values are taken from Android, which uses nice - // values like linux, but defines some preset nice values. - // Process.THREAD_PRIORITY_AUDIO = -16 - // Process.THREAD_PRIORITY_BACKGROUND = 10 - // Process.THREAD_PRIORITY_DEFAULT = 0; - // Process.THREAD_PRIORITY_DISPLAY = -4; - // Process.THREAD_PRIORITY_FOREGROUND = -2; - // Process.THREAD_PRIORITY_LESS_FAVORABLE = 1; - // Process.THREAD_PRIORITY_LOWEST = 19; - // Process.THREAD_PRIORITY_MORE_FAVORABLE = -1; - // Process.THREAD_PRIORITY_URGENT_AUDIO = -19; - // Process.THREAD_PRIORITY_URGENT_DISPLAY = -8; - // We use -6 for display, but we may want to split this - // into urgent (-8) and non-urgent (-4). - static const int threadPriorityAudio = -16; - static const int threadPriorityBackground = 10; - static const int threadPriorityDefault = 0; - static const int threadPriorityDisplay = -6; - switch (priority) { - case kThreadPriority_RealtimeAudio: - return threadPriorityAudio; - case kThreadPriority_Background: - return threadPriorityBackground; - case kThreadPriority_Normal: - return threadPriorityDefault; - case kThreadPriority_Display: - return threadPriorityDisplay; - default: - NOTREACHED() << "Unknown priority."; - return 0; - } -} -} // namespace - -//static -void PlatformThread::SetThreadPriority(PlatformThreadHandle handle, - ThreadPriority priority) { - // On Android, we set the Audio priority through JNI as Audio priority - // will also allow the process to run while it is backgrounded. - if (priority == kThreadPriority_RealtimeAudio) { - JNIEnv* env = base::android::AttachCurrentThread(); - Java_ThreadUtils_setThreadPriorityAudio(env, PlatformThread::CurrentId()); - return; - } - - // setpriority(2) will set a thread's priority if it is passed a tid as - // the 'process identifier', not affecting the rest of the threads in the - // process. Setting this priority will only succeed if the user has been - // granted permission to adjust nice values on the system. - DCHECK_NE(handle.id_, kInvalidThreadId); - int kNiceSetting = ThreadNiceValue(priority); - if (setpriority(PRIO_PROCESS, handle.id_, kNiceSetting)) - LOG(ERROR) << "Failed to set nice value of thread to " << kNiceSetting; -} - -void PlatformThread::SetName(const char* name) { - ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name); - tracked_objects::ThreadData::InitializeThreadContext(name); -} - - -void InitThreading() { -} - -void InitOnThread() { - // Threads on linux/android may inherit their priority from the thread - // where they were created. This sets all new threads to the default. - PlatformThread::SetThreadPriority(PlatformThread::CurrentHandle(), - kThreadPriority_Normal); -} - -void TerminateOnThread() { - base::android::DetachFromVM(); -} - -size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) { - return 0; -} - -bool RegisterThreadUtils(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -} // namespace base diff --git a/base/threading/platform_thread_linux.cc b/base/threading/platform_thread_linux.cc deleted file mode 100644 index 42e12c7..0000000 --- a/base/threading/platform_thread_linux.cc +++ /dev/null @@ -1,103 +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 <errno.h> -#include <sched.h> - -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/safe_strerror_posix.h" -#include "base/threading/thread_id_name_manager.h" -#include "base/threading/thread_restrictions.h" -#include "base/tracked_objects.h" - -#if defined(OS_LINUX) -#include <sys/prctl.h> -#include <sys/resource.h> -#include <sys/syscall.h> -#include <sys/time.h> -#include <unistd.h> -#endif - -namespace base { - -namespace { -int ThreadNiceValue(ThreadPriority priority) { - static const int threadPriorityAudio = -10; - static const int threadPriorityBackground = 10; - static const int threadPriorityDefault = 0; - static const int threadPriorityDisplay = -6; - switch (priority) { - case kThreadPriority_RealtimeAudio: - return threadPriorityAudio; - case kThreadPriority_Background: - return threadPriorityBackground; - case kThreadPriority_Normal: - return threadPriorityDefault; - case kThreadPriority_Display: - return threadPriorityDisplay; - default: - NOTREACHED() << "Unknown priority."; - return 0; - } -} -} // namespace - -// static -void PlatformThread::SetName(const char* name) { - ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name); - tracked_objects::ThreadData::InitializeThreadContext(name); - -#ifndef OS_NACL - // On linux we can get the thread names to show up in the debugger by setting - // the process name for the LWP. We don't want to do this for the main - // thread because that would rename the process, causing tools like killall - // to stop working. - if (PlatformThread::CurrentId() == getpid()) - return; - - // http://0pointer.de/blog/projects/name-your-threads.html - // Set the name for the LWP (which gets truncated to 15 characters). - // Note that glibc also has a 'pthread_setname_np' api, but it may not be - // available everywhere and it's only benefit over using prctl directly is - // that it can set the name of threads other than the current thread. - int err = prctl(PR_SET_NAME, name); - // We expect EPERM failures in sandboxed processes, just ignore those. - if (err < 0 && errno != EPERM) - DPLOG(ERROR) << "prctl(PR_SET_NAME)"; -#endif -} - -// static -void PlatformThread::SetThreadPriority(PlatformThreadHandle handle, - ThreadPriority priority) { -#ifndef OS_NACL - // setpriority(2) will set a thread's priority if it is passed a tid as - // the 'process identifier', not affecting the rest of the threads in the - // process. Setting this priority will only succeed if the user has been - // granted permission to adjust nice values on the system. - DCHECK_NE(handle.id_, kInvalidThreadId); - int kNiceSetting = ThreadNiceValue(priority); - if (setpriority(PRIO_PROCESS, handle.id_, kNiceSetting)) - LOG(ERROR) << "Failed to set nice value of thread to " << kNiceSetting; -#endif -} - -void InitThreading() { -} - -void InitOnThread() { -} - -void TerminateOnThread() { -} - -size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) { - return 0; -} - -} // namespace base diff --git a/base/threading/platform_thread_mac.mm b/base/threading/platform_thread_mac.mm index d81a286..48041a0 100644 --- a/base/threading/platform_thread_mac.mm +++ b/base/threading/platform_thread_mac.mm @@ -5,12 +5,10 @@ #include "base/threading/platform_thread.h" #import <Foundation/Foundation.h> -#include <algorithm> #include <dlfcn.h> #include <mach/mach.h> #include <mach/mach_time.h> #include <mach/thread_policy.h> -#include <sys/resource.h> #include "base/lazy_instance.h" #include "base/logging.h" @@ -165,7 +163,7 @@ void SetPriorityRealtimeAudio(mach_port_t mach_thread_id) { void PlatformThread::SetThreadPriority(PlatformThreadHandle handle, ThreadPriority priority) { // Convert from pthread_t to mach thread identifier. - mach_port_t mach_thread_id = pthread_mach_thread_np(handle.handle_); + mach_port_t mach_thread_id = pthread_mach_thread_np(handle); switch (priority) { case kThreadPriority_Normal: @@ -174,51 +172,7 @@ void PlatformThread::SetThreadPriority(PlatformThreadHandle handle, case kThreadPriority_RealtimeAudio: SetPriorityRealtimeAudio(mach_thread_id); break; - default: - NOTREACHED() << "Unknown priority."; - break; - } -} - -size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) { -#if defined(OS_IOS) - return 0; -#else - // The Mac OS X default for a pthread stack size is 512kB. - // Libc-594.1.4/pthreads/pthread.c's pthread_attr_init uses - // DEFAULT_STACK_SIZE for this purpose. - // - // 512kB isn't quite generous enough for some deeply recursive threads that - // otherwise request the default stack size by specifying 0. Here, adopt - // glibc's behavior as on Linux, which is to use the current stack size - // limit (ulimit -s) as the default stack size. See - // glibc-2.11.1/nptl/nptl-init.c's __pthread_initialize_minimal_internal. To - // avoid setting the limit below the Mac OS X default or the minimum usable - // stack size, these values are also considered. If any of these values - // can't be determined, or if stack size is unlimited (ulimit -s unlimited), - // stack_size is left at 0 to get the system default. - // - // Mac OS X normally only applies ulimit -s to the main thread stack. On - // contemporary OS X and Linux systems alike, this value is generally 8MB - // or in that neighborhood. - size_t default_stack_size = 0; - struct rlimit stack_rlimit; - if (pthread_attr_getstacksize(&attributes, &default_stack_size) == 0 && - getrlimit(RLIMIT_STACK, &stack_rlimit) == 0 && - stack_rlimit.rlim_cur != RLIM_INFINITY) { - default_stack_size = - std::max(std::max(default_stack_size, - static_cast<size_t>(PTHREAD_STACK_MIN)), - static_cast<size_t>(stack_rlimit.rlim_cur)); } - return default_stack_size; -#endif -} - -void InitOnThread() { -} - -void TerminateOnThread() { } } // namespace base diff --git a/base/threading/platform_thread_posix.cc b/base/threading/platform_thread_posix.cc index b1c0e9d..43e58b7 100644 --- a/base/threading/platform_thread_posix.cc +++ b/base/threading/platform_thread_posix.cc @@ -11,7 +11,6 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/safe_strerror_posix.h" -#include "base/synchronization/waitable_event.h" #include "base/threading/thread_id_name_manager.h" #include "base/threading/thread_restrictions.h" #include "base/tracked_objects.h" @@ -29,53 +28,74 @@ #include <unistd.h> #endif +#if defined(OS_ANDROID) +#include <sys/resource.h> +#include "base/android/thread_utils.h" +#include "jni/ThreadUtils_jni.h" +#endif + namespace base { +#if defined(OS_MACOSX) void InitThreading(); -void InitOnThread(); -void TerminateOnThread(); -size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes); +#endif namespace { struct ThreadParams { - ThreadParams() - : delegate(NULL), - joinable(false), - priority(kThreadPriority_Normal), - handle(NULL), - handle_set(false, false) { - } - PlatformThread::Delegate* delegate; bool joinable; ThreadPriority priority; - PlatformThreadHandle* handle; - WaitableEvent handle_set; }; +void SetCurrentThreadPriority(ThreadPriority priority) { +#if defined(OS_LINUX) || defined(OS_ANDROID) + switch (priority) { + case kThreadPriority_Normal: + NOTREACHED() << "Don't reset priority as not all processes can."; + break; + case kThreadPriority_RealtimeAudio: +#if defined(OS_LINUX) + const int kNiceSetting = -10; + // Linux isn't posix compliant with setpriority(2), it will set a thread + // priority if it is passed a tid, not affecting the rest of the threads + // in the process. Setting this priority will only succeed if the user + // has been granted permission to adjust nice values on the system. + if (setpriority(PRIO_PROCESS, PlatformThread::CurrentId(), kNiceSetting)) + DVLOG(1) << "Failed to set nice value of thread to " << kNiceSetting; +#elif defined(OS_ANDROID) + JNIEnv* env = base::android::AttachCurrentThread(); + Java_ThreadUtils_setThreadPriorityAudio(env, PlatformThread::CurrentId()); +#endif // defined(OS_LINUX) + break; + } +#else // !defined(OS_LINUX) && !defined(OS_ANDROID) + PlatformThread::SetThreadPriority(pthread_self(), priority); +#endif +} + void* ThreadFunc(void* params) { - base::InitOnThread(); +#if defined(OS_ANDROID) + // Threads on linux/android may inherit their priority from the thread + // where they were created. This sets all threads to the default. + // TODO(epenner): Move thread priorities to base. (crbug.com/170549) + if (setpriority(PRIO_PROCESS, PlatformThread::CurrentId(), 0)) + DVLOG(1) << "Failed to reset initial thread nice value to zero."; +#endif ThreadParams* thread_params = static_cast<ThreadParams*>(params); - PlatformThread::Delegate* delegate = thread_params->delegate; if (!thread_params->joinable) base::ThreadRestrictions::SetSingletonAllowed(false); - if (thread_params->priority != kThreadPriority_Normal) { - PlatformThread::SetThreadPriority(PlatformThread::CurrentHandle(), - thread_params->priority); - } - - // Stash the id in the handle so the calling thread has a complete - // handle, and unblock the parent thread. - *(thread_params->handle) = PlatformThreadHandle(pthread_self(), - PlatformThread::CurrentId()); - thread_params->handle_set.Signal(); + // If there is a non-default priority for this thread, set it now. + if (thread_params->priority != kThreadPriority_Normal) + SetCurrentThreadPriority(thread_params->priority); + delete thread_params; delegate->ThreadMain(); - - base::TerminateOnThread(); +#if defined(OS_ANDROID) + base::android::DetachFromVM(); +#endif return NULL; } @@ -83,36 +103,60 @@ bool CreateThread(size_t stack_size, bool joinable, PlatformThread::Delegate* delegate, PlatformThreadHandle* thread_handle, ThreadPriority priority) { +#if defined(OS_MACOSX) base::InitThreading(); +#endif // OS_MACOSX bool success = false; pthread_attr_t attributes; pthread_attr_init(&attributes); - // Pthreads are joinable by default, so only specify the detached - // attribute if the thread should be non-joinable. + // Pthreads are joinable by default, so only specify the detached attribute if + // the thread should be non-joinable. if (!joinable) { pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED); } - // Get a better default if available. - if (stack_size == 0) - stack_size = base::GetDefaultThreadStackSize(attributes); +#if defined(OS_MACOSX) && !defined(OS_IOS) + // The Mac OS X default for a pthread stack size is 512kB. + // Libc-594.1.4/pthreads/pthread.c's pthread_attr_init uses + // DEFAULT_STACK_SIZE for this purpose. + // + // 512kB isn't quite generous enough for some deeply recursive threads that + // otherwise request the default stack size by specifying 0. Here, adopt + // glibc's behavior as on Linux, which is to use the current stack size + // limit (ulimit -s) as the default stack size. See + // glibc-2.11.1/nptl/nptl-init.c's __pthread_initialize_minimal_internal. To + // avoid setting the limit below the Mac OS X default or the minimum usable + // stack size, these values are also considered. If any of these values + // can't be determined, or if stack size is unlimited (ulimit -s unlimited), + // stack_size is left at 0 to get the system default. + // + // Mac OS X normally only applies ulimit -s to the main thread stack. On + // contemporary OS X and Linux systems alike, this value is generally 8MB + // or in that neighborhood. + if (stack_size == 0) { + size_t default_stack_size; + struct rlimit stack_rlimit; + if (pthread_attr_getstacksize(&attributes, &default_stack_size) == 0 && + getrlimit(RLIMIT_STACK, &stack_rlimit) == 0 && + stack_rlimit.rlim_cur != RLIM_INFINITY) { + stack_size = std::max(std::max(default_stack_size, + static_cast<size_t>(PTHREAD_STACK_MIN)), + static_cast<size_t>(stack_rlimit.rlim_cur)); + } + } +#endif // OS_MACOSX && !OS_IOS if (stack_size > 0) pthread_attr_setstacksize(&attributes, stack_size); - ThreadParams params; - params.delegate = delegate; - params.joinable = joinable; - params.priority = priority; - params.handle = thread_handle; - - pthread_t handle = 0; - int err = pthread_create(&handle, - &attributes, - ThreadFunc, - ¶ms); + ThreadParams* params = new ThreadParams; + params->delegate = delegate; + params->joinable = joinable; + params->priority = priority; + + int err = pthread_create(thread_handle, &attributes, ThreadFunc, params); success = !err; if (!success) { errno = err; @@ -120,13 +164,8 @@ bool CreateThread(size_t stack_size, bool joinable, } pthread_attr_destroy(&attributes); - - // Don't let this call complete until the thread id - // is set in the handle. - if (success) - params.handle_set.Wait(); - CHECK_EQ(handle, thread_handle->platform_handle()); - + if (!success) + delete params; return success; } @@ -154,11 +193,6 @@ PlatformThreadId PlatformThread::CurrentId() { #endif } -//static -PlatformThreadHandle PlatformThread::CurrentHandle() { - return PlatformThreadHandle(pthread_self(), CurrentId()); -} - // static void PlatformThread::YieldCurrentThread() { sched_yield(); @@ -179,6 +213,42 @@ void PlatformThread::Sleep(TimeDelta duration) { sleep_time = remaining; } +#if defined(OS_LINUX) +// static +void PlatformThread::SetName(const char* name) { + ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name); + tracked_objects::ThreadData::InitializeThreadContext(name); + + // On linux we can get the thread names to show up in the debugger by setting + // the process name for the LWP. We don't want to do this for the main + // thread because that would rename the process, causing tools like killall + // to stop working. + if (PlatformThread::CurrentId() == getpid()) + return; + + // http://0pointer.de/blog/projects/name-your-threads.html + // Set the name for the LWP (which gets truncated to 15 characters). + // Note that glibc also has a 'pthread_setname_np' api, but it may not be + // available everywhere and it's only benefit over using prctl directly is + // that it can set the name of threads other than the current thread. + int err = prctl(PR_SET_NAME, name); + // We expect EPERM failures in sandboxed processes, just ignore those. + if (err < 0 && errno != EPERM) + DPLOG(ERROR) << "prctl(PR_SET_NAME)"; +} +#elif defined(OS_MACOSX) +// Mac is implemented in platform_thread_mac.mm. +#else +// static +void PlatformThread::SetName(const char* name) { + ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name); + tracked_objects::ThreadData::InitializeThreadContext(name); + + // (This should be relatively simple to implement for the BSDs; I + // just don't have one handy to test the code on.) +} +#endif // defined(OS_LINUX) + // static const char* PlatformThread::GetName() { return ThreadIdNameManager::GetInstance()->GetName(CurrentId()); @@ -187,7 +257,6 @@ const char* PlatformThread::GetName() { // static bool PlatformThread::Create(size_t stack_size, Delegate* delegate, PlatformThreadHandle* thread_handle) { - base::ThreadRestrictions::ScopedAllowWait allow_wait; return CreateThread(stack_size, true /* joinable thread */, delegate, thread_handle, kThreadPriority_Normal); } @@ -196,7 +265,6 @@ bool PlatformThread::Create(size_t stack_size, Delegate* delegate, bool PlatformThread::CreateWithPriority(size_t stack_size, Delegate* delegate, PlatformThreadHandle* thread_handle, ThreadPriority priority) { - base::ThreadRestrictions::ScopedAllowWait allow_wait; return CreateThread(stack_size, true, // joinable thread delegate, thread_handle, priority); } @@ -205,7 +273,6 @@ bool PlatformThread::CreateWithPriority(size_t stack_size, Delegate* delegate, bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) { PlatformThreadHandle unused; - base::ThreadRestrictions::ScopedAllowWait allow_wait; bool result = CreateThread(stack_size, false /* non-joinable thread */, delegate, &unused, kThreadPriority_Normal); return result; @@ -217,7 +284,21 @@ void PlatformThread::Join(PlatformThreadHandle thread_handle) { // the thread referred to by |thread_handle| may still be running long-lived / // blocking tasks. base::ThreadRestrictions::AssertIOAllowed(); - pthread_join(thread_handle.handle_, NULL); + pthread_join(thread_handle, NULL); +} + +#if !defined(OS_MACOSX) && !defined(OS_ANDROID) +// Mac OS X uses lower-level mach APIs and Android uses Java APIs. +// static +void PlatformThread::SetThreadPriority(PlatformThreadHandle, ThreadPriority) { + // TODO(crogers): Implement, see http://crbug.com/116172 +} +#endif + +#if defined(OS_ANDROID) +bool RegisterThreadUtils(JNIEnv* env) { + return RegisterNativesImpl(env); } +#endif // defined(OS_ANDROID) } // namespace base diff --git a/base/threading/platform_thread_win.cc b/base/threading/platform_thread_win.cc index 637fdfe..9e877b3 100644 --- a/base/threading/platform_thread_win.cc +++ b/base/threading/platform_thread_win.cc @@ -64,6 +64,7 @@ DWORD __stdcall ThreadFunc(void* params) { bool CreateThreadInternal(size_t stack_size, PlatformThread::Delegate* delegate, PlatformThreadHandle* out_thread_handle) { + PlatformThreadHandle thread_handle; unsigned int flags = 0; if (stack_size > 0 && base::win::GetVersion() >= base::win::VERSION_XP) { flags = STACK_SIZE_PARAM_IS_A_RESERVATION; @@ -80,7 +81,7 @@ bool CreateThreadInternal(size_t stack_size, // 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 - void* thread_handle = CreateThread( + thread_handle = CreateThread( NULL, stack_size, ThreadFunc, params, flags, NULL); if (!thread_handle) { delete params; @@ -88,7 +89,7 @@ bool CreateThreadInternal(size_t stack_size, } if (out_thread_handle) - *out_thread_handle = PlatformThreadHandle(thread_handle); + *out_thread_handle = thread_handle; else CloseHandle(thread_handle); return true; @@ -102,12 +103,6 @@ PlatformThreadId PlatformThread::CurrentId() { } // static -PlatformThreadHandle PlatformThread::CurrentHandle() { - NOTIMPLEMENTED(); // See OpenThread() - return kNullThreadHandle; -} - -// static void PlatformThread::YieldCurrentThread() { ::Sleep(0); } @@ -169,7 +164,7 @@ bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) { // static void PlatformThread::Join(PlatformThreadHandle thread_handle) { - DCHECK(thread_handle.handle_); + DCHECK(thread_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 @@ -181,17 +176,17 @@ void PlatformThread::Join(PlatformThreadHandle thread_handle) { // Wait for the thread to exit. It should already have terminated but make // sure this assumption is valid. - DWORD result = WaitForSingleObject(thread_handle.handle_, INFINITE); + DWORD result = WaitForSingleObject(thread_handle, INFINITE); if (result != WAIT_OBJECT_0) { // Debug info for bug 127931. DWORD error = GetLastError(); debug::Alias(&error); debug::Alias(&result); - debug::Alias(&thread_handle.handle_); + debug::Alias(&thread_handle); CHECK(false); } - CloseHandle(thread_handle.handle_); + CloseHandle(thread_handle); } // static @@ -199,13 +194,10 @@ void PlatformThread::SetThreadPriority(PlatformThreadHandle handle, ThreadPriority priority) { switch (priority) { case kThreadPriority_Normal: - ::SetThreadPriority(handle.handle_, THREAD_PRIORITY_NORMAL); + ::SetThreadPriority(handle, THREAD_PRIORITY_NORMAL); break; case kThreadPriority_RealtimeAudio: - ::SetThreadPriority(handle.handle_, THREAD_PRIORITY_TIME_CRITICAL); - break; - default: - NOTREACHED() << "Unknown priority."; + ::SetThreadPriority(handle, THREAD_PRIORITY_TIME_CRITICAL); break; } } diff --git a/base/threading/thread.cc b/base/threading/thread.cc index 8b3dc2b..35e88a7 100644 --- a/base/threading/thread.cc +++ b/base/threading/thread.cc @@ -148,13 +148,6 @@ bool Thread::IsRunning() const { return running_; } -void Thread::SetPriority(ThreadPriority priority) { - // The thread must be started (and id known) for this to be - // compatible with all platforms. - DCHECK_NE(thread_id_, kInvalidThreadId); - PlatformThread::SetThreadPriority(thread_, priority); -} - void Thread::Run(MessageLoop* message_loop) { message_loop->Run(); } diff --git a/base/threading/thread.h b/base/threading/thread.h index 15f73a0..cf1a86d 100644 --- a/base/threading/thread.h +++ b/base/threading/thread.h @@ -142,9 +142,6 @@ class BASE_EXPORT Thread : PlatformThread::Delegate { // Returns true if the thread has been started, and not yet stopped. bool IsRunning() const; - // Sets the thread priority. The thread must already be started. - void SetPriority(ThreadPriority priority); - protected: // Called just prior to starting the message loop virtual void Init() {} diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h index 5abc8dc9..51cfa27 100644 --- a/base/threading/thread_restrictions.h +++ b/base/threading/thread_restrictions.h @@ -182,7 +182,6 @@ class BASE_EXPORT ThreadRestrictions { friend class SimpleThread; friend class Thread; friend class ThreadTestHelper; - friend class PlatformThread; // END ALLOWED USAGE. // BEGIN USAGE THAT NEEDS TO BE FIXED. |