abstract of OSI thread to make bluedroid more compatible with different OS.
"bluedroid/osi/mutex.c"
"bluedroid/osi/osi.c"
"bluedroid/osi/semaphore.c"
+ "bluedroid/osi/thread.c"
"bluedroid/stack/a2dp/a2d_api.c"
"bluedroid/stack/a2dp/a2d_sbc.c"
"bluedroid/stack/avct/avct_api.c"
#include "osi/alarm.h"
#include "osi/thread.h"
#include "stack/btm_api.h"
+#include "stack/btu.h"
#include "bta/bta_api.h"
#include "bta/bta_sys.h"
#include "bta_sys_int.h"
// there is a procedure in progress that can schedule a task via this
// message queue. This causes |btu_bta_msg_queue| to get cleaned up before
// it gets used here; hence we check for NULL before using it.
- if (btu_task_post(SIG_BTU_BTA_MSG, p_msg, TASK_POST_BLOCKING) != TASK_POST_SUCCESS) {
+ if (btu_task_post(SIG_BTU_BTA_MSG, p_msg, OSI_THREAD_BLOCKING) == false) {
osi_free(p_msg);
}
}
assert(data != NULL);
TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
- btu_task_post(SIG_BTU_BTA_ALARM, p_tle, TASK_POST_BLOCKING);
+ btu_task_post(SIG_BTU_BTA_ALARM, p_tle, OSI_THREAD_BLOCKING);
}
void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms)
#endif /* #if BTC_HF_CLIENT_INCLUDED */
#endif /* #if CONFIG_BT_CLASSIC_ENABLED */
+#define BTC_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
+#define BTC_TASK_STACK_SIZE (CONFIG_BTC_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) //by menuconfig
+#define BTC_TASK_NAME "btcT"
+#define BTC_TASK_PRIO (configMAX_PRIORITIES - 6)
+#define BTC_TASK_QUEUE_LEN 60
-static xTaskHandle xBtcTaskHandle = NULL;
-static xQueueHandle xBtcQueue = 0;
+static osi_thread_t *btc_thread;
static btc_func_t profile_tab[BTC_PID_NUM] = {
[BTC_PID_MAIN_INIT] = {btc_main_call_handler, NULL },
**
** Description Process profile Task Thread.
******************************************************************************/
-static void btc_task(void *arg)
+static void btc_thread_handler(void *arg)
{
- btc_msg_t msg;
-
- for (;;) {
- if (pdTRUE == xQueueReceive(xBtcQueue, &msg, (portTickType)portMAX_DELAY)) {
- BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg.sig, msg.pid, msg.act, msg.arg);
- switch (msg.sig) {
- case BTC_SIG_API_CALL:
- profile_tab[msg.pid].btc_call(&msg);
- break;
- case BTC_SIG_API_CB:
- profile_tab[msg.pid].btc_cb(&msg);
- break;
- default:
- break;
- }
- if (msg.arg) {
- osi_free(msg.arg);
- }
- }
+ btc_msg_t *msg = (btc_msg_t *)arg;
+
+ BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg->sig, msg->pid, msg->act, msg->arg);
+ switch (msg->sig) {
+ case BTC_SIG_API_CALL:
+ profile_tab[msg->pid].btc_call(msg);
+ break;
+ case BTC_SIG_API_CB:
+ profile_tab[msg->pid].btc_cb(msg);
+ break;
+ default:
+ break;
+ }
+
+ if (msg->arg) {
+ osi_free(msg->arg);
}
+ osi_free(msg);
}
-static bt_status_t btc_task_post(btc_msg_t *msg, task_post_t timeout)
+static bt_status_t btc_task_post(btc_msg_t *msg, osi_thread_blocking_t blocking)
{
- if (msg == NULL) {
- return BT_STATUS_PARM_INVALID;
+ btc_msg_t *lmsg;
+
+ lmsg = (btc_msg_t *)osi_malloc(sizeof(btc_msg_t));
+ if (lmsg == NULL) {
+ return BT_STATUS_NOMEM;
}
- if (xQueueSend(xBtcQueue, msg, timeout) != pdTRUE) {
- BTC_TRACE_ERROR("Btc Post failed\n");
+ memcpy(lmsg, msg, sizeof(btc_msg_t));
+
+ if (osi_thread_post(btc_thread, btc_thread_handler, lmsg, 0, blocking) == false) {
return BT_STATUS_BUSY;
}
lmsg.arg = NULL;
}
- return btc_task_post(&lmsg, TASK_POST_BLOCKING);
+ return btc_task_post(&lmsg, OSI_THREAD_BLOCKING);
+
}
int btc_init(void)
{
- xBtcQueue = xQueueCreate(BTC_TASK_QUEUE_LEN, sizeof(btc_msg_t));
- xTaskCreatePinnedToCore(btc_task, "Btc_task", BTC_TASK_STACK_SIZE, NULL, BTC_TASK_PRIO, &xBtcTaskHandle, BTC_TASK_PINNED_TO_CORE);
- if (xBtcTaskHandle == NULL || xBtcQueue == 0){
+ btc_thread = osi_thread_create("BTC_TASK", BTC_TASK_STACK_SIZE, BTC_TASK_PRIO, BTC_TASK_PINNED_TO_CORE, 1);
+ if (btc_thread == NULL) {
return BT_STATUS_NOMEM;
}
+
btc_gap_callback_init();
#if SCAN_QUEUE_CONGEST_CHECK
btc_adv_list_init();
void btc_deinit(void)
{
- vTaskDelete(xBtcTaskHandle);
- vQueueDelete(xBtcQueue);
+ osi_thread_free(btc_thread);
+ btc_thread = NULL;
#if SCAN_QUEUE_CONGEST_CHECK
btc_adv_list_deinit();
#endif
- xBtcTaskHandle = NULL;
- xBtcQueue = 0;
}
bool btc_check_queue_is_congest(void)
{
- UBaseType_t wait_size = uxQueueMessagesWaiting(xBtcQueue);
- if(wait_size >= QUEUE_CONGEST_SIZE) {
+ if (osi_thread_queue_wait_size(btc_thread, 0) >= QUEUE_CONGEST_SIZE) {
return true;
}
+
return false;
}
#if (BTC_AV_SINK_INCLUDED == TRUE)
+/* Macro */
+#define BTC_A2DP_SINK_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
+#define BTC_A2DP_SINK_TASK_STACK_SIZE (CONFIG_A2DP_SINK_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) // by menuconfig
+#define BTC_A2DP_SINK_TASK_NAME "BtA2dSinkT"
+#define BTC_A2DP_SINK_TASK_PRIO (configMAX_PRIORITIES - 3)
+
+
/*****************************************************************************
** Constants
*****************************************************************************/
BTC_A2DP_SINK_STATE_SHUTTING_DOWN = 2
};
-enum {
- BTC_A2DP_SINK_DATA_EVT = 0,
-};
-
/*
* CONGESTION COMPENSATION CTRL ::
*
/* 18 frames is equivalent to 6.89*18*2.9 ~= 360 ms @ 44.1 khz, 20 ms mediatick */
#define MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ (18)
+typedef struct {
+ uint32_t sig;
+ void *param;
+} a2dp_sink_task_evt_t;
+
typedef struct {
UINT16 num_frames_to_be_processed;
UINT16 len;
static void btc_a2dp_sink_handle_decoder_reset(tBTC_MEDIA_SINK_CFG_UPDATE *p_msg);
static void btc_a2dp_sink_handle_clear_track(void);
static BOOLEAN btc_a2dp_sink_clear_track(void);
-static void btc_a2dp_sink_task_handler(void *arg);
-static void btc_a2dp_sink_data_ready(UNUSED_ATTR void *context);
+static void btc_a2dp_sink_ctrl_handler(void *arg);
+
+static void btc_a2dp_sink_data_ready(void *context);
static tBTC_A2DP_SINK_CB btc_aa_snk_cb;
static int btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_OFF;
static future_t *btc_a2dp_sink_future = NULL;
-static xTaskHandle btc_aa_snk_task_hdl = NULL;
-static QueueHandle_t btc_aa_snk_data_queue = NULL;
-static QueueHandle_t btc_aa_snk_ctrl_queue = NULL;
-static QueueSetHandle_t btc_aa_snk_queue_set;
-
+static osi_thread_t *btc_aa_snk_task_hdl = NULL;
static esp_a2d_sink_data_cb_t bt_aa_snk_data_cb = NULL;
void btc_a2dp_sink_reg_data_cb(esp_a2d_sink_data_cb_t callback)
** BTC ADAPTATION
*****************************************************************************/
-static void btc_a2dp_sink_ctrl_post(uint32_t sig, void *par)
+static bool btc_a2dp_sink_ctrl_post(uint32_t sig, void *param)
{
- BtTaskEvt_t *evt = (BtTaskEvt_t *)osi_malloc(sizeof(BtTaskEvt_t));
+ a2dp_sink_task_evt_t *evt = (a2dp_sink_task_evt_t *)osi_malloc(sizeof(a2dp_sink_task_evt_t));
+
if (evt == NULL) {
- return;
+ return false;
}
evt->sig = sig;
- evt->par = par;
+ evt->param = param;
- if (xQueueSend(btc_aa_snk_ctrl_queue, &evt, portMAX_DELAY) != pdTRUE) {
- APPL_TRACE_WARNING("btc_aa_snk_ctrl_queue failed, sig 0x%x\n", sig);
- }
+ return osi_thread_post(btc_aa_snk_task_hdl, btc_a2dp_sink_ctrl_handler, evt, 0, OSI_THREAD_BLOCKING);
}
-static void btc_a2dp_sink_ctrl_handler(BtTaskEvt_t *e)
+static void btc_a2dp_sink_ctrl_handler(void *arg)
{
+ a2dp_sink_task_evt_t *e = (a2dp_sink_task_evt_t *)arg;
+
if (e == NULL) {
return;
}
+
switch (e->sig) {
case BTC_MEDIA_TASK_SINK_INIT:
btc_a2dp_sink_thread_init(NULL);
btc_a2dp_sink_thread_cleanup(NULL);
break;
case BTC_MEDIA_AUDIO_SINK_CFG_UPDATE:
- btc_a2dp_sink_handle_decoder_reset(e->par);
+ btc_a2dp_sink_handle_decoder_reset(e->param);
break;
case BTC_MEDIA_AUDIO_SINK_CLEAR_TRACK:
btc_a2dp_sink_handle_clear_track();
default:
APPL_TRACE_WARNING("media task unhandled evt: 0x%x\n", e->sig);
}
- if (e->par != NULL) {
- osi_free(e->par);
- }
-}
-static void btc_a2dp_sink_task_handler(void *arg)
-{
- QueueSetMemberHandle_t xActivatedMember;
- BtTaskEvt_t *e = NULL;
- for (;;) {
- xActivatedMember = xQueueSelectFromSet(btc_aa_snk_queue_set, portMAX_DELAY);
- if (xActivatedMember == btc_aa_snk_data_queue) {
- int32_t data_evt;
- xQueueReceive(xActivatedMember, &data_evt, 0);
- if (data_evt == BTC_A2DP_SINK_DATA_EVT) {
- btc_a2dp_sink_data_ready(NULL);
- }
- } else if (xActivatedMember == btc_aa_snk_ctrl_queue) {
- xQueueReceive(xActivatedMember, &e, 0);
- btc_a2dp_sink_ctrl_handler(e);
- osi_free(e);
- }
+ if (e->param != NULL) {
+ osi_free(e->param);
}
+
+ osi_free(e);
}
bool btc_a2dp_sink_startup(void)
}
#endif /* BTC_SBC_DEC_DYNAMIC_MEMORY == TRUE */
- btc_aa_snk_queue_set = xQueueCreateSet(BTC_A2DP_SINK_TASK_QUEUE_SET_LEN);
- configASSERT(btc_aa_snk_queue_set);
- btc_aa_snk_data_queue = xQueueCreate(BTC_A2DP_SINK_DATA_QUEUE_LEN, sizeof(int32_t));
- configASSERT(btc_aa_snk_data_queue);
- xQueueAddToSet(btc_aa_snk_data_queue, btc_aa_snk_queue_set);
-
- btc_aa_snk_ctrl_queue = xQueueCreate(BTC_A2DP_SINK_CTRL_QUEUE_LEN, sizeof(void *));
- configASSERT(btc_aa_snk_ctrl_queue);
- xQueueAddToSet(btc_aa_snk_ctrl_queue, btc_aa_snk_queue_set);
-
- if (!btc_aa_snk_data_queue || !btc_aa_snk_ctrl_queue || !btc_aa_snk_queue_set ) {
+ btc_aa_snk_task_hdl = osi_thread_create(BTC_A2DP_SINK_TASK_NAME, BTC_A2DP_SINK_TASK_STACK_SIZE, BTC_A2DP_SINK_TASK_PRIO, BTC_A2DP_SINK_TASK_PINNED_TO_CORE, 2);
+ if (btc_aa_snk_task_hdl == NULL) {
goto error_exit;
}
- xTaskCreatePinnedToCore(btc_a2dp_sink_task_handler, BTC_A2DP_SINK_TASK_NAME, BTC_A2DP_SINK_TASK_STACK_SIZE, NULL, BTC_A2DP_SINK_TASK_PRIO, &btc_aa_snk_task_hdl, BTC_A2DP_SINK_TASK_PINNED_TO_CORE);
- if (btc_aa_snk_task_hdl == NULL) {
+ if (btc_a2dp_sink_ctrl_post(BTC_MEDIA_TASK_SINK_INIT, NULL) == false) {
goto error_exit;
}
- btc_a2dp_sink_ctrl_post(BTC_MEDIA_TASK_SINK_INIT, NULL);
-
APPL_TRACE_EVENT("## A2DP SINK MEDIA THREAD STARTED ##\n");
return true;
error_exit:;
APPL_TRACE_ERROR("%s unable to start up media thread\n", __func__);
-
if (btc_aa_snk_task_hdl != NULL) {
- vTaskDelete(btc_aa_snk_task_hdl);
+ osi_thread_free(btc_aa_snk_task_hdl);
btc_aa_snk_task_hdl = NULL;
}
- if (btc_aa_snk_data_queue) {
- vQueueDelete(btc_aa_snk_data_queue);
- btc_aa_snk_data_queue = NULL;
- }
- if (btc_aa_snk_ctrl_queue) {
- vQueueDelete(btc_aa_snk_ctrl_queue);
- btc_aa_snk_ctrl_queue = NULL;
- }
- if (btc_aa_snk_queue_set) {
- vQueueDelete(btc_aa_snk_queue_set);
- btc_aa_snk_queue_set = NULL;
- }
#if (BTC_SBC_DEC_DYNAMIC_MEMORY == TRUE)
if (btc_sbc_decoder_context_ptr) {
osi_free(btc_sbc_decoder_context_ptr);
future_await(btc_a2dp_sink_future);
btc_a2dp_sink_future = NULL;
- vTaskDelete(btc_aa_snk_task_hdl);
+ osi_thread_free(btc_aa_snk_task_hdl);
btc_aa_snk_task_hdl = NULL;
- vQueueDelete(btc_aa_snk_data_queue);
- btc_aa_snk_data_queue = NULL;
-
- vQueueDelete(btc_aa_snk_ctrl_queue);
- btc_aa_snk_ctrl_queue = NULL;
-
- vQueueDelete(btc_aa_snk_queue_set);
- btc_aa_snk_queue_set = NULL;
-
#if (BTC_SBC_DEC_DYNAMIC_MEMORY == TRUE)
osi_free(btc_sbc_decoder_context_ptr);
btc_sbc_decoder_context_ptr = NULL;
return;
}
-static void btc_a2dp_sink_data_post(int32_t data_type)
+static void btc_a2dp_sink_data_post(void)
{
- if (xQueueSend(btc_aa_snk_data_queue, &data_type, 0) != pdTRUE) {
- APPL_TRACE_DEBUG("Media data Q filled\n");
- }
+ osi_thread_post(btc_aa_snk_task_hdl, btc_a2dp_sink_data_ready, NULL, 1, OSI_THREAD_BLOCKING);
}
/*******************************************************************************
*******************************************************************************/
static BOOLEAN btc_a2dp_sink_clear_track(void)
{
- btc_a2dp_sink_ctrl_post(BTC_MEDIA_AUDIO_SINK_CLEAR_TRACK, NULL);
- return TRUE;
+ return btc_a2dp_sink_ctrl_post(BTC_MEDIA_AUDIO_SINK_CLEAR_TRACK, NULL);
}
/* when true media task discards any rx frames */
return TRUE;
}
- btc_a2dp_sink_ctrl_post(BTC_MEDIA_FLUSH_AA_RX, NULL);
- return TRUE;
+ return btc_a2dp_sink_ctrl_post(BTC_MEDIA_FLUSH_AA_RX, NULL);
}
/*******************************************************************************
p_msg->num_frames_to_be_processed = (*((UINT8 *)(p_msg + 1) + p_msg->offset)) & 0x0f;
APPL_TRACE_VERBOSE("btc_a2dp_sink_enque_buf %d + \n", p_msg->num_frames_to_be_processed);
fixed_queue_enqueue(btc_aa_snk_cb.RxSbcQ, p_msg);
- btc_a2dp_sink_data_post(BTC_A2DP_SINK_DATA_EVT);
+ btc_a2dp_sink_data_post();
} else {
/* let caller deal with a failed allocation */
APPL_TRACE_WARNING("btc_a2dp_sink_enque_buf No Buffer left - ");
#if BTC_AV_SRC_INCLUDED
+/* Macro */
+#define BTC_A2DP_SOURCE_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
+#define BTC_A2DP_SOURCE_TASK_STACK_SIZE (CONFIG_A2DP_SOURCE_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) // by menuconfig
+#define BTC_A2DP_SOURCE_TASK_NAME "BtA2dSourceT"
+#define BTC_A2DP_SOURCE_TASK_PRIO (configMAX_PRIORITIES - 3)
+
+
/*****************************************************************************
** Constants
*****************************************************************************/
BTC_A2DP_SOURCE_STATE_SHUTTING_DOWN = 2
};
-enum {
- BTC_A2DP_SOURCE_DATA_EVT = 1,
-};
/* Media task tick in milliseconds, must be set to multiple of
(1000/TICKS_PER_SEC) */
#define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ (5)
#define MAX_OUTPUT_A2DP_SRC_FRAME_QUEUE_SZ (27) // 18 for 20ms tick
+typedef struct {
+ uint32_t sig;
+ void *param;
+} a2dp_src_task_evt_t;
+
typedef struct {
UINT16 num_frames_to_be_processed;
UINT16 len;
static void btc_a2dp_source_prep_2_send(UINT8 nb_frame);
static void btc_a2dp_source_handle_timer(UNUSED_ATTR void *context);
static void btc_a2dp_source_encoder_init(void);
+static void btc_a2dp_source_ctrl_handler(void *arg);
static tBTC_A2DP_SOURCE_CB btc_aa_src_cb;
static int btc_a2dp_source_state = BTC_A2DP_SOURCE_STATE_OFF;
static future_t *btc_a2dp_source_future = NULL;
-static xTaskHandle btc_aa_src_task_hdl = NULL;
-static QueueHandle_t btc_aa_src_data_queue = NULL;
-static QueueHandle_t btc_aa_src_ctrl_queue = NULL;
-static QueueSetHandle_t btc_aa_src_queue_set;
-
+static osi_thread_t *btc_aa_src_task_hdl = NULL;
static esp_a2d_source_data_cb_t btc_aa_src_data_cb = NULL;
static UINT64 last_frame_us = 0;
return btc_a2dp_source_state == BTC_A2DP_SOURCE_STATE_SHUTTING_DOWN;
}
-static void btc_a2dp_source_ctrl_post(uint32_t sig, void *par)
+static void btc_a2dp_source_ctrl_post(uint32_t sig, void *param)
{
- BtTaskEvt_t *evt = (BtTaskEvt_t *)osi_malloc(sizeof(BtTaskEvt_t));
+ a2dp_src_task_evt_t *evt = (a2dp_src_task_evt_t *)osi_malloc(sizeof(a2dp_src_task_evt_t));
+
if (evt == NULL) {
return;
}
evt->sig = sig;
- evt->par = par;
+ evt->param = param;
- if (xQueueSend(btc_aa_src_ctrl_queue, &evt, portMAX_DELAY) != pdTRUE) {
- APPL_TRACE_WARNING("btc_aa_src_ctrl_queue failed, sig 0x%x\n", sig);
- }
+ osi_thread_post(btc_aa_src_task_hdl, btc_a2dp_source_ctrl_handler, evt, 0, OSI_THREAD_BLOCKING);
}
-static void btc_a2dp_source_ctrl_handler(BtTaskEvt_t *e)
+static void btc_a2dp_source_ctrl_handler(void *arg)
{
+ a2dp_src_task_evt_t *e = (a2dp_src_task_evt_t *)arg;
+
if (e == NULL) {
return;
}
+
switch (e->sig) {
case BTC_MEDIA_TASK_INIT:
btc_a2dp_source_thread_init(NULL);
btc_a2dp_source_aa_stop_tx();
break;
case BTC_MEDIA_SBC_ENC_INIT:
- btc_a2dp_source_enc_init(e->par);
+ btc_a2dp_source_enc_init(e->param);
break;
case BTC_MEDIA_SBC_ENC_UPDATE:
- btc_a2dp_source_enc_update(e->par);
+ btc_a2dp_source_enc_update(e->param);
break;
case BTC_MEDIA_AUDIO_FEEDING_INIT:
- btc_a2dp_source_audio_feeding_init(e->par);
+ btc_a2dp_source_audio_feeding_init(e->param);
break;
case BTC_MEDIA_FLUSH_AA_TX:
btc_a2dp_source_aa_tx_flush();
default:
APPL_TRACE_WARNING("media task unhandled evt: 0x%x\n", e->sig);
}
- if (e->par != NULL) {
- osi_free(e->par);
- }
-}
-static void btc_a2dp_source_task_handler(void *arg)
-{
- QueueSetMemberHandle_t xActivatedMember;
- BtTaskEvt_t *e = NULL;
- for (;;) {
- xActivatedMember = xQueueSelectFromSet(btc_aa_src_queue_set, portMAX_DELAY);
- if (xActivatedMember == btc_aa_src_data_queue) {
- int32_t data_evt;
- xQueueReceive(xActivatedMember, &data_evt, 0);
- if (data_evt == BTC_A2DP_SOURCE_DATA_EVT) {
- btc_a2dp_source_handle_timer(NULL);
- }
- } else if (xActivatedMember == btc_aa_src_ctrl_queue) {
- xQueueReceive(xActivatedMember, &e, 0);
- btc_a2dp_source_ctrl_handler(e);
- osi_free(e);
- }
+ if (e->param != NULL) {
+ osi_free(e->param);
}
+
+ osi_free(e);
}
bool btc_a2dp_source_startup(void)
}
#endif /* #if BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE */
- btc_aa_src_queue_set = xQueueCreateSet(BTC_A2DP_SOURCE_TASK_QUEUE_SET_LEN);
- configASSERT(btc_aa_src_queue_set);
- btc_aa_src_data_queue = xQueueCreate(BTC_A2DP_SOURCE_DATA_QUEUE_LEN, sizeof(void *));
- configASSERT(btc_aa_src_data_queue);
- xQueueAddToSet(btc_aa_src_data_queue, btc_aa_src_queue_set);
-
- btc_aa_src_ctrl_queue = xQueueCreate(BTC_A2DP_SOURCE_CTRL_QUEUE_LEN, sizeof(void *));
- configASSERT(btc_aa_src_ctrl_queue);
- xQueueAddToSet(btc_aa_src_ctrl_queue, btc_aa_src_queue_set);
-
- if (!btc_aa_src_data_queue || !btc_aa_src_ctrl_queue || !btc_aa_src_queue_set ) {
- goto error_exit;
- }
-
- xTaskCreatePinnedToCore(btc_a2dp_source_task_handler, BTC_A2DP_SOURCE_TASK_NAME, BTC_A2DP_SOURCE_TASK_STACK_SIZE, NULL, BTC_A2DP_SOURCE_TASK_PRIO, &btc_aa_src_task_hdl, BTC_A2DP_SOURCE_TASK_PINNED_TO_CORE);
+ btc_aa_src_task_hdl = osi_thread_create(BTC_A2DP_SOURCE_TASK_NAME, BTC_A2DP_SOURCE_TASK_STACK_SIZE, BTC_A2DP_SOURCE_TASK_PRIO, BTC_A2DP_SOURCE_TASK_PINNED_TO_CORE, 2);
if (btc_aa_src_task_hdl == NULL) {
goto error_exit;
}
btc_a2dp_source_ctrl_post(BTC_MEDIA_TASK_INIT, NULL);
-
APPL_TRACE_EVENT("## A2DP SOURCE MEDIA THREAD STARTED ##\n");
return true;
error_exit:;
APPL_TRACE_ERROR("%s unable to start up media thread\n", __func__);
+ osi_thread_free(btc_aa_src_task_hdl);
+ btc_aa_src_task_hdl = NULL;
- if (btc_aa_src_task_hdl != NULL) {
- vTaskDelete(btc_aa_src_task_hdl);
- btc_aa_src_task_hdl = NULL;
- }
-
- if (btc_aa_src_data_queue) {
- vQueueDelete(btc_aa_src_data_queue);
- btc_aa_src_data_queue = NULL;
- }
- if (btc_aa_src_ctrl_queue) {
- vQueueDelete(btc_aa_src_ctrl_queue);
- btc_aa_src_ctrl_queue = NULL;
- }
- if (btc_aa_src_queue_set) {
- vQueueDelete(btc_aa_src_queue_set);
- btc_aa_src_queue_set = NULL;
- }
#if (BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE)
if (btc_sbc_encoder_ptr) {
osi_free(btc_sbc_encoder_ptr);
btc_sbc_encoder_ptr = NULL;
}
#endif /* #if BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE */
+
return false;
}
future_await(btc_a2dp_source_future);
btc_a2dp_source_future = NULL;
- vTaskDelete(btc_aa_src_task_hdl);
+ osi_thread_free(btc_aa_src_task_hdl);
btc_aa_src_task_hdl = NULL;
- vQueueDelete(btc_aa_src_data_queue);
- btc_aa_src_data_queue = NULL;
-
- vQueueDelete(btc_aa_src_ctrl_queue);
- btc_aa_src_ctrl_queue = NULL;
-
- vQueueDelete(btc_aa_src_queue_set);
- btc_aa_src_queue_set = NULL;
-
#if (BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE)
osi_free(btc_sbc_encoder_ptr);
btc_sbc_encoder_ptr = NULL;
btc_a2dp_source_stop_audio_req();
}
-static void btc_a2dp_source_data_post(int32_t data_type)
+static void btc_a2dp_source_data_post(void)
{
- if (xQueueSend(btc_aa_src_data_queue, &data_type, 0) != pdTRUE) {
- APPL_TRACE_DEBUG("Media data Q filled\n");
- }
+ osi_thread_post(btc_aa_src_task_hdl, btc_a2dp_source_handle_timer, NULL, 1, OSI_THREAD_BLOCKING);
}
static UINT64 time_now_us()
* the "cleanup() -> btc_a2dp_stop_media_task()" processing during
* the shutdown of the Bluetooth stack.
*/
+#if 0
if (btc_aa_src_ctrl_queue != NULL) {
+#endif
btc_a2dp_source_ctrl_post(BTC_MEDIA_STOP_AA_TX, NULL);
+#if 0
}
+#endif
return TRUE;
}
* the "cleanup() -> btc_a2dp_stop_media_task()" processing during
* the shutdown of the Bluetooth stack.
*/
+#if 0
if (btc_aa_src_ctrl_queue != NULL) {
+#endif
btc_a2dp_source_ctrl_post(BTC_MEDIA_FLUSH_AA_TX, NULL);
+#if 0
}
+#endif
return TRUE;
}
static void btc_a2dp_source_alarm_cb(UNUSED_ATTR void *context)
{
- btc_a2dp_source_data_post(BTC_A2DP_SOURCE_DATA_EVT);
+ btc_a2dp_source_data_post();
}
/*******************************************************************************
#include "stack/dyn_mem.h" /* defines static and/or dynamic memory for components */
+
+/* OS Configuration from User config (eg: sdkconfig) */
+#if CONFIG_BLUEDROID_PINNED_TO_CORE
+#define TASK_PINNED_TO_CORE (CONFIG_BLUEDROID_PINNED_TO_CORE < portNUM_PROCESSORS ? CONFIG_BLUEDROID_PINNED_TO_CORE : tskNO_AFFINITY)
+#else
+#define TASK_PINNED_TO_CORE (0)
+#endif
+
/******************************************************************************
**
** Classic BT features
#include "esp_bt.h"
#include "stack/hcimsgs.h"
+#define HCI_H4_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
+#define HCI_H4_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE)
+#define HCI_H4_TASK_PRIO (configMAX_PRIORITIES - 4)
+#define HCI_H4_TASK_NAME "hciH4T"
+#define HCI_H4_QUEUE_LEN 1
+
+
#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
#include "l2c_int.h"
#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
+#include "stack/hcimsgs.h"
#define HCI_HAL_SERIAL_BUFFER_SIZE 1026
#define HCI_BLE_EVENT 0x3e
static const hci_hal_t interface;
static const hci_hal_callbacks_t *callbacks;
static const esp_vhci_host_callback_t vhci_host_cb;
-
-static xTaskHandle xHciH4TaskHandle;
-static xQueueHandle xHciH4Queue;
+static osi_thread_t *hci_h4_thread;
static void host_send_pkt_available_cb(void);
static int host_recv_pkt_cb(uint8_t *data, uint16_t len);
hci_hal_env_init(HCI_HAL_SERIAL_BUFFER_SIZE, QUEUE_SIZE_MAX);
#endif
- xHciH4Queue = xQueueCreate(HCI_H4_QUEUE_LEN, sizeof(BtTaskEvt_t));
- xTaskCreatePinnedToCore(hci_hal_h4_rx_handler, HCI_H4_TASK_NAME, HCI_H4_TASK_STACK_SIZE, NULL, HCI_H4_TASK_PRIO, &xHciH4TaskHandle, HCI_H4_TASK_PINNED_TO_CORE);
+ hci_h4_thread = osi_thread_create(HCI_H4_TASK_NAME, HCI_H4_TASK_STACK_SIZE, HCI_H4_TASK_PRIO, HCI_H4_TASK_PINNED_TO_CORE, 1);
+ if (hci_h4_thread == NULL) {
+ return false;
+ }
//register vhci host cb
if (esp_vhci_host_register_callback(&vhci_host_cb) != ESP_OK) {
{
hci_hal_env_deinit();
- /* delete task and queue */
- vTaskDelete(xHciH4TaskHandle);
- vQueueDelete(xHciH4Queue);
+ osi_thread_free(hci_h4_thread);
+ hci_h4_thread = NULL;
}
/**
// Internal functions
static void hci_hal_h4_rx_handler(void *arg)
{
- BtTaskEvt_t e;
-
- for (;;) {
- if (pdTRUE == xQueueReceive(xHciH4Queue, &e, (portTickType)portMAX_DELAY)) {
- if (e.sig == SIG_HCI_HAL_RECV_PACKET) {
- fixed_queue_process(hci_hal_env.rx_q);
-
- }
- }
- }
+ fixed_queue_process(hci_hal_env.rx_q);
}
-task_post_status_t hci_hal_h4_task_post(task_post_t timeout)
+bool hci_hal_h4_task_post(osi_thread_blocking_t blocking)
{
- BtTaskEvt_t evt;
-
- evt.sig = SIG_HCI_HAL_RECV_PACKET;
- evt.par = 0;
-
- if (xQueueSend(xHciH4Queue, &evt, timeout) != pdTRUE) {
- return TASK_POST_SUCCESS;
- }
-
- return TASK_POST_FAIL;
+ return osi_thread_post(hci_h4_thread, hci_hal_h4_rx_handler, NULL, 0, blocking);
}
#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
{
//Controller rx cache buffer is ready for receiving new host packet
//Just Call Host main thread task to process pending packets.
- hci_host_task_post(TASK_POST_BLOCKING);
+ hci_host_task_post(OSI_THREAD_BLOCKING);
}
static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
pkt->layer_specific = 0;
memcpy(pkt->data, data, len);
fixed_queue_enqueue(hci_hal_env.rx_q, pkt);
- hci_hal_h4_task_post(0);
+ hci_hal_h4_task_post(OSI_THREAD_NON_BLOCKING);
+
BTTRC_DUMP_BUFFER("Recv Pkt", pkt->data, len);
#include "common/bt_trace.h"
#include "stack/hcidefs.h"
#include "stack/hcimsgs.h"
+#include "stack/btu.h"
#include "common/bt_vendor_lib.h"
#include "hci/hci_internals.h"
#include "hci/hci_hal.h"
#include "osi/mutex.h"
#include "osi/fixed_queue.h"
+#define HCI_HOST_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
+#define HCI_HOST_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE)
+#define HCI_HOST_TASK_PRIO (configMAX_PRIORITIES - 3)
+#define HCI_HOST_TASK_NAME "hciHostT"
+#define HCI_HOST_QUEUE_LEN 40
+
typedef struct {
uint16_t opcode;
future_t *complete_future;
static bool interface_created;
static hci_t interface;
static hci_host_env_t hci_host_env;
-
-static xTaskHandle xHciHostTaskHandle;
-static xQueueHandle xHciHostQueue;
-
+static osi_thread_t *hci_host_thread;
static bool hci_host_startup_flag;
// Modules we import and callbacks we export
goto error;
}
- xHciHostQueue = xQueueCreate(HCI_HOST_QUEUE_LEN, sizeof(BtTaskEvt_t));
- xTaskCreatePinnedToCore(hci_host_thread_handler, HCI_HOST_TASK_NAME, HCI_HOST_TASK_STACK_SIZE, NULL, HCI_HOST_TASK_PRIO, &xHciHostTaskHandle, HCI_HOST_TASK_PINNED_TO_CORE);
+ hci_host_thread = osi_thread_create(HCI_HOST_TASK_NAME, HCI_HOST_TASK_STACK_SIZE, HCI_HOST_TASK_PRIO, HCI_HOST_TASK_PINNED_TO_CORE, 1);
+ if (hci_host_thread == NULL) {
+ return -2;
+ }
packet_fragmenter->init(&packet_fragmenter_callbacks);
hal->open(&hal_callbacks);
//low_power_manager->cleanup();
hal->close();
- vTaskDelete(xHciHostTaskHandle);
- vQueueDelete(xHciHostQueue);
+
+ osi_thread_free(hci_host_thread);
+ hci_host_thread = NULL;
}
-task_post_status_t hci_host_task_post(task_post_t timeout)
+bool hci_host_task_post(osi_thread_blocking_t blocking)
{
- BtTaskEvt_t evt;
-
- if (hci_host_startup_flag == false) {
- return TASK_POST_FAIL;
- }
-
- evt.sig = SIG_HCI_HOST_SEND_AVAILABLE;
- evt.par = 0;
-
- if (xQueueSend(xHciHostQueue, &evt, timeout) != pdTRUE) {
- HCI_TRACE_ERROR("xHciHostQueue failed\n");
- return TASK_POST_FAIL;
- }
-
- return TASK_POST_SUCCESS;
+ return osi_thread_post(hci_host_thread, hci_host_thread_handler, NULL, 0, blocking);
}
static int hci_layer_init_env(void)
* All packets will be directly copied to single queue in driver layer with
* H4 type header added (1 byte).
*/
-
- BtTaskEvt_t e;
-
- for (;;) {
- if (pdTRUE == xQueueReceive(xHciHostQueue, &e, (portTickType)portMAX_DELAY)) {
-
- if (e.sig == SIG_HCI_HOST_SEND_AVAILABLE) {
- if (esp_vhci_host_check_send_available()) {
- /*Now Target only allowed one packet per TX*/
- BT_HDR *pkt = packet_fragmenter->fragment_current_packet();
- if (pkt != NULL) {
- packet_fragmenter->fragment_and_dispatch(pkt);
- } else {
- if (!fixed_queue_is_empty(hci_host_env.command_queue) &&
- hci_host_env.command_credits > 0) {
- fixed_queue_process(hci_host_env.command_queue);
- } else if (!fixed_queue_is_empty(hci_host_env.packet_queue)) {
- fixed_queue_process(hci_host_env.packet_queue);
- }
- }
- }
+ if (esp_vhci_host_check_send_available()) {
+ /*Now Target only allowed one packet per TX*/
+ BT_HDR *pkt = packet_fragmenter->fragment_current_packet();
+ if (pkt != NULL) {
+ packet_fragmenter->fragment_and_dispatch(pkt);
+ } else {
+ if (!fixed_queue_is_empty(hci_host_env.command_queue) &&
+ hci_host_env.command_credits > 0) {
+ fixed_queue_process(hci_host_env.command_queue);
+ } else if (!fixed_queue_is_empty(hci_host_env.packet_queue)) {
+ fixed_queue_process(hci_host_env.packet_queue);
}
}
}
BTTRC_DUMP_BUFFER(NULL, command->data + command->offset, command->len);
fixed_queue_enqueue(hci_host_env.command_queue, wait_entry);
- hci_host_task_post(TASK_POST_BLOCKING);
+ hci_host_task_post(OSI_THREAD_BLOCKING);
}
command->event = MSG_STACK_TO_HC_HCI_CMD;
fixed_queue_enqueue(hci_host_env.command_queue, wait_entry);
- hci_host_task_post(TASK_POST_BLOCKING);
+ hci_host_task_post(OSI_THREAD_BLOCKING);
return future;
}
fixed_queue_enqueue(hci_host_env.packet_queue, data);
}
- hci_host_task_post(TASK_POST_BLOCKING);
+ hci_host_task_post(OSI_THREAD_BLOCKING);
}
/*Tell HCI Host Task to continue TX Pending commands*/
if (hci_host_env.command_credits &&
!fixed_queue_is_empty(hci_host_env.command_queue)) {
- hci_host_task_post(TASK_POST_BLOCKING);
+ hci_host_task_post(OSI_THREAD_BLOCKING);
}
if (wait_entry) {
{
// Events should already have been dispatched before this point
//Tell Up-layer received packet.
- if (btu_task_post(SIG_BTU_HCI_MSG, packet, TASK_POST_BLOCKING) != TASK_POST_SUCCESS) {
+ if (btu_task_post(SIG_BTU_HCI_MSG, packet, OSI_THREAD_BLOCKING) == false) {
osi_free(packet);
}
}
#include "osi/allocator.h"
#include "osi/osi.h"
#include "osi/future.h"
+#include "osi/thread.h"
+
///// LEGACY DEFINITIONS /////
/* Message event mask across Host/Controller lib and stack */
int hci_start_up(void);
void hci_shut_down(void);
+bool hci_host_task_post(osi_thread_blocking_t blocking);
#endif /* _HCI_LAYER_H_ */
#define portBASE_TYPE int
-struct bt_task_evt {
- uint32_t sig; //task sig
- void *par; //point to task param
- void *cb; //point to function cb
- void *arg; //point to function arg
-};
-typedef struct bt_task_evt BtTaskEvt_t;
+struct osi_thread;
-typedef bt_status_t (* BtTaskCb_t)(void *arg);
-
-typedef enum {
- SIG_HCI_HAL_RECV_PACKET = 0,
- SIG_HCI_HAL_NUM,
-} SIG_HCI_HAL_t;
+typedef struct osi_thread osi_thread_t;
+typedef void (*osi_thread_func_t)(void *context);
typedef enum {
- SIG_HCI_HOST_SEND_AVAILABLE = 0,
- SIG_HCI_HOST_NUM,
-} SIG_HCI_HOST_t;
+ OSI_THREAD_CORE_0 = 0,
+ OSI_THREAD_CORE_1,
+ OSI_THREAD_CORE_AFFINITY,
+} osi_thread_core_t;
typedef enum {
- SIG_BTU_START_UP = 0,
- SIG_BTU_HCI_MSG,
- SIG_BTU_BTA_MSG,
- SIG_BTU_BTA_ALARM,
- SIG_BTU_GENERAL_ALARM,
- SIG_BTU_ONESHOT_ALARM,
- SIG_BTU_L2CAP_ALARM,
- SIG_BTU_NUM,
-} SIG_BTU_t;
-
-#define TASK_PINNED_TO_CORE (CONFIG_BT_BLUEDROID_PINNED_TO_CORE < portNUM_PROCESSORS ? CONFIG_BT_BLUEDROID_PINNED_TO_CORE : tskNO_AFFINITY)
-
-#define HCI_HOST_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
-#define HCI_HOST_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE)
-#define HCI_HOST_TASK_PRIO (configMAX_PRIORITIES - 3)
-#define HCI_HOST_TASK_NAME "hciHostT"
-#define HCI_HOST_QUEUE_LEN 40
-
-#define HCI_H4_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
-#define HCI_H4_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE)
-#define HCI_H4_TASK_PRIO (configMAX_PRIORITIES - 4)
-#define HCI_H4_TASK_NAME "hciH4T"
-#define HCI_H4_QUEUE_LEN 1
-
-#define BTU_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
-#define BTU_TASK_STACK_SIZE (CONFIG_BT_BTU_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE)
-#define BTU_TASK_PRIO (configMAX_PRIORITIES - 5)
-#define BTU_TASK_NAME "btuT"
-#define BTU_QUEUE_LEN 50
-
-#define BTC_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
-#define BTC_TASK_STACK_SIZE (CONFIG_BT_BTC_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) //by menuconfig
-#define BTC_TASK_NAME "btcT"
-#define BTC_TASK_PRIO (configMAX_PRIORITIES - 6)
-#define BTC_TASK_QUEUE_LEN 60
-
-#define BTC_A2DP_SINK_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
-#define BTC_A2DP_SINK_TASK_STACK_SIZE (CONFIG_BT_A2DP_SINK_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) // by menuconfig
-#define BTC_A2DP_SINK_TASK_NAME "BtA2dSinkT"
-#define BTC_A2DP_SINK_TASK_PRIO (configMAX_PRIORITIES - 3)
-#define BTC_A2DP_SINK_DATA_QUEUE_LEN (3)
-#define BTC_A2DP_SINK_CTRL_QUEUE_LEN (5)
-#define BTC_A2DP_SINK_TASK_QUEUE_SET_LEN (BTC_A2DP_SINK_DATA_QUEUE_LEN + BTC_A2DP_SINK_CTRL_QUEUE_LEN)
-
-#define BTC_A2DP_SOURCE_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
-#define BTC_A2DP_SOURCE_TASK_STACK_SIZE (CONFIG_BT_A2DP_SOURCE_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) // by menuconfig
-#define BTC_A2DP_SOURCE_TASK_NAME "BtA2dSourceT"
-#define BTC_A2DP_SOURCE_TASK_PRIO (configMAX_PRIORITIES - 3)
-#define BTC_A2DP_SOURCE_DATA_QUEUE_LEN (1)
-#define BTC_A2DP_SOURCE_CTRL_QUEUE_LEN (5)
-#define BTC_A2DP_SOURCE_TASK_QUEUE_SET_LEN (BTC_A2DP_SOURCE_DATA_QUEUE_LEN + BTC_A2DP_SOURCE_CTRL_QUEUE_LEN)
-
-#define TASK_POST_NON_BLOCKING (0)
-#define TASK_POST_BLOCKING (portMAX_DELAY)
-typedef uint32_t task_post_t; /* Timeout of task post return, unit TICK */
+ OSI_THREAD_NON_BLOCKING = 0,
+ OSI_THREAD_BLOCKING,
+} osi_thread_blocking_t;
-typedef enum {
- TASK_POST_SUCCESS = 0,
- TASK_POST_FAIL,
-} task_post_status_t;
+osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priority, osi_thread_core_t core, uint8_t work_queue_num);
+
+void osi_thread_free(osi_thread_t *thread);
+
+bool osi_thread_post(osi_thread_t *thread, osi_thread_func_t func, void *context, int queue_idx, osi_thread_blocking_t blocking);
+
+bool osi_thread_set_priority(osi_thread_t *thread, int priority);
+
+const char *osi_thread_name(osi_thread_t *thread);
-task_post_status_t btu_task_post(uint32_t sig, void *param, task_post_t timeout);
-task_post_status_t hci_host_task_post(task_post_t timeout);
-task_post_status_t hci_hal_h4_task_post(task_post_t timeout);
+int osi_thread_queue_wait_size(osi_thread_t *thread, int wq_idx);
#endif /* __THREAD_H__ */
--- /dev/null
+/******************************************************************************
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+#include <string.h>
+
+#include "osi/allocator.h"
+#include "osi/fixed_queue.h"
+#include "osi/semaphore.h"
+#include "osi/thread.h"
+
+struct osi_thread {
+ void *thread_handle; /*!< Store the thread object */
+ int thread_id; /*!< May for some OS, such as Linux */
+ bool stop;
+ uint8_t work_queue_num; /*!< Work queue number */
+ fixed_queue_t **work_queues; /*!< Point to queue array, and the priority inverse array index */
+ osi_sem_t work_sem;
+ osi_sem_t stop_sem;
+};
+
+struct osi_thread_start_arg {
+ osi_thread_t *thread;
+ osi_sem_t start_sem;
+ int error;
+};
+
+typedef struct {
+ osi_thread_func_t func;
+ void *context;
+} work_item_t;
+
+static const size_t DEFAULT_WORK_QUEUE_CAPACITY = 100;
+
+static void osi_thread_run(void *arg)
+{
+ struct osi_thread_start_arg *start = (struct osi_thread_start_arg *)arg;
+ osi_thread_t *thread = start->thread;
+
+ osi_sem_give(&start->start_sem);
+
+ while (1) {
+ int idx = 0;
+
+ osi_sem_take(&thread->work_sem, OSI_SEM_MAX_TIMEOUT);
+
+ if (thread->stop) {
+ break;
+ }
+
+ while (!thread->stop && idx < thread->work_queue_num) {
+ work_item_t *item = fixed_queue_try_dequeue(thread->work_queues[idx]);
+ if (item) {
+ item->func(item->context);
+ osi_free(item);
+ idx = 0;
+ continue;
+ } else {
+ idx++;
+ }
+ }
+ }
+
+ thread->thread_handle = NULL;
+ osi_sem_give(&thread->stop_sem);
+
+ vTaskDelete(NULL);
+}
+
+static int osi_thread_join(osi_thread_t *thread, uint32_t wait_ms)
+{
+ assert(thread != NULL);
+ return osi_sem_take(&thread->stop_sem, wait_ms);
+}
+
+static void osi_thread_stop(osi_thread_t *thread)
+{
+ int ret;
+
+ assert(thread != NULL);
+
+ //stop the thread
+ thread->stop = true;
+ osi_sem_give(&thread->work_sem);
+
+ //join
+ ret = osi_thread_join(thread, 1000); //wait 1000ms
+
+ //if join failed, delete the task here
+ if (ret != 0 && thread->thread_handle) {
+ vTaskDelete(thread->thread_handle);
+ }
+}
+
+//in linux, the stack_size, priority and core may not be set here, the code will be ignore the arguments
+osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priority, osi_thread_core_t core, uint8_t work_queue_num)
+{
+ int ret;
+ osi_thread_t *thread;
+ struct osi_thread_start_arg start_arg = {0};
+
+ if (stack_size <= 0 ||
+ core < OSI_THREAD_CORE_0 || core > OSI_THREAD_CORE_AFFINITY ||
+ work_queue_num <= 0) {
+ return NULL;
+ }
+
+ thread = (osi_thread_t *)osi_malloc(sizeof(osi_thread_t));
+ if (thread == NULL) {
+ goto _err;
+ }
+
+ thread->stop = false;
+ thread->work_queue_num = work_queue_num;
+ thread->work_queues = (fixed_queue_t **)osi_malloc(sizeof(fixed_queue_t *) * work_queue_num);
+ if (thread->work_queues == NULL) {
+ goto _err;
+ }
+
+ for (int i = 0; i < thread->work_queue_num; i++) {
+ thread->work_queues[i] = fixed_queue_new(DEFAULT_WORK_QUEUE_CAPACITY);
+ if (thread->work_queues[i] == NULL) {
+ goto _err;
+ }
+ }
+
+ ret = osi_sem_new(&thread->work_sem, 1, 0);
+ if (ret != 0) {
+ goto _err;
+ }
+
+ ret = osi_sem_new(&thread->stop_sem, 1, 0);
+ if (ret != 0) {
+ goto _err;
+ }
+
+ start_arg.thread = thread;
+ ret = osi_sem_new(&start_arg.start_sem, 1, 0);
+ if (ret != 0) {
+ goto _err;
+ }
+
+ if (xTaskCreatePinnedToCore(osi_thread_run, name, stack_size, &start_arg, priority, &thread->thread_handle, core) != pdPASS) {
+ goto _err;
+ }
+
+ osi_sem_take(&start_arg.start_sem, OSI_SEM_MAX_TIMEOUT);
+ osi_sem_free(&start_arg.start_sem);
+
+ return thread;
+
+_err:
+
+ if (thread) {
+ if (start_arg.start_sem) {
+ osi_sem_free(&start_arg.start_sem);
+ }
+
+ if (thread->thread_handle) {
+ vTaskDelete(thread->thread_handle);
+ }
+
+ for (int i = 0; i < thread->work_queue_num; i++) {
+ if (thread->work_queues[i]) {
+ fixed_queue_free(thread->work_queues[i], osi_free_func);
+ }
+ }
+
+ if (thread->work_queues) {
+ osi_free(thread->work_queues);
+ }
+
+ if (thread->work_sem) {
+ osi_sem_free(&thread->work_sem);
+ }
+
+ if (thread->stop_sem) {
+ osi_sem_free(&thread->stop_sem);
+ }
+
+ osi_free(thread);
+ }
+
+ return NULL;
+}
+
+void osi_thread_free(osi_thread_t *thread)
+{
+ if (!thread)
+ return;
+
+ osi_thread_stop(thread);
+
+ for (int i = 0; i < thread->work_queue_num; i++) {
+ if (thread->work_queues[i]) {
+ fixed_queue_free(thread->work_queues[i], osi_free_func);
+ }
+ }
+
+ if (thread->work_queues) {
+ osi_free(thread->work_queues);
+ }
+
+ if (thread->work_sem) {
+ osi_sem_free(&thread->work_sem);
+ }
+
+ if (thread->stop_sem) {
+ osi_sem_free(&thread->stop_sem);
+ }
+
+
+ osi_free(thread);
+}
+
+bool osi_thread_post(osi_thread_t *thread, osi_thread_func_t func, void *context, int queue_idx, osi_thread_blocking_t blocking)
+{
+ assert(thread != NULL);
+ assert(func != NULL);
+
+ if (queue_idx >= thread->work_queue_num) {
+ return false;
+ }
+
+ work_item_t *item = (work_item_t *)osi_malloc(sizeof(work_item_t));
+ if (item == NULL) {
+ return false;
+ }
+ item->func = func;
+ item->context = context;
+
+ if (blocking == OSI_THREAD_BLOCKING) {
+ fixed_queue_enqueue(thread->work_queues[queue_idx], item);
+ } else {
+ if (fixed_queue_try_enqueue(thread->work_queues[queue_idx], item) == false) {
+ osi_free(item);
+ return false;
+ }
+ }
+
+ osi_sem_give(&thread->work_sem);
+
+ return true;
+}
+
+bool osi_thread_set_priority(osi_thread_t *thread, int priority)
+{
+ assert(thread != NULL);
+
+ vTaskPrioritySet(thread->thread_handle, priority);
+ return true;
+}
+
+const char *osi_thread_name(osi_thread_t *thread)
+{
+ assert(thread != NULL);
+
+ return pcTaskGetTaskName(thread->thread_handle);
+}
+
+int osi_thread_queue_wait_size(osi_thread_t *thread, int wq_idx)
+{
+ if (wq_idx < 0 || wq_idx >= thread->work_queue_num) {
+ return -1;
+ }
+
+ return fixed_queue_length(thread->work_queues[wq_idx]);
+}
event->event = BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK;
- btu_task_post(SIG_BTU_HCI_MSG, event, TASK_POST_BLOCKING);
+ btu_task_post(SIG_BTU_HCI_MSG, event, OSI_THREAD_BLOCKING);
}
event->event = BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK;
- btu_task_post(SIG_BTU_HCI_MSG, event, TASK_POST_BLOCKING);
+ btu_task_post(SIG_BTU_HCI_MSG, event, OSI_THREAD_BLOCKING);
}
/*******************************************************************************
#endif
#endif
+#define BTU_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
+#define BTU_TASK_STACK_SIZE (4096 + BT_TASK_EXTRA_STACK_SIZE)
+#define BTU_TASK_PRIO (configMAX_PRIORITIES - 5)
+#define BTU_TASK_NAME "btuT"
+#define BTU_QUEUE_LEN 50
+
hash_map_t *btu_general_alarm_hash_map;
osi_mutex_t btu_general_alarm_lock;
static const size_t BTU_GENERAL_ALARM_HASH_MAP_SIZE = 34;
osi_mutex_t btu_l2cap_alarm_lock;
static const size_t BTU_L2CAP_ALARM_HASH_MAP_SIZE = 34;
-//thread_t *bt_workqueue_thread;
-//static const char *BT_WORKQUEUE_NAME = "bt_workqueue";
-xTaskHandle xBtuTaskHandle = NULL;
-xQueueHandle xBtuQueue = 0;
+osi_thread_t *btu_thread = NULL;
extern void PLATFORM_DisableHciTransport(UINT8 bDisable);
extern void btu_task_thread_handler(void *arg);
void btu_task_start_up(void);
void btu_task_shut_down(void);
+
/*****************************************************************************
** V A R I A B L E S *
******************************************************************************/
osi_mutex_new(&btu_l2cap_alarm_lock);
- xBtuQueue = xQueueCreate(BTU_QUEUE_LEN, sizeof(BtTaskEvt_t));
- xTaskCreatePinnedToCore(btu_task_thread_handler, BTU_TASK_NAME, BTU_TASK_STACK_SIZE, NULL, BTU_TASK_PRIO, &xBtuTaskHandle, BTU_TASK_PINNED_TO_CORE);
+ btu_thread = osi_thread_create(BTU_TASK_NAME, BTU_TASK_STACK_SIZE, BTU_TASK_PRIO, BTU_TASK_PINNED_TO_CORE, 1);
+ if (btu_thread == NULL) {
+ goto error_exit;
+ }
- btu_task_post(SIG_BTU_START_UP, NULL, TASK_POST_BLOCKING);
+ if (btu_task_post(SIG_BTU_START_UP, NULL, OSI_THREAD_BLOCKING) == false) {
+ goto error_exit;
+ }
return;
hash_map_free(btu_l2cap_alarm_hash_map);
osi_mutex_free(&btu_l2cap_alarm_lock);
- vTaskDelete(xBtuTaskHandle);
- vQueueDelete(xBtuQueue);
-
- btu_general_alarm_hash_map = NULL;
+ if (btu_thread) {
+ osi_thread_free(btu_thread);
+ btu_thread = NULL;
+ }
+ btu_general_alarm_hash_map = NULL;
btu_oneshot_alarm_hash_map = NULL;
-
btu_l2cap_alarm_hash_map = NULL;
-
- xBtuTaskHandle = NULL;
- xBtuQueue = 0;
}
/*****************************************************************************
return 0;
#endif
}
+
#if SCAN_QUEUE_CONGEST_CHECK
bool BTU_check_queue_is_congest(void)
{
- UBaseType_t wait_size = uxQueueMessagesWaiting(xBtuQueue);
- if(wait_size >= QUEUE_CONGEST_SIZE ) {
+ if (osi_thread_queue_wait_size(btu_thread, 0) >= QUEUE_CONGEST_SIZE) {
return true;
}
+
return false;
}
#endif
#include "btm_ble_int.h"
#endif
+typedef struct {
+ uint32_t sig;
+ void *param;
+} btu_thread_evt_t;
+
//#if (defined(BT_APP_DEMO) && BT_APP_DEMO == TRUE)
//#include "bt_app_common.h"
//#endif
extern hash_map_t *btu_l2cap_alarm_hash_map;
extern osi_mutex_t btu_l2cap_alarm_lock;
-extern xTaskHandle xBtuTaskHandle;
-extern xQueueHandle xBtuQueue;
+extern void *btu_thread;
+
extern bluedroid_init_done_cb_t bluedroid_init_done_cb;
/* Define a function prototype to allow a generic timeout handler */
}
#endif
-/*****************************************************************************
-**
-** Function btu_task_thread_handler
-**
-** Description Process BTU Task Thread.
-******************************************************************************/
-void btu_task_thread_handler(void *arg)
+void btu_thread_handler(void *arg)
{
- BtTaskEvt_t e;
-
- for (;;) {
- if (pdTRUE == xQueueReceive(xBtuQueue, &e, (portTickType)portMAX_DELAY)) {
-
- switch (e.sig) {
- case SIG_BTU_START_UP:
- btu_task_start_up();
- break;
- case SIG_BTU_HCI_MSG:
- btu_hci_msg_process((BT_HDR *)e.par);
- break;
+ btu_thread_evt_t *evt = (btu_thread_evt_t *)arg;
+
+ switch (evt->sig) {
+ case SIG_BTU_START_UP:
+ btu_task_start_up();
+ break;
+ case SIG_BTU_HCI_MSG:
+ btu_hci_msg_process((BT_HDR *)evt->param);
+ break;
#if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
- case SIG_BTU_BTA_MSG:
- bta_sys_event((BT_HDR *)e.par);
- break;
- case SIG_BTU_BTA_ALARM:
- btu_bta_alarm_process((TIMER_LIST_ENT *)e.par);
- break;
+ case SIG_BTU_BTA_MSG:
+ bta_sys_event((BT_HDR *)evt->param);
+ break;
+ case SIG_BTU_BTA_ALARM:
+ btu_bta_alarm_process((TIMER_LIST_ENT *)evt->param);
+ break;
#endif
- case SIG_BTU_GENERAL_ALARM:
- btu_general_alarm_process((TIMER_LIST_ENT *)e.par);
- break;
- case SIG_BTU_ONESHOT_ALARM: {
- TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)e.par;
- btu_general_alarm_process(p_tle);
- break;
- }
- case SIG_BTU_L2CAP_ALARM:
- btu_l2cap_alarm_process((TIMER_LIST_ENT *)e.par);
- break;
- default:
- break;
- }
- }
+ case SIG_BTU_GENERAL_ALARM:
+ case SIG_BTU_ONESHOT_ALARM:
+ btu_general_alarm_process((TIMER_LIST_ENT *)evt->param);
+ break;
+ case SIG_BTU_L2CAP_ALARM:
+ btu_l2cap_alarm_process((TIMER_LIST_ENT *)evt->param);
+ break;
+ default:
+ break;
}
-}
+ osi_free(evt);
+}
-task_post_status_t btu_task_post(uint32_t sig, void *param, task_post_t timeout)
+bool btu_task_post(uint32_t sig, void *param, osi_thread_blocking_t blocking)
{
- BtTaskEvt_t evt;
+ btu_thread_evt_t *evt;
- evt.sig = sig;
- evt.par = param;
-
- if (xQueueSend(xBtuQueue, &evt, timeout) != pdTRUE) {
- HCI_TRACE_ERROR("xBtuQueue failed\n");
- return TASK_POST_FAIL;
+ evt = (btu_thread_evt_t *)osi_malloc(sizeof(btu_thread_evt_t));
+ if (evt == NULL) {
+ return false;
}
- return TASK_POST_SUCCESS;
+ evt->sig = sig;
+ evt->param = param;
+
+ return osi_thread_post(btu_thread, btu_thread_handler, evt, 0, blocking);
}
void btu_task_start_up(void)
assert(data != NULL);
TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
- btu_task_post(SIG_BTU_GENERAL_ALARM, p_tle, TASK_POST_BLOCKING);
+ btu_task_post(SIG_BTU_GENERAL_ALARM, p_tle, OSI_THREAD_BLOCKING);
}
void btu_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec)
assert(data != NULL);
TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
- btu_task_post(SIG_BTU_L2CAP_ALARM, p_tle, TASK_POST_BLOCKING);
+ btu_task_post(SIG_BTU_L2CAP_ALARM, p_tle, OSI_THREAD_BLOCKING);
}
void btu_start_quick_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_ticks)
btu_stop_timer_oneshot(p_tle);
- btu_task_post(SIG_BTU_ONESHOT_ALARM, p_tle, TASK_POST_BLOCKING);
+ btu_task_post(SIG_BTU_ONESHOT_ALARM, p_tle, OSI_THREAD_BLOCKING);
}
/*
#include "common/bt_target.h"
#include "common/bt_defs.h"
+#include "osi/thread.h"
// HACK(zachoverflow): temporary dark magic
#define BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK 0x1700 // didn't look used in bt_types...here goes nothing
#define BTU_TTYPE_UCD_TO 108
#define BTU_TTYPE_BLE_SCAN 109
+/* BTU Task Signal */
+typedef enum {
+ SIG_BTU_START_UP = 0,
+ SIG_BTU_HCI_MSG,
+ SIG_BTU_BTA_MSG,
+ SIG_BTU_BTA_ALARM,
+ SIG_BTU_GENERAL_ALARM,
+ SIG_BTU_ONESHOT_ALARM,
+ SIG_BTU_L2CAP_ALARM,
+ SIG_BTU_NUM,
+} SIG_BTU_t;
/* This is the inquiry response information held by BTU, and available
** to applications.
UINT16 BTU_BleAclPktSize(void);
+bool btu_task_post(uint32_t sig, void *param, osi_thread_blocking_t blocking);
+
/*
#ifdef __cplusplus
}