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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/threading/platform_thread.h" 5 #include "base/threading/platform_thread.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <sched.h> 8 #include <sched.h>
9 9
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
(...skipping 12 matching lines...) Expand all
23 #if defined(OS_LINUX) 23 #if defined(OS_LINUX)
24 #include <sys/prctl.h> 24 #include <sys/prctl.h>
25 #include <sys/resource.h> 25 #include <sys/resource.h>
26 #include <sys/syscall.h> 26 #include <sys/syscall.h>
27 #include <sys/time.h> 27 #include <sys/time.h>
28 #include <unistd.h> 28 #include <unistd.h>
29 #endif 29 #endif
30 30
31 #if defined(OS_ANDROID) 31 #if defined(OS_ANDROID)
32 #include <sys/resource.h> 32 #include <sys/resource.h>
33 #include "base/android/jni_android.h"
33 #include "base/android/thread_utils.h" 34 #include "base/android/thread_utils.h"
34 #include "jni/ThreadUtils_jni.h" 35 #include "jni/ThreadUtils_jni.h"
35 #endif 36 #endif
36 37
37 // TODO(bbudge) Use time.h when NaCl toolchain supports _POSIX_TIMERS 38 // TODO(bbudge) Use time.h when NaCl toolchain supports _POSIX_TIMERS
38 #if defined(OS_NACL) 39 #if defined(OS_NACL)
39 #include <sys/nacl_syscalls.h> 40 #include <sys/nacl_syscalls.h>
40 #endif 41 #endif
41 42
42 namespace base { 43 namespace base {
43 44
44 #if defined(OS_MACOSX) 45 #if defined(OS_MACOSX)
45 void InitThreading(); 46 void InitThreading();
46 #endif 47 #endif
47 48
48 namespace { 49 namespace {
49 50
50 struct ThreadParams { 51 struct ThreadParams {
51 PlatformThread::Delegate* delegate; 52 PlatformThread::Delegate* delegate;
52 bool joinable; 53 bool joinable;
53 ThreadPriority priority; 54 ThreadPriority priority;
54 }; 55 };
55 56
56 void SetCurrentThreadPriority(ThreadPriority priority) { 57
57 #if defined(OS_LINUX) || defined(OS_ANDROID) 58 int NiceValue(ThreadPriority priority) {
59 // These nice values are taken from Android, which uses nice
60 // values like linux, but defines some preset nice values.
61 // Process.THREAD_PRIORITY_AUDIO = -16
62 // Process.THREAD_PRIORITY_BACKGROUND = 10
63 // Process.THREAD_PRIORITY_DEFAULT = 0;
64 // Process.THREAD_PRIORITY_DISPLAY = -4;
65 // Process.THREAD_PRIORITY_FOREGROUND = -2;
66 // Process.THREAD_PRIORITY_LESS_FAVORABLE = 1;
67 // Process.THREAD_PRIORITY_LOWEST = 19;
68 // Process.THREAD_PRIORITY_MORE_FAVORABLE = -1;
69 // Process.THREAD_PRIORITY_URGENT_AUDIO = -19;
70 // Process.THREAD_PRIORITY_URGENT_DISPLAY = -8;
71 // 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
72 // into urgent (-8) and non-urgent (-4).
73 #if defined(OS_ANDROID)
74 static const int threadPriorityAudio = -16;
75 #else
76 // TODO(epenner): Can we just use -16 on linux as well?
77 static const int threadPriorityAudio = -10;
78 #endif
79 static const int threadPriorityBackground = 10;
80 static const int threadPriorityDefault = 0;
81 static const int threadPriorityDisplay = 6;
58 switch (priority) { 82 switch (priority) {
83 case kThreadPriority_RealtimeAudio:
84 return threadPriorityAudio;
85 case kThreadPriority_Background:
86 return threadPriorityBackground;
59 case kThreadPriority_Normal: 87 case kThreadPriority_Normal:
60 NOTREACHED() << "Don't reset priority as not all processes can."; 88 return threadPriorityDefault;
61 break; 89 case kThreadPriority_Display:
62 case kThreadPriority_RealtimeAudio: 90 return threadPriorityDisplay;
63 #if defined(OS_LINUX) 91 default:
64 const int kNiceSetting = -10; 92 NOTREACHED() << "Unknown priority.";
65 // Linux isn't posix compliant with setpriority(2), it will set a thread 93 return 0;
66 // priority if it is passed a tid, not affecting the rest of the threads
67 // in the process. Setting this priority will only succeed if the user
68 // has been granted permission to adjust nice values on the system.
69 if (setpriority(PRIO_PROCESS, PlatformThread::CurrentId(), kNiceSetting))
70 DVLOG(1) << "Failed to set nice value of thread to " << kNiceSetting;
71 #elif defined(OS_ANDROID)
72 JNIEnv* env = base::android::AttachCurrentThread();
73 Java_ThreadUtils_setThreadPriorityAudio(env, PlatformThread::CurrentId());
74 #endif // defined(OS_LINUX)
75 break;
76 } 94 }
77 #else // !defined(OS_LINUX) && !defined(OS_ANDROID)
78 PlatformThread::SetThreadPriority(pthread_self(), priority);
79 #endif
80 } 95 }
81 96
82 void* ThreadFunc(void* params) { 97 void* ThreadFunc(void* params) {
83 #if defined(OS_ANDROID)
84 // Threads on linux/android may inherit their priority from the thread
85 // where they were created. This sets all threads to the default.
86 // TODO(epenner): Move thread priorities to base. (crbug.com/170549)
87 if (setpriority(PRIO_PROCESS, PlatformThread::CurrentId(), 0))
88 DVLOG(1) << "Failed to reset initial thread nice value to zero.";
89 #endif
90 ThreadParams* thread_params = static_cast<ThreadParams*>(params); 98 ThreadParams* thread_params = static_cast<ThreadParams*>(params);
91 PlatformThread::Delegate* delegate = thread_params->delegate; 99 PlatformThread::Delegate* delegate = thread_params->delegate;
92 if (!thread_params->joinable) 100 if (!thread_params->joinable)
93 base::ThreadRestrictions::SetSingletonAllowed(false); 101 base::ThreadRestrictions::SetSingletonAllowed(false);
94 102
95 // If there is a non-default priority for this thread, set it now. 103 #if defined(OS_ANDROID) || defined(OS_LINUX)
96 if (thread_params->priority != kThreadPriority_Normal) 104 // Threads on linux/android may inherit their priority from the thread
97 SetCurrentThreadPriority(thread_params->priority); 105 // where they were created. We may also not be allowed to set the
106 // priority on some processes, so we query it first and only
107 // change it if needed.
108 errno = 0; // getpriority may return -1 so we need to use errno.
109 int prio = getpriority(PRIO_PROCESS, PlatformThread::CurrentId());
110 bool error = prio == -1 && errno != 0;
111 if (error)
112 LOG(ERROR) << "Failed to get thread nice value";
113 // Set the priority if needed
114 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
115 PlatformThread::SetThreadPriority(pthread_self(),
116 PlatformThread::CurrentId(),
117 thread_params->priority);
118 }
119 #else
120 PlatformThread::SetThreadPriority(pthread_self(),
121 PlatformThread::CurrentId(),
122 thread_params->priority);
123 #endif
98 124
99 delete thread_params; 125 delete thread_params;
100 delegate->ThreadMain(); 126 delegate->ThreadMain();
101 #if defined(OS_ANDROID) 127 #if defined(OS_ANDROID)
102 base::android::DetachFromVM(); 128 base::android::DetachFromVM();
103 #endif 129 #endif
104 return NULL; 130 return NULL;
105 } 131 }
106 132
107 bool CreateThread(size_t stack_size, bool joinable, 133 bool CreateThread(size_t stack_size, bool joinable,
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 311
286 // static 312 // static
287 void PlatformThread::Join(PlatformThreadHandle thread_handle) { 313 void PlatformThread::Join(PlatformThreadHandle thread_handle) {
288 // Joining another thread may block the current thread for a long time, since 314 // Joining another thread may block the current thread for a long time, since
289 // the thread referred to by |thread_handle| may still be running long-lived / 315 // the thread referred to by |thread_handle| may still be running long-lived /
290 // blocking tasks. 316 // blocking tasks.
291 base::ThreadRestrictions::AssertIOAllowed(); 317 base::ThreadRestrictions::AssertIOAllowed();
292 pthread_join(thread_handle, NULL); 318 pthread_join(thread_handle, NULL);
293 } 319 }
294 320
295 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) 321 #if !defined(OS_MACOSX)
296 // Mac OS X uses lower-level mach APIs and Android uses Java APIs. 322 // Mac OS X uses lower-level mach APIs
297 // static 323 void PlatformThread::SetThreadPriority(PlatformThreadHandle,
298 void PlatformThread::SetThreadPriority(PlatformThreadHandle, ThreadPriority) { 324 PlatformThreadId id,
299 // TODO(crogers): Implement, see http://crbug.com/116172 325 ThreadPriority priority) {
326 // setpriority(2) will set a thread's priority if it is passed a tid as
327 // the 'process identifier', not affecting the rest of the threads in the
328 // process. Setting this priority will only succeed if the user has been
329 // granted permission to adjust nice values on the system.
330 #if defined(OS_ANDROID)
331 // On Android, we set the Audio priority through JNI as Audio priority
332 // will also allow the process to run while it is backgrounded.
333 if (priority == kThreadPriority_RealtimeAudio) {
334 JNIEnv* env = base::android::AttachCurrentThread();
335 Java_ThreadUtils_setThreadPriorityAudio(env, PlatformThread::CurrentId());
336 return;
337 }
338 #endif
339 #if !defined(OS_NACL)
340 DCHECK_NE(id, kInvalidThreadId);
341 int kNiceSetting = NiceValue(priority);
342 if (setpriority(PRIO_PROCESS, id, kNiceSetting))
343 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.
344 #endif
300 } 345 }
301 #endif 346 #endif
302 347
303 #if defined(OS_ANDROID) 348 #if defined(OS_ANDROID)
304 bool RegisterThreadUtils(JNIEnv* env) { 349 bool RegisterThreadUtils(JNIEnv* env) {
305 return RegisterNativesImpl(env); 350 return RegisterNativesImpl(env);
306 } 351 }
307 #endif // defined(OS_ANDROID) 352 #endif // defined(OS_ANDROID)
308 353
309 } // namespace base 354 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698