Chromium Code Reviews| 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 |