Skip to content

Commit df3ab4a

Browse files
gkastenAndroid (Google) Code Review
authored andcommitted
Merge "Scheduling policy service"
2 parents 69c1a57 + 07b0465 commit df3ab4a

File tree

7 files changed

+159
-2
lines changed

7 files changed

+159
-2
lines changed

Android.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ LOCAL_SRC_FILES += \
132132
core/java/android/os/IPermissionController.aidl \
133133
core/java/android/os/IPowerManager.aidl \
134134
core/java/android/os/IRemoteCallback.aidl \
135+
core/java/android/os/ISchedulingPolicyService.aidl \
135136
core/java/android/os/IUpdateLock.aidl \
136137
core/java/android/os/IVibratorService.aidl \
137138
core/java/android/service/dreams/IDreamManager.aidl \

core/java/android/content/Context.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,6 +1927,17 @@ public abstract boolean startInstrumentation(ComponentName className,
19271927
*/
19281928
public static final String INPUT_SERVICE = "input";
19291929

1930+
/**
1931+
* Use with {@link #getSystemService} to retrieve a
1932+
* {@link android.os.SchedulingPolicyService} for managing scheduling policy.
1933+
*
1934+
* @see #getSystemService
1935+
* @see android.os.SchedulingPolicyService
1936+
*
1937+
* @hide
1938+
*/
1939+
public static final String SCHEDULING_POLICY_SERVICE = "scheduling_policy";
1940+
19301941
/**
19311942
* Determine whether the given permission is allowed for a particular
19321943
* process and user ID running in the system.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (C) 2012 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package android.os;
18+
19+
/**
20+
* Initially only provides requestPriority() below, but in longer term
21+
* other scheduling policy related services will be collected here.
22+
*
23+
* @hide
24+
*/
25+
interface ISchedulingPolicyService {
26+
27+
/**
28+
* Move thread tid into appropriate cgroup and assign it priority prio.
29+
* The thread group leader of tid must be pid.
30+
* There may be restrictions on who can call this.
31+
*/
32+
int requestPriority(int pid, int tid, int prio);
33+
34+
}

core/java/android/os/Process.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,24 @@ public class Process {
299299
**/
300300
private static final int THREAD_GROUP_FOREGROUND = 1;
301301

302+
/**
303+
* System thread group.
304+
* @hide
305+
**/
306+
public static final int THREAD_GROUP_SYSTEM = 2;
307+
308+
/**
309+
* Application audio thread group.
310+
* @hide
311+
**/
312+
public static final int THREAD_GROUP_AUDIO_APP = 3;
313+
314+
/**
315+
* System audio thread group.
316+
* @hide
317+
**/
318+
public static final int THREAD_GROUP_AUDIO_SYS = 4;
319+
302320
public static final int SIGNAL_QUIT = 3;
303321
public static final int SIGNAL_KILL = 9;
304322
public static final int SIGNAL_USR1 = 10;
@@ -657,6 +675,21 @@ public static final int getParentPid(int pid) {
657675
return (int) procStatusValues[0];
658676
}
659677

678+
/**
679+
* Returns the thread group leader id for a currently running thread.
680+
* @param tid the thread id
681+
* @return the thread group leader id of the thread, or -1 if the thread is not running.
682+
* This is same as what getpid(2) would return if called by tid.
683+
* @hide
684+
*/
685+
public static final int getThreadGroupLeader(int tid) {
686+
String[] procStatusLabels = { "Tgid:" };
687+
long[] procStatusValues = new long[1];
688+
procStatusValues[0] = -1;
689+
Process.readProcLines("/proc/" + tid + "/status", procStatusLabels, procStatusValues);
690+
return (int) procStatusValues[0];
691+
}
692+
660693
/**
661694
* Set the priority of a thread, based on Linux priorities.
662695
*
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (C) 2012 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package android.os;
18+
19+
import android.content.Context;
20+
import android.content.pm.PackageManager;
21+
import android.os.Binder;
22+
import android.os.Process;
23+
import android.util.Log;
24+
25+
/**
26+
* The implementation of the scheduling policy service interface.
27+
*
28+
* @hide
29+
*/
30+
public class SchedulingPolicyService extends ISchedulingPolicyService.Stub {
31+
32+
private static final String TAG = "SchedulingPolicyService";
33+
34+
// Minimum and maximum values allowed for requestPriority parameter prio
35+
private static final int PRIORITY_MIN = 1;
36+
private static final int PRIORITY_MAX = 2;
37+
38+
public SchedulingPolicyService() {
39+
}
40+
41+
public int requestPriority(int pid, int tid, int prio) {
42+
//Log.i(TAG, "requestPriority(pid=" + pid + ", tid=" + tid + ", prio=" + prio + ")");
43+
44+
// Verify that caller is mediaserver, priority is in range, and that the
45+
// callback thread specified by app belongs to the app that called mediaserver.
46+
// Once we've verified that the caller is mediaserver, we can trust the pid but
47+
// we can't trust the tid. No need to explicitly check for pid == 0 || tid == 0,
48+
// since if not the case then the getThreadGroupLeader() test will also fail.
49+
if (Binder.getCallingUid() != Process.MEDIA_UID || prio < PRIORITY_MIN ||
50+
prio > PRIORITY_MAX || Process.getThreadGroupLeader(tid) != pid) {
51+
return PackageManager.PERMISSION_DENIED;
52+
}
53+
try {
54+
// make good use of our CAP_SYS_NICE capability
55+
Process.setThreadGroup(tid, Binder.getCallingPid() == pid ?
56+
Process.THREAD_GROUP_AUDIO_SYS : Process.THREAD_GROUP_AUDIO_APP);
57+
// must be in this order or it fails the schedulability constraint
58+
Process.setThreadScheduler(tid, Process.SCHED_FIFO, prio);
59+
} catch (RuntimeException e) {
60+
return PackageManager.PERMISSION_DENIED;
61+
}
62+
return PackageManager.PERMISSION_GRANTED;
63+
}
64+
65+
}

core/jni/android_util_Process.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,17 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
242242
continue;
243243
}
244244

245-
if (isDefault) {
246-
t_pri = getpriority(PRIO_PROCESS, t_pid);
245+
t_pri = getpriority(PRIO_PROCESS, t_pid);
246+
247+
if (t_pri <= ANDROID_PRIORITY_AUDIO) {
248+
int scheduler = sched_getscheduler(t_pid);
249+
if ((scheduler == SCHED_FIFO) || (scheduler == SCHED_RR)) {
250+
// This task wants to stay in it's current audio group so it can keep it's budget
251+
continue;
252+
}
253+
}
247254

255+
if (isDefault) {
248256
if (t_pri >= ANDROID_PRIORITY_BACKGROUND) {
249257
// This task wants to stay at background
250258
continue;

services/java/com/android/server/SystemServer.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import android.net.wifi.p2p.WifiP2pService;
3131
import android.os.Looper;
3232
import android.os.RemoteException;
33+
import android.os.SchedulingPolicyService;
3334
import android.os.ServiceManager;
3435
import android.os.StrictMode;
3536
import android.os.SystemClock;
@@ -155,6 +156,10 @@ public void run() {
155156
Slog.i(TAG, "Telephony Registry");
156157
ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));
157158

159+
Slog.i(TAG, "Scheduling Policy");
160+
ServiceManager.addService(Context.SCHEDULING_POLICY_SERVICE,
161+
new SchedulingPolicyService());
162+
158163
AttributeCache.init(context);
159164

160165
Slog.i(TAG, "Package Manager");

0 commit comments

Comments
 (0)