Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright 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.cc
     22  *
     23  *  Description:   Miscellaneous helper functions
     24  *
     25  *
     26  ******************************************************************************/
     27 
     28 #define LOG_TAG "bt_utils"
     29 
     30 #include "bt_utils.h"
     31 
     32 #include <errno.h>
     33 #include <pthread.h>
     34 #include <stdio.h>
     35 #include <stdlib.h>
     36 #include <sys/resource.h>
     37 #include <unistd.h>
     38 #include <mutex>
     39 
     40 #define A2DP_RT_PRIORITY 1
     41 #ifndef OS_GENERIC
     42 #include <cutils/sched_policy.h>
     43 #endif
     44 
     45 #include "bt_types.h"
     46 #include "btcore/include/module.h"
     47 #include "osi/include/compat.h"
     48 #include "osi/include/log.h"
     49 #include "osi/include/properties.h"
     50 
     51 /*******************************************************************************
     52  *  Type definitions for callback functions
     53  ******************************************************************************/
     54 static pthread_once_t g_DoSchedulingGroupOnce[TASK_HIGH_MAX];
     55 static bool g_DoSchedulingGroup[TASK_HIGH_MAX];
     56 static std::mutex gIdxLock;
     57 static int g_TaskIdx;
     58 static int g_TaskIDs[TASK_HIGH_MAX];
     59 #define INVALID_TASK_ID (-1)
     60 
     61 static future_t* init(void) {
     62   int i;
     63 
     64   for (i = 0; i < TASK_HIGH_MAX; i++) {
     65     g_DoSchedulingGroupOnce[i] = PTHREAD_ONCE_INIT;
     66     g_DoSchedulingGroup[i] = true;
     67     g_TaskIDs[i] = INVALID_TASK_ID;
     68   }
     69 
     70   return NULL;
     71 }
     72 
     73 static future_t* clean_up(void) {
     74   return NULL;
     75 }
     76 
     77 EXPORT_SYMBOL extern const module_t bt_utils_module = {.name = BT_UTILS_MODULE,
     78                                                        .init = init,
     79                                                        .start_up = NULL,
     80                                                        .shut_down = NULL,
     81                                                        .clean_up = clean_up,
     82                                                        .dependencies = {NULL}};
     83 
     84 /*****************************************************************************
     85  *
     86  * Function        check_do_scheduling_group
     87  *
     88  * Description     check if it is ok to change schedule group
     89  *
     90  * Returns         void
     91  *
     92  ******************************************************************************/
     93 static void check_do_scheduling_group(void) {
     94   char buf[PROPERTY_VALUE_MAX];
     95   int len = osi_property_get("debug.sys.noschedgroups", buf, "");
     96   if (len > 0) {
     97     int temp;
     98     if (sscanf(buf, "%d", &temp) == 1) {
     99       g_DoSchedulingGroup[g_TaskIdx] = temp == 0;
    100     }
    101   }
    102 }
    103 
    104 /*****************************************************************************
    105  *
    106  * Function        raise_priority_a2dp
    107  *
    108  * Description     Raise task priority for A2DP streaming
    109  *
    110  * Returns         void
    111  *
    112  ******************************************************************************/
    113 void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task) {
    114   int rc = 0;
    115   int tid = gettid();
    116 
    117   {
    118     std::lock_guard<std::mutex> lock(gIdxLock);
    119     g_TaskIdx = high_task;
    120 
    121 // TODO(armansito): Remove this conditional check once we find a solution
    122 // for system/core on non-Android platforms.
    123 #if defined(OS_GENERIC)
    124     rc = -1;
    125 #else   // !defined(OS_GENERIC)
    126     pthread_once(&g_DoSchedulingGroupOnce[g_TaskIdx],
    127                  check_do_scheduling_group);
    128     if (g_DoSchedulingGroup[g_TaskIdx]) {
    129       // set_sched_policy does not support tid == 0
    130       rc = set_sched_policy(tid, SP_AUDIO_SYS);
    131     }
    132 #endif  // defined(OS_GENERIC)
    133 
    134     g_TaskIDs[high_task] = tid;
    135   }
    136 
    137   if (rc) {
    138     LOG_WARN(LOG_TAG, "failed to change sched policy, tid %d, err: %d", tid,
    139              errno);
    140   }
    141 
    142   // make A2DP threads use RT scheduling policy since they are part of the
    143   // audio pipeline
    144   {
    145     struct sched_param rt_params;
    146     rt_params.sched_priority = A2DP_RT_PRIORITY;
    147 
    148     const int rc = sched_setscheduler(tid, SCHED_FIFO, &rt_params);
    149     if (rc != 0) {
    150       LOG_ERROR(LOG_TAG,
    151                 "%s unable to set SCHED_FIFO priority %d for tid %d, error %s",
    152                 __func__, A2DP_RT_PRIORITY, tid, strerror(errno));
    153     }
    154   }
    155 }
    156