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 #define LOG_TAG "SchedulingPolicyService"
18 //#define LOG_NDEBUG 0
19
20 #include <audio_utils/threads.h>
21 #include <binder/IServiceManager.h>
22 #include <cutils/android_filesystem_config.h>
23 #include <cutils/properties.h>
24 #include <utils/Mutex.h>
25 #include "ISchedulingPolicyService.h"
26 #include "mediautils/SchedulingPolicyService.h"
27
28 namespace android {
29
30 static sp<ISchedulingPolicyService> sSchedulingPolicyService;
31 static const String16 _scheduling_policy("scheduling_policy");
32 static Mutex sMutex;
33
requestPriority(pid_t pid,pid_t tid,int32_t prio,bool isForApp,bool asynchronous)34 int requestPriority(pid_t pid, pid_t tid, int32_t prio, bool isForApp, bool asynchronous)
35 {
36 // audioserver thread priority boosted internally to reduce binder latency and boot time.
37 if (!isForApp && pid == getpid() && getuid() == AID_AUDIOSERVER && prio >= 1 && prio <= 3) {
38 const status_t status = audio_utils::set_thread_priority(
39 tid, audio_utils::rtprio_to_unified_priority(prio));
40 if (status == NO_ERROR) return NO_ERROR;
41 ALOGD("%s: set priority %d, status:%d needs to fallback to SchedulingPolicyService",
42 __func__, prio, status);
43 }
44
45 // FIXME merge duplicated code related to service lookup, caching, and error recovery
46 int ret;
47 for (;;) {
48 sMutex.lock();
49 sp<ISchedulingPolicyService> sps = sSchedulingPolicyService;
50 sMutex.unlock();
51 if (sps == 0) {
52 sp<IBinder> binder = defaultServiceManager()->checkService(_scheduling_policy);
53 if (binder == 0) {
54 sleep(1);
55 continue;
56 }
57 sps = interface_cast<ISchedulingPolicyService>(binder);
58 sMutex.lock();
59 sSchedulingPolicyService = sps;
60 sMutex.unlock();
61 }
62 ret = sps->requestPriority(pid, tid, prio, isForApp, asynchronous);
63 if (ret != DEAD_OBJECT) {
64 break;
65 }
66 ALOGW("SchedulingPolicyService died");
67 sMutex.lock();
68 sSchedulingPolicyService.clear();
69 sMutex.unlock();
70 }
71 return ret;
72 }
73
requestCpusetBoost(bool enable,const sp<IBinder> & client)74 int requestCpusetBoost(bool enable, const sp<IBinder> &client)
75 {
76 int ret;
77 sMutex.lock();
78 sp<ISchedulingPolicyService> sps = sSchedulingPolicyService;
79 sMutex.unlock();
80 if (sps == 0) {
81 sp<IBinder> binder = defaultServiceManager()->checkService(_scheduling_policy);
82 if (binder == 0) {
83 return DEAD_OBJECT;
84 }
85 sps = interface_cast<ISchedulingPolicyService>(binder);
86 sMutex.lock();
87 sSchedulingPolicyService = sps;
88 sMutex.unlock();
89 }
90 ret = sps->requestCpusetBoost(enable, client);
91 if (ret != DEAD_OBJECT) {
92 return ret;
93 }
94 ALOGW("SchedulingPolicyService died");
95 sMutex.lock();
96 sSchedulingPolicyService.clear();
97 sMutex.unlock();
98 return ret;
99 }
100
requestSpatializerPriority(pid_t pid,pid_t tid)101 int requestSpatializerPriority(pid_t pid, pid_t tid) {
102 if (pid == -1 || tid == -1) return BAD_VALUE;
103
104 // update priority to RT if specified.
105 constexpr int32_t kRTPriorityMin = 1;
106 constexpr int32_t kRTPriorityMax = 3;
107 const int32_t priorityBoost =
108 property_get_int32("audio.spatializer.priority", kRTPriorityMin);
109 if (priorityBoost >= kRTPriorityMin && priorityBoost <= kRTPriorityMax) {
110 const status_t status = requestPriority(
111 pid, tid, priorityBoost, false /* isForApp */, true /*asynchronous*/);
112 if (status != OK) {
113 ALOGW("%s: Cannot request spatializer priority boost %d, status:%d",
114 __func__, priorityBoost, status);
115 return status < 0 ? status : UNKNOWN_ERROR;
116 }
117 return priorityBoost;
118 }
119 return 0; // no boost requested
120 }
121
122 } // namespace android
123