Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(628)

Unified Diff: base/threading/platform_thread_posix.cc

Issue 12741012: base: Support setting thread priorities generically. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added back JNI for Audio. Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/threading/platform_thread_posix.cc
diff --git a/base/threading/platform_thread_posix.cc b/base/threading/platform_thread_posix.cc
index 0fb2a8a2258068af1a1393201b530483d0d475f7..5f4b6d1d18768b04e821533d78e40816073a599f 100644
--- a/base/threading/platform_thread_posix.cc
+++ b/base/threading/platform_thread_posix.cc
@@ -30,6 +30,7 @@
#if defined(OS_ANDROID)
#include <sys/resource.h>
+#include "base/android/jni_android.h"
#include "base/android/thread_utils.h"
#include "jni/ThreadUtils_jni.h"
#endif
@@ -53,48 +54,73 @@ struct ThreadParams {
ThreadPriority priority;
};
-void SetCurrentThreadPriority(ThreadPriority priority) {
-#if defined(OS_LINUX) || defined(OS_ANDROID)
+
+int NiceValue(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
jar (doing other things) 2013/04/24 01:04:57 This comment does not relate well to line 64 or 70
epenner 2013/04/30 04:37:08 Thanks! This was a typo. It should be -6 below. D
+ // into urgent (-8) and non-urgent (-4).
+#if defined(OS_ANDROID)
+ static const int threadPriorityAudio = -16;
+#else
+ // TODO(epenner): Can we just use -16 on linux as well?
+ static const int threadPriorityAudio = -10;
+#endif
+ static const int threadPriorityBackground = 10;
+ static const int threadPriorityDefault = 0;
+ static const int threadPriorityDisplay = 6;
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;
+ return threadPriorityAudio;
+ case kThreadPriority_Background:
+ return threadPriorityBackground;
+ case kThreadPriority_Normal:
+ return threadPriorityDefault;
+ case kThreadPriority_Display:
+ return threadPriorityDisplay;
+ default:
+ NOTREACHED() << "Unknown priority.";
+ return 0;
}
-#else // !defined(OS_LINUX) && !defined(OS_ANDROID)
- PlatformThread::SetThreadPriority(pthread_self(), priority);
-#endif
}
void* ThreadFunc(void* params) {
-#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 there is a non-default priority for this thread, set it now.
- if (thread_params->priority != kThreadPriority_Normal)
- SetCurrentThreadPriority(thread_params->priority);
+#if defined(OS_ANDROID) || defined(OS_LINUX)
+ // Threads on linux/android may inherit their priority from the thread
+ // where they were created. We may also not be allowed to set the
+ // priority on some processes, so we query it first and only
+ // change it if needed.
+ errno = 0; // getpriority may return -1 so we need to use errno.
+ int prio = getpriority(PRIO_PROCESS, PlatformThread::CurrentId());
+ bool error = prio == -1 && errno != 0;
+ if (error)
+ LOG(ERROR) << "Failed to get thread nice value";
+ // Set the priority if needed
+ if (!error && prio != NiceValue(thread_params->priority)) {
jar (doing other things) 2013/04/24 01:04:57 nit: Given the up-front-comment, I'd rather see an
epenner 2013/04/30 04:37:08 This has moved into SetThreadPriority now, I think
+ PlatformThread::SetThreadPriority(pthread_self(),
+ PlatformThread::CurrentId(),
+ thread_params->priority);
+ }
+#else
+ PlatformThread::SetThreadPriority(pthread_self(),
+ PlatformThread::CurrentId(),
+ thread_params->priority);
+#endif
delete thread_params;
delegate->ThreadMain();
@@ -292,11 +318,30 @@ void PlatformThread::Join(PlatformThreadHandle thread_handle) {
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
+#if !defined(OS_MACOSX)
+// Mac OS X uses lower-level mach APIs
+void PlatformThread::SetThreadPriority(PlatformThreadHandle,
+ PlatformThreadId id,
+ ThreadPriority priority) {
+ // 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.
+#if defined(OS_ANDROID)
+ // 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;
+ }
+#endif
+#if !defined(OS_NACL)
+ DCHECK_NE(id, kInvalidThreadId);
+ int kNiceSetting = NiceValue(priority);
+ if (setpriority(PRIO_PROCESS, id, kNiceSetting))
+ LOG(ERROR) << "Failed to set nice value of thread to " << kNiceSetting;
jar (doing other things) 2013/04/24 01:04:57 DLOG is generally preferred. No one will read thi
epenner 2013/04/30 04:37:08 Done.
+#endif
}
#endif

Powered by Google App Engine
This is Rietveld 408576698