1/****************************************************************************** 2 * 3 * Copyright (C) 2012 Broadcom Corporation 4 * 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: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 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. 16 * 17 ******************************************************************************/ 18 19/************************************************************************************ 20 * 21 * Filename: bt_utils.c 22 * 23 * Description: Miscellaneous helper functions 24 * 25 * 26 ***********************************************************************************/ 27 28#include <cutils/properties.h> 29#include <cutils/sched_policy.h> 30#include <errno.h> 31#include <pthread.h> 32#include <sys/resource.h> 33#include <stdio.h> 34#include <stdlib.h> 35#include <unistd.h> 36#include <utils/ThreadDefs.h> 37 38#define LOG_TAG "BT_UTILS" 39 40#include <utils/Log.h> 41 42#include "data_types.h" 43#include "bt_utils.h" 44 45 46/******************************************************************************* 47** Type definitions for callback functions 48********************************************************************************/ 49static pthread_once_t g_DoSchedulingGroupOnce[TASK_HIGH_MAX]; 50static BOOLEAN g_DoSchedulingGroup[TASK_HIGH_MAX]; 51static pthread_mutex_t gIdxLock; 52static int g_TaskIdx; 53static int g_TaskIDs[TASK_HIGH_MAX]; 54#define INVALID_TASK_ID (-1) 55 56/***************************************************************************** 57** 58** Function bt_utils_init 59** 60** Description Initialize bluedroid util 61** 62** Returns void 63** 64*******************************************************************************/ 65void bt_utils_init() { 66 int i; 67 pthread_mutexattr_t lock_attr; 68 69 for(i = 0; i < TASK_HIGH_MAX; i++) { 70 g_DoSchedulingGroupOnce[i] = PTHREAD_ONCE_INIT; 71 g_DoSchedulingGroup[i] = TRUE; 72 g_TaskIDs[i] = INVALID_TASK_ID; 73 } 74 pthread_mutexattr_init(&lock_attr); 75 pthread_mutex_init(&gIdxLock, &lock_attr); 76} 77 78/***************************************************************************** 79** 80** Function bt_utils_cleanup 81** 82** Description Clean up bluedroid util 83** 84** Returns void 85** 86*******************************************************************************/ 87void bt_utils_cleanup() { 88 pthread_mutex_destroy(&gIdxLock); 89} 90 91/***************************************************************************** 92** 93** Function check_do_scheduling_group 94** 95** Description check if it is ok to change schedule group 96** 97** Returns void 98** 99*******************************************************************************/ 100static void check_do_scheduling_group(void) { 101 char buf[PROPERTY_VALUE_MAX]; 102 int len = property_get("debug.sys.noschedgroups", buf, ""); 103 if (len > 0) { 104 int temp; 105 if (sscanf(buf, "%d", &temp) == 1) { 106 g_DoSchedulingGroup[g_TaskIdx] = temp == 0; 107 } 108 } 109} 110 111/***************************************************************************** 112** 113** Function raise_priority_a2dp 114** 115** Description Raise task priority for A2DP streaming 116** 117** Returns void 118** 119*******************************************************************************/ 120void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task) { 121 int rc = 0; 122 int tid = gettid(); 123 int priority = ANDROID_PRIORITY_AUDIO; 124 125 pthread_mutex_lock(&gIdxLock); 126 g_TaskIdx = high_task; 127 128 pthread_once(&g_DoSchedulingGroupOnce[g_TaskIdx], check_do_scheduling_group); 129 if (g_DoSchedulingGroup[g_TaskIdx]) { 130 // set_sched_policy does not support tid == 0 131 rc = set_sched_policy(tid, SP_AUDIO_SYS); 132 } 133 g_TaskIDs[high_task] = tid; 134 pthread_mutex_unlock(&gIdxLock); 135 136 if (rc) { 137 ALOGW("failed to change sched policy, tid %d, err: %d", tid, errno); 138 } 139 140 // always use urgent priority for HCI worker thread until we can adjust 141 // its prio individually. All other threads can be dynamically adjusted voa 142 // adjust_priority_a2dp() 143 144 if (high_task == TASK_HIGH_HCI_WORKER) 145 priority = ANDROID_PRIORITY_URGENT_AUDIO; 146 147 if (setpriority(PRIO_PROCESS, tid, priority) < 0) { 148 ALOGW("failed to change priority tid: %d to %d", tid, priority); 149 } 150} 151 152/***************************************************************************** 153** 154** Function adjust_priority_a2dp 155** 156** Description increase the a2dp consumer task priority temporarily when start 157** audio playing, to avoid overflow the audio packet queue, restore 158** the a2dp consumer task priority when stop audio playing. 159** 160** Returns void 161** 162*******************************************************************************/ 163void adjust_priority_a2dp(int start) { 164 int priority = start ? ANDROID_PRIORITY_URGENT_AUDIO : ANDROID_PRIORITY_AUDIO; 165 int tid; 166 int i; 167 168 for (i = 0; i < TASK_HIGH_MAX; i++) 169 { 170 tid = g_TaskIDs[i]; 171 if (tid != INVALID_TASK_ID) 172 { 173 if (setpriority(PRIO_PROCESS, tid, priority) < 0) 174 { 175 ALOGW("failed to change priority tid: %d to %d", tid, priority); 176 } 177 } 178 } 179} 180