• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ********************************************************************************/
49 static pthread_once_t g_DoSchedulingGroupOnce[TASK_HIGH_MAX];
50 static BOOLEAN g_DoSchedulingGroup[TASK_HIGH_MAX];
51 static pthread_mutex_t         gIdxLock;
52 static int g_TaskIdx;
53 static 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 *******************************************************************************/
bt_utils_init()65 void 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 *******************************************************************************/
bt_utils_cleanup()87 void 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 *******************************************************************************/
check_do_scheduling_group(void)100 static 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 *******************************************************************************/
raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task)120 void 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 *******************************************************************************/
adjust_priority_a2dp(int start)163 void 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