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