Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9aa26a28 authored by Andre Eisenbach's avatar Andre Eisenbach
Browse files

Raise BTU and HCI thread priorities

The audio sub-system and audio related tasks run at elevated thread
priorities in order to ensure timely handling of audio packets. This
patch raises the thread priority of lower layer Bluetooth tasks involved
in delivering audio packets to avoid thread pre-emption and subsequent
audio skipping.

Bug: 24570959
Change-Id: I5e19ee4590207df753f7b8bfc22174959722ec2d
parent 3aa91043
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -27,10 +27,15 @@
#include "osi/include/osi.h"
#include "osi/include/log.h"
#include "osi/include/reactor.h"
#include "osi/include/thread.h"
#include "vendor.h"

#define HCI_HAL_SERIAL_BUFFER_SIZE 1026

// Increased HCI thread priority to keep up with the audio sub-system
// when streaming time sensitive data (A2DP).
#define HCI_THREAD_PRIORITY -19

// Our interface and modules we import
static const hci_hal_t interface;
static const hci_hal_callbacks_t *callbacks;
@@ -83,6 +88,10 @@ static bool hal_open() {
  stream_has_interpretation = false;
  eager_reader_register(uart_stream, thread_get_reactor(thread), event_uart_has_bytes, NULL);

  // Raise thread priorities to keep up with audio
  thread_set_priority(thread, HCI_THREAD_PRIORITY);
  thread_set_priority(eager_reader_get_read_thread(uart_stream), HCI_THREAD_PRIORITY);

  return true;

error:
+5 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <stdint.h>

#include "allocator.h"
#include "osi/include/thread.h"

typedef struct eager_reader_t eager_reader_t;
typedef struct reactor_t reactor_t;
@@ -61,3 +62,7 @@ void eager_reader_unregister(eager_reader_t *reader);
// but you should probably only be reading from one thread anyway,
// otherwise the byte stream probably doesn't make sense.
size_t eager_reader_read(eager_reader_t *reader, uint8_t *buffer, size_t max_size, bool block);

// Returns the inbound read thread for a given |reader| or NULL if the thread
// is not running.
thread_t* eager_reader_get_read_thread(const eager_reader_t *reader);
+5 −0
Original line number Diff line number Diff line
@@ -58,6 +58,11 @@ bool thread_post(thread_t *thread, thread_fn func, void *context);
// |thread| may not be NULL.
void thread_stop(thread_t *thread);

// Attempts to sets the |priority| of a given |thread|.
// The |thread| has to be running for this call to succeed.
// Returns true on success.
bool thread_set_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.
bool thread_is_self(const thread_t *thread);
+5 −1
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@
#include "osi/include/osi.h"
#include "osi/include/log.h"
#include "osi/include/reactor.h"
#include "osi/include/thread.h"

#if !defined(EFD_SEMAPHORE)
#  define EFD_SEMAPHORE (1 << 0)
@@ -212,6 +211,11 @@ size_t eager_reader_read(eager_reader_t *reader, uint8_t *buffer, size_t max_siz
  return bytes_consumed;
}

thread_t* eager_reader_get_read_thread(const eager_reader_t *reader) {
  assert(reader != NULL);
  return reader->inbound_read_thread;
}

static bool has_byte(const eager_reader_t *reader) {
  assert(reader != NULL);

+15 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <pthread.h>
#include <string.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include <sys/types.h>

#include "osi/include/allocator.h"
@@ -154,6 +155,20 @@ void thread_stop(thread_t *thread) {
  reactor_stop(thread->reactor);
}

bool thread_set_priority(thread_t *thread, int priority) {
  if (!thread)
    return false;

  const int rc = setpriority(PRIO_PROCESS, thread->tid, priority);
  if (rc < 0) {
    LOG_ERROR("%s unable to set thread priority %d for tid %d, error %d",
      __func__, priority, thread->tid, rc);
    return false;
  }

  return true;
}

bool thread_is_self(const thread_t *thread) {
  assert(thread != NULL);
  return !!pthread_equal(pthread_self(), thread->pthread);
Loading