1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
// 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/prctl.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) should change the whole thread group's (i.e. process)
// priority. however, on linux it will only change the target thread's
// priority. see the bugs section in
// http://man7.org/linux/man-pages/man2/getpriority.2.html.
// we prefer using 0 rather than the current thread id since they are
// equivalent but it makes sandboxing easier (https://crbug.com/399473).
DCHECK_NE(handle.id_, kInvalidThreadId);
int kNiceSetting = ThreadNiceValue(priority);
const PlatformThreadId current_id = PlatformThread::CurrentId();
if (setpriority(PRIO_PROCESS,
handle.id_ == current_id ? 0 : 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);
// Like linux, on android 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;
// Set the name for the LWP (which gets truncated to 15 characters).
int err = prctl(PR_SET_NAME, name);
if (err < 0 && errno != EPERM)
DPLOG(ERROR) << "prctl(PR_SET_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) {
#if !defined(ADDRESS_SANITIZER)
return 0;
#else
// AddressSanitizer bloats the stack approximately 2x. Default stack size of
// 1Mb is not enough for some tests (see http://crbug.com/263749 for example).
return 2 * (1 << 20); // 2Mb
#endif
}
bool RegisterThreadUtils(JNIEnv* env) {
return RegisterNativesImpl(env);
}
} // namespace base
|