Revert "Make Bluetooth audio threads use RT scheduling"
This reverts commit eaa42774f393eb3ccaee91a958e8df6a8fb09b91.
http://b/37733903
Test: confirmed switching users does not hang.
Change-Id: Ic54e4ed2dda057e681df225a37a574c221cd8fc3
(cherry picked from commit feb2d84f4b69392b5f37ae1ec9d53ac728514275)
diff --git a/btif/src/btif_av.cc b/btif/src/btif_av.cc
index 4e78fbf..7e4ad4e 100644
--- a/btif/src/btif_av.cc
+++ b/btif/src/btif_av.cc
@@ -929,9 +929,17 @@
* see update_audio_focus_state()
*/
btif_report_audio_state(BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda));
+
+ /* increase the a2dp consumer task priority temporarily when start
+ ** audio playing, to avoid overflow the audio packet queue. */
+ adjust_priority_a2dp(true);
+
break;
case BTIF_SM_EXIT_EVT:
+ /* restore the a2dp consumer task priority when stop audio playing. */
+ adjust_priority_a2dp(false);
+
break;
case BTIF_AV_START_STREAM_REQ_EVT:
diff --git a/hci/src/hci_layer.cc b/hci/src/hci_layer.cc
index e3223ac..1b875b2 100644
--- a/hci/src/hci_layer.cc
+++ b/hci/src/hci_layer.cc
@@ -63,9 +63,6 @@
#define DEFAULT_STARTUP_TIMEOUT_MS 8000
#define STRING_VALUE_OF(x) #x
-// RT priority for HCI thread
-static const int BT_HCI_RT_PRIORITY = 1;
-
// Abort if there is no response to an HCI command.
static const uint32_t COMMAND_PENDING_TIMEOUT_MS = 2000;
@@ -191,9 +188,6 @@
LOG_ERROR(LOG_TAG, "%s unable to create thread.", __func__);
goto error;
}
- if (!thread_set_rt_priority(thread, BT_HCI_RT_PRIORITY)) {
- LOG_ERROR(LOG_TAG, "%s unable to make thread RT.", __func__);
- }
commands_pending_response = list_new(NULL);
if (!commands_pending_response) {
diff --git a/osi/include/thread.h b/osi/include/thread.h
index c8da381..de359f7 100644
--- a/osi/include/thread.h
+++ b/osi/include/thread.h
@@ -65,13 +65,6 @@
// Returns true on success.
bool thread_set_priority(thread_t* thread, int priority);
-// Attempts to set |thread| to the real-time SCHED_FIFO |priority|.
-// The |thread| has to be running for this call to succeed.
-// Priority values are valid in the range sched_get_priority_max(SCHED_FIFO)
-// to sched_get_priority_min(SCHED_FIFO). Larger values are higher priority.
-// Returns true on success.
-bool thread_set_rt_priority(thread_t* thread, int priority);
-
// Returns true if the current thread is the same as the one represented by
// |thread|.
// |thread| may not be NULL.
diff --git a/osi/src/alarm.cc b/osi/src/alarm.cc
index 684a078..620e352 100644
--- a/osi/src/alarm.cc
+++ b/osi/src/alarm.cc
@@ -27,7 +27,6 @@
#include <fcntl.h>
#include <inttypes.h>
#include <malloc.h>
-#include <pthread.h>
#include <signal.h>
#include <string.h>
#include <time.h>
@@ -45,9 +44,12 @@
#include "osi/include/thread.h"
#include "osi/include/wakelock.h"
-// Callback and timer threads should run at RT priority in order to ensure they
-// meet audio deadlines. Use this priority for all audio/timer related thread.
-static const int THREAD_RT_PRIORITY = 1;
+// Make callbacks run at high thread priority. Some callbacks are used for audio
+// related timer tasks as well as re-transmissions etc. Since we at this point
+// cannot differentiate what callback we are dealing with, assume high priority
+// for now.
+// TODO(eisenbach): Determine correct thread priority (from parent?/per alarm?)
+static const int CALLBACK_THREAD_PRIORITY_HIGH = -19;
typedef struct {
size_t count;
@@ -312,7 +314,7 @@
__func__);
goto error;
}
- thread_set_rt_priority(default_callback_thread, THREAD_RT_PRIORITY);
+ thread_set_priority(default_callback_thread, CALLBACK_THREAD_PRIORITY_HIGH);
default_callback_queue = fixed_queue_new(SIZE_MAX);
if (default_callback_queue == NULL) {
LOG_ERROR(LOG_TAG, "%s unable to create default alarm callbacks queue.",
@@ -328,7 +330,8 @@
LOG_ERROR(LOG_TAG, "%s unable to create alarm callback thread.", __func__);
goto error;
}
- thread_set_rt_priority(dispatcher_thread, THREAD_RT_PRIORITY);
+
+ thread_set_priority(dispatcher_thread, CALLBACK_THREAD_PRIORITY_HIGH);
thread_post(dispatcher_thread, callback_dispatch, NULL);
return true;
@@ -622,18 +625,9 @@
CHECK(timer != NULL);
struct sigevent sigevent;
- // create timer with RT priority thread
- pthread_attr_t thread_attr;
- pthread_attr_init(&thread_attr);
- pthread_attr_setschedpolicy(&thread_attr, SCHED_FIFO);
- struct sched_param param;
- param.sched_priority = THREAD_RT_PRIORITY;
- pthread_attr_setschedparam(&thread_attr, ¶m);
-
memset(&sigevent, 0, sizeof(sigevent));
sigevent.sigev_notify = SIGEV_THREAD;
sigevent.sigev_notify_function = (void (*)(union sigval))timer_callback;
- sigevent.sigev_notify_attributes = (void*)(&thread_attr);
if (timer_create(clock_id, &sigevent, timer) == -1) {
LOG_ERROR(LOG_TAG, "%s unable to create timer with clock %d: %s", __func__,
clock_id, strerror(errno));
diff --git a/osi/src/thread.cc b/osi/src/thread.cc
index 61b44f2..d218129 100644
--- a/osi/src/thread.cc
+++ b/osi/src/thread.cc
@@ -159,23 +159,6 @@
return true;
}
-bool thread_set_rt_priority(thread_t* thread, int priority) {
- if (!thread) return false;
-
- struct sched_param rt_params;
- rt_params.sched_priority = priority;
-
- const int rc = sched_setscheduler(thread->tid, SCHED_FIFO, &rt_params);
- if (rc != 0) {
- LOG_ERROR(LOG_TAG,
- "%s unable to set SCHED_FIFO priority %d for tid %d, error %s",
- __func__, priority, thread->tid, strerror(errno));
- return false;
- }
-
- return true;
-}
-
bool thread_is_self(const thread_t* thread) {
CHECK(thread != NULL);
return !!pthread_equal(pthread_self(), thread->pthread);
diff --git a/stack/btu/btu_init.cc b/stack/btu/btu_init.cc
index 14612a3..c7b2b2a 100644
--- a/stack/btu/btu_init.cc
+++ b/stack/btu/btu_init.cc
@@ -36,8 +36,9 @@
#include "sdpint.h"
#include "smp_int.h"
-// RT priority for audio-related tasks
-#define BTU_TASK_RT_PRIORITY 1
+// Increase BTU task thread priority to avoid pre-emption
+// of audio realated tasks.
+#define BTU_TASK_THREAD_PRIORITY (-19)
extern fixed_queue_t* btif_msg_queue;
@@ -129,7 +130,7 @@
bt_workqueue_thread = thread_new(BT_WORKQUEUE_NAME);
if (bt_workqueue_thread == NULL) goto error_exit;
- thread_set_rt_priority(bt_workqueue_thread, BTU_TASK_RT_PRIORITY);
+ thread_set_priority(bt_workqueue_thread, BTU_TASK_THREAD_PRIORITY);
// Continue startup on bt workqueue thread.
thread_post(bt_workqueue_thread, btu_task_start_up, NULL);
diff --git a/utils/include/bt_utils.h b/utils/include/bt_utils.h
index 2b1a7b1..892855e 100644
--- a/utils/include/bt_utils.h
+++ b/utils/include/bt_utils.h
@@ -36,5 +36,6 @@
******************************************************************************/
void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task);
+void adjust_priority_a2dp(int start);
#endif /* BT_UTILS_H */
diff --git a/utils/src/bt_utils.cc b/utils/src/bt_utils.cc
index 65bd7af..d7b8ebd 100644
--- a/utils/src/bt_utils.cc
+++ b/utils/src/bt_utils.cc
@@ -37,9 +37,12 @@
#include <unistd.h>
#include <mutex>
-#define A2DP_RT_PRIORITY 1
-#ifndef OS_GENERIC
+#ifdef OS_GENERIC
+#define ANDROID_PRIORITY_AUDIO -16
+#define ANDROID_PRIORITY_URGENT_AUDIO -19
+#else
#include <cutils/sched_policy.h>
+#include <utils/ThreadDefs.h>
#endif
#include "bt_types.h"
@@ -113,6 +116,7 @@
void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task) {
int rc = 0;
int tid = gettid();
+ int priority = ANDROID_PRIORITY_AUDIO;
{
std::lock_guard<std::mutex> lock(gIdxLock);
@@ -139,17 +143,41 @@
errno);
}
- // make A2DP threads use RT scheduling policy since they are part of the
- // audio pipeline
- {
- struct sched_param rt_params;
- rt_params.sched_priority = A2DP_RT_PRIORITY;
+ // always use urgent priority for HCI worker thread until we can adjust
+ // its prio individually. All other threads can be dynamically adjusted voa
+ // adjust_priority_a2dp()
- const int rc = sched_setscheduler(tid, SCHED_FIFO, &rt_params);
- if (rc != 0) {
- LOG_ERROR(LOG_TAG,
- "%s unable to set SCHED_FIFO priority %d for tid %d, error %s",
- __func__, A2DP_RT_PRIORITY, tid, strerror(errno));
+ priority = ANDROID_PRIORITY_URGENT_AUDIO;
+
+ if (setpriority(PRIO_PROCESS, tid, priority) < 0) {
+ LOG_WARN(LOG_TAG, "failed to change priority tid: %d to %d", tid, priority);
+ }
+}
+
+/*****************************************************************************
+ *
+ * Function adjust_priority_a2dp
+ *
+ * Description Increase the a2dp consumer task priority temporarily when
+ * audio starts playing to avoid overflowing the audio packet
+ * queue. Restore the a2dp consumer task priority when audio
+ * is not playing.
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+void adjust_priority_a2dp(int start) {
+ int priority = start ? ANDROID_PRIORITY_URGENT_AUDIO : ANDROID_PRIORITY_AUDIO;
+ int tid;
+ int i;
+
+ for (i = 0; i < TASK_HIGH_MAX; i++) {
+ tid = g_TaskIDs[i];
+ if (tid != INVALID_TASK_ID) {
+ if (setpriority(PRIO_PROCESS, tid, priority) < 0) {
+ LOG_WARN(LOG_TAG, "failed to change priority tid: %d to %d", tid,
+ priority);
+ }
}
}
}