1 /******************************************************************************
3 * Copyright (C) 2012 Broadcom Corporation
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 ******************************************************************************/
19 /************************************************************************************
21 * Filename: bt_utils.c
23 * Description: Miscellaneous helper functions
26 ***********************************************************************************/
28 #define LOG_TAG "bt_utils"
36 #include <sys/resource.h>
39 #include <utils/ThreadDefs.h>
40 #include <cutils/sched_policy.h>
42 // TODO(armansito): cutils/properties.h is only being used to pull-in runtime
43 // settings on Android. Remove this conditional include once we have a generic
44 // way to obtain system properties.
45 #if !defined(OS_GENERIC)
46 #include <cutils/properties.h>
47 #endif // !defined(OS_GENERIC)
50 #include "btcore/include/module.h"
51 #include "osi/include/compat.h"
52 #include "osi/include/log.h"
54 /*******************************************************************************
55 ** Type definitions for callback functions
56 ********************************************************************************/
57 static pthread_once_t g_DoSchedulingGroupOnce[TASK_HIGH_MAX];
58 static BOOLEAN g_DoSchedulingGroup[TASK_HIGH_MAX];
59 static pthread_mutex_t gIdxLock;
61 static int g_TaskIDs[TASK_HIGH_MAX];
62 #define INVALID_TASK_ID (-1)
64 static future_t *init(void) {
66 pthread_mutexattr_t lock_attr;
68 for(i = 0; i < TASK_HIGH_MAX; i++) {
69 g_DoSchedulingGroupOnce[i] = PTHREAD_ONCE_INIT;
70 g_DoSchedulingGroup[i] = TRUE;
71 g_TaskIDs[i] = INVALID_TASK_ID;
74 pthread_mutexattr_init(&lock_attr);
75 pthread_mutex_init(&gIdxLock, &lock_attr);
79 static future_t *clean_up(void) {
80 pthread_mutex_destroy(&gIdxLock);
84 EXPORT_SYMBOL const module_t bt_utils_module = {
85 .name = BT_UTILS_MODULE,
95 // TODO(armansito): Remove this conditional code once there is a generic way
96 // to obtain system properties. System properties are only available on
97 // Android. Don't do the following check if this is a generic build.
98 #if !defined(OS_GENERIC)
99 /*****************************************************************************
101 ** Function check_do_scheduling_group
103 ** Description check if it is ok to change schedule group
107 *******************************************************************************/
108 static void check_do_scheduling_group(void) {
109 char buf[PROPERTY_VALUE_MAX];
110 int len = property_get("debug.sys.noschedgroups", buf, "");
113 if (sscanf(buf, "%d", &temp) == 1) {
114 g_DoSchedulingGroup[g_TaskIdx] = temp == 0;
118 #endif // !defined(OS_GENERIC)
120 /*****************************************************************************
122 ** Function raise_priority_a2dp
124 ** Description Raise task priority for A2DP streaming
128 *******************************************************************************/
129 void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task) {
132 int priority = ANDROID_PRIORITY_AUDIO;
134 pthread_mutex_lock(&gIdxLock);
135 g_TaskIdx = high_task;
137 // TODO(armansito): Remove this conditional check once we find a solution
138 // for system/core on non-Android platforms.
139 #if defined(OS_GENERIC)
141 #else // !defined(OS_GENERIC)
142 pthread_once(&g_DoSchedulingGroupOnce[g_TaskIdx], check_do_scheduling_group);
143 if (g_DoSchedulingGroup[g_TaskIdx]) {
144 // set_sched_policy does not support tid == 0
145 rc = set_sched_policy(tid, SP_AUDIO_SYS);
147 #endif // defined(OS_GENERIC)
149 g_TaskIDs[high_task] = tid;
150 pthread_mutex_unlock(&gIdxLock);
153 LOG_WARN(LOG_TAG, "failed to change sched policy, tid %d, err: %d", tid, errno);
156 // always use urgent priority for HCI worker thread until we can adjust
157 // its prio individually. All other threads can be dynamically adjusted voa
158 // adjust_priority_a2dp()
160 priority = ANDROID_PRIORITY_URGENT_AUDIO;
162 if (setpriority(PRIO_PROCESS, tid, priority) < 0) {
163 LOG_WARN(LOG_TAG, "failed to change priority tid: %d to %d", tid, priority);
167 /*****************************************************************************
169 ** Function adjust_priority_a2dp
171 ** Description increase the a2dp consumer task priority temporarily when start
172 ** audio playing, to avoid overflow the audio packet queue, restore
173 ** the a2dp consumer task priority when stop audio playing.
177 *******************************************************************************/
178 void adjust_priority_a2dp(int start) {
179 int priority = start ? ANDROID_PRIORITY_URGENT_AUDIO : ANDROID_PRIORITY_AUDIO;
183 for (i = 0; i < TASK_HIGH_MAX; i++)
186 if (tid != INVALID_TASK_ID)
188 if (setpriority(PRIO_PROCESS, tid, priority) < 0)
190 LOG_WARN(LOG_TAG, "failed to change priority tid: %d to %d", tid, priority);