forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@201202 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
epenner@chromium.org
committed
May 21, 2013
1 parent
f398851
commit a688c89
Showing
18 changed files
with
434 additions
and
186 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// 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 |
Oops, something went wrong.