15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 35b790feeeb211c42bf78ca3ae9c26aa30e516765Jakub Pawlowski * Copyright 2012 Broadcom Corporation 45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * you may not use this file except in compliance with the License. 75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * You may obtain a copy of the License at: 85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * See the License for the specific language governing permissions and 155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * limitations under the License. 165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/ 185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 19ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/******************************************************************************* 205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 21b2a292b5d8df2f359c38b0787bc01181225a9bc9Pavlin Radoslavov * Filename: bt_utils.cc 225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Description: Miscellaneous helper functions 245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 26ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 28f8027005333c88a2f097cfd70d15c3d54c7764aeChris Manton#define LOG_TAG "bt_utils" 2944802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati 3049a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen#include "bt_utils.h" 31499282bc6a165ef3aa76bbef4722a833a2aea675Arman Uguray 325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <errno.h> 335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <pthread.h> 345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdio.h> 355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdlib.h> 3649a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen#include <sys/resource.h> 375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <unistd.h> 3821da63773cb7734e699a4dad662b5b84d2f3dfa8Marie Janssen#include <mutex> 3949a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen 400035d8c9a8b50456f72874174857950df0ecfc67Philip Cuadra#define A2DP_RT_PRIORITY 1 410035d8c9a8b50456f72874174857950df0ecfc67Philip Cuadra#ifndef OS_GENERIC 4249a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen#include <cutils/sched_policy.h> 43b08fbbf1067d6b17386006811b8baaeb14989794Jakub Pawlowski#endif 4449a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen 4583e2c342e8b40009f3509425722d309c0b8189b9Chris Manton#include "bt_types.h" 4695b74f252f534ec757aab1fc08e086e02b2cfe8dSharvil Nanavati#include "btcore/include/module.h" 4747d68ee6229ccec3deeaaf694fa86438d97333a4Scott James Remnant#include "osi/include/compat.h" 4844802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati#include "osi/include/log.h" 493eb4a4827c9436ddd8333457be3474b6fadfb38fJakub Pawlowski#include "osi/include/properties.h" 505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 52ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Type definitions for callback functions 53ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic pthread_once_t g_DoSchedulingGroupOnce[TASK_HIGH_MAX]; 55911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic bool g_DoSchedulingGroup[TASK_HIGH_MAX]; 5621da63773cb7734e699a4dad662b5b84d2f3dfa8Marie Janssenstatic std::mutex gIdxLock; 575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int g_TaskIdx; 584128e36cd8430dfbed16d364e6ab5265e1642db5Zhihai Xustatic int g_TaskIDs[TASK_HIGH_MAX]; 59911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define INVALID_TASK_ID (-1) 605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 61911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic future_t* init(void) { 6296363ff2b78c10e2b2e106464f337b58ec1a616aZach Johnson int i; 635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 64911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson for (i = 0; i < TASK_HIGH_MAX; i++) { 6596363ff2b78c10e2b2e106464f337b58ec1a616aZach Johnson g_DoSchedulingGroupOnce[i] = PTHREAD_ONCE_INIT; 66d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen g_DoSchedulingGroup[i] = true; 6796363ff2b78c10e2b2e106464f337b58ec1a616aZach Johnson g_TaskIDs[i] = INVALID_TASK_ID; 6896363ff2b78c10e2b2e106464f337b58ec1a616aZach Johnson } 6996363ff2b78c10e2b2e106464f337b58ec1a616aZach Johnson 7096363ff2b78c10e2b2e106464f337b58ec1a616aZach Johnson return NULL; 715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 73911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic future_t* clean_up(void) { 7496363ff2b78c10e2b2e106464f337b58ec1a616aZach Johnson return NULL; 755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 77911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsonEXPORT_SYMBOL extern const module_t bt_utils_module = {.name = BT_UTILS_MODULE, 78911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson .init = init, 79911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson .start_up = NULL, 80911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson .shut_down = NULL, 81911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson .clean_up = clean_up, 82911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson .dependencies = {NULL}}; 8396363ff2b78c10e2b2e106464f337b58ec1a616aZach Johnson 845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 85ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 86ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function check_do_scheduling_group 87ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 88ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description check if it is ok to change schedule group 89ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 90ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns void 91ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 92ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void check_do_scheduling_group(void) { 94911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson char buf[PROPERTY_VALUE_MAX]; 95911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson int len = osi_property_get("debug.sys.noschedgroups", buf, ""); 96911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (len > 0) { 97911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson int temp; 98911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (sscanf(buf, "%d", &temp) == 1) { 99911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson g_DoSchedulingGroup[g_TaskIdx] = temp == 0; 1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 101911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 105ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 106ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function raise_priority_a2dp 107ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 108ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Raise task priority for A2DP streaming 109ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 110ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns void 111ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 112ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task) { 114911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson int rc = 0; 115911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson int tid = gettid(); 1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11721da63773cb7734e699a4dad662b5b84d2f3dfa8Marie Janssen { 11821da63773cb7734e699a4dad662b5b84d2f3dfa8Marie Janssen std::lock_guard<std::mutex> lock(gIdxLock); 11921da63773cb7734e699a4dad662b5b84d2f3dfa8Marie Janssen g_TaskIdx = high_task; 1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 121911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson// TODO(armansito): Remove this conditional check once we find a solution 122911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson// for system/core on non-Android platforms. 123499282bc6a165ef3aa76bbef4722a833a2aea675Arman Uguray#if defined(OS_GENERIC) 12421da63773cb7734e699a4dad662b5b84d2f3dfa8Marie Janssen rc = -1; 125911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#else // !defined(OS_GENERIC) 12621da63773cb7734e699a4dad662b5b84d2f3dfa8Marie Janssen pthread_once(&g_DoSchedulingGroupOnce[g_TaskIdx], 12721da63773cb7734e699a4dad662b5b84d2f3dfa8Marie Janssen check_do_scheduling_group); 12821da63773cb7734e699a4dad662b5b84d2f3dfa8Marie Janssen if (g_DoSchedulingGroup[g_TaskIdx]) { 12921da63773cb7734e699a4dad662b5b84d2f3dfa8Marie Janssen // set_sched_policy does not support tid == 0 13021da63773cb7734e699a4dad662b5b84d2f3dfa8Marie Janssen rc = set_sched_policy(tid, SP_AUDIO_SYS); 13121da63773cb7734e699a4dad662b5b84d2f3dfa8Marie Janssen } 132499282bc6a165ef3aa76bbef4722a833a2aea675Arman Uguray#endif // defined(OS_GENERIC) 133499282bc6a165ef3aa76bbef4722a833a2aea675Arman Uguray 13421da63773cb7734e699a4dad662b5b84d2f3dfa8Marie Janssen g_TaskIDs[high_task] = tid; 13521da63773cb7734e699a4dad662b5b84d2f3dfa8Marie Janssen } 1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 137911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (rc) { 138911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson LOG_WARN(LOG_TAG, "failed to change sched policy, tid %d, err: %d", tid, 139911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson errno); 140911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1420035d8c9a8b50456f72874174857950df0ecfc67Philip Cuadra // make A2DP threads use RT scheduling policy since they are part of the 1430035d8c9a8b50456f72874174857950df0ecfc67Philip Cuadra // audio pipeline 1440035d8c9a8b50456f72874174857950df0ecfc67Philip Cuadra { 1450035d8c9a8b50456f72874174857950df0ecfc67Philip Cuadra struct sched_param rt_params; 1460035d8c9a8b50456f72874174857950df0ecfc67Philip Cuadra rt_params.sched_priority = A2DP_RT_PRIORITY; 1470035d8c9a8b50456f72874174857950df0ecfc67Philip Cuadra 1480035d8c9a8b50456f72874174857950df0ecfc67Philip Cuadra const int rc = sched_setscheduler(tid, SCHED_FIFO, &rt_params); 1490035d8c9a8b50456f72874174857950df0ecfc67Philip Cuadra if (rc != 0) { 1500035d8c9a8b50456f72874174857950df0ecfc67Philip Cuadra LOG_ERROR(LOG_TAG, 1510035d8c9a8b50456f72874174857950df0ecfc67Philip Cuadra "%s unable to set SCHED_FIFO priority %d for tid %d, error %s", 1520035d8c9a8b50456f72874174857950df0ecfc67Philip Cuadra __func__, A2DP_RT_PRIORITY, tid, strerror(errno)); 1534128e36cd8430dfbed16d364e6ab5265e1642db5Zhihai Xu } 154911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1554128e36cd8430dfbed16d364e6ab5265e1642db5Zhihai Xu} 156