summaryrefslogtreecommitdiffstats
path: root/base/threading
diff options
context:
space:
mode:
authorscottmg@chromium.org <scottmg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-21 03:57:12 +0000
committerscottmg@chromium.org <scottmg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-21 03:57:12 +0000
commit5686b177b4c9de40440ccd60546529b8a4522cd1 (patch)
tree5724cad21e7ee040c06bf3a68c67e55237fbf404 /base/threading
parent41cea7ac73afdc41854ddab97f8f1b00541e603d (diff)
downloadchromium_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.h66
-rw-r--r--base/threading/platform_thread_android.cc105
-rw-r--r--base/threading/platform_thread_linux.cc103
-rw-r--r--base/threading/platform_thread_mac.mm48
-rw-r--r--base/threading/platform_thread_posix.cc201
-rw-r--r--base/threading/platform_thread_win.cc26
-rw-r--r--base/threading/thread.cc7
-rw-r--r--base/threading/thread.h3
-rw-r--r--base/threading/thread_restrictions.h1
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,
- &params);
+ 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.