mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
refactor(ble_log): decouple runtime submission ownership
Move transport ownership from the runtime to the LBM: submit and recycle now hand the peripheral-owned flag explicitly instead of the runtime reaching back into LBM buffers. The submit path never blocks producers - a transport that cannot be queued is recycled immediately so its data survives for the next flush. Cross-context ownership accesses go through explicit atomic helpers: release-store on recycle pairs with acquire-loads in the flush paths, and the inflight high-water mark stays a relaxed CAS-max (a plain volatile update races the runtime hook's statistics reads).
This commit is contained in:
@@ -39,6 +39,7 @@ BLE_LOG_STATIC
|
||||
bool ble_log_lbm_acquire_trans(size_t log_len, ble_log_lbm_t **out_lbm,
|
||||
ble_log_prph_trans_t ***out_trans);
|
||||
BLE_LOG_STATIC void ble_log_lbm_release(ble_log_lbm_t *lbm);
|
||||
BLE_LOG_STATIC void ble_log_lbm_submit_trans(ble_log_prph_trans_t **trans);
|
||||
BLE_LOG_STATIC
|
||||
ble_log_prph_trans_t **ble_log_lbm_get_trans(ble_log_lbm_t *lbm, size_t log_len);
|
||||
BLE_LOG_STATIC bool ble_log_lbm_flush_all_trans(void);
|
||||
@@ -125,6 +126,23 @@ void ble_log_lbm_release(ble_log_lbm_t *lbm)
|
||||
}
|
||||
}
|
||||
|
||||
BLE_LOG_IRAM_ATTR BLE_LOG_STATIC
|
||||
void ble_log_lbm_submit_trans(ble_log_prph_trans_t **trans)
|
||||
{
|
||||
ble_log_prph_trans_t *submitted = *trans;
|
||||
BLE_LOG_ATOMIC_STORE_RELAXED(submitted->prph_owned, true);
|
||||
|
||||
ble_log_lbm_t *lbm = (ble_log_lbm_t *)submitted->owner;
|
||||
uint32_t inflight = __atomic_add_fetch(&lbm->trans_inflight, 1, __ATOMIC_RELAXED);
|
||||
uint32_t peak = __atomic_load_n(&lbm->trans_inflight_peak, __ATOMIC_RELAXED);
|
||||
while (inflight > peak &&
|
||||
!__atomic_compare_exchange_n(&lbm->trans_inflight_peak, &peak, inflight,
|
||||
false, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) {
|
||||
}
|
||||
|
||||
ble_log_rt_submit_trans(submitted);
|
||||
}
|
||||
|
||||
BLE_LOG_STATIC bool ble_log_lbm_flush_all_trans(void)
|
||||
{
|
||||
ble_log_lbm_t *lbm;
|
||||
@@ -138,9 +156,8 @@ BLE_LOG_STATIC bool ble_log_lbm_flush_all_trans(void)
|
||||
int trans_idx = lbm->trans_idx;
|
||||
for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) {
|
||||
trans = &(lbm->trans[trans_idx]);
|
||||
if (!__atomic_load_n(&(*trans)->prph_owned, __ATOMIC_ACQUIRE) &&
|
||||
(*trans)->pos) {
|
||||
ble_log_rt_queue_trans(trans);
|
||||
if (!BLE_LOG_ATOMIC_LOAD_ACQUIRE((*trans)->prph_owned) && (*trans)->pos) {
|
||||
ble_log_lbm_submit_trans(trans);
|
||||
}
|
||||
trans_idx = (trans_idx + 1) & (BLE_LOG_TRANS_BUF_CNT - 1);
|
||||
}
|
||||
@@ -153,7 +170,7 @@ BLE_LOG_STATIC bool ble_log_lbm_flush_all_trans(void)
|
||||
lbm = &(lbm_ctx->lbm_pool[i]);
|
||||
for (int j = 0; j < BLE_LOG_TRANS_BUF_CNT; j++) {
|
||||
trans = &(lbm->trans[j]);
|
||||
in_progress |= __atomic_load_n(&(*trans)->prph_owned, __ATOMIC_ACQUIRE);
|
||||
in_progress |= BLE_LOG_ATOMIC_LOAD_ACQUIRE((*trans)->prph_owned);
|
||||
}
|
||||
}
|
||||
if (in_progress) {
|
||||
@@ -230,7 +247,7 @@ void ble_log_lbm_write_trans(ble_log_prph_trans_t **trans, ble_log_src_t src_cod
|
||||
|
||||
/* Queue trans if full */
|
||||
if (BLE_LOG_TRANS_FREE_SPACE((*trans)) <= BLE_LOG_FRAME_OVERHEAD) {
|
||||
ble_log_rt_queue_trans(trans);
|
||||
ble_log_lbm_submit_trans(trans);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,7 +274,7 @@ void ble_log_lbm_stream_seal(ble_log_prph_trans_t **trans, ble_log_src_t src_cod
|
||||
|
||||
ble_log_stat_mgr_update(src_code, payload_len, false);
|
||||
|
||||
ble_log_rt_queue_trans(trans);
|
||||
ble_log_lbm_submit_trans(trans);
|
||||
}
|
||||
#endif /* BLE_LOG_UART_REDIR_ENABLED */
|
||||
|
||||
@@ -319,7 +336,7 @@ BLE_LOG_IRAM_ATTR void ble_log_lbm_recycle_trans(ble_log_prph_trans_t *trans)
|
||||
{
|
||||
ble_log_lbm_t *lbm = (ble_log_lbm_t *)trans->owner;
|
||||
__atomic_fetch_sub(&lbm->trans_inflight, 1, __ATOMIC_RELAXED);
|
||||
__atomic_store_n(&trans->prph_owned, false, __ATOMIC_RELEASE);
|
||||
BLE_LOG_ATOMIC_STORE_RELEASE(trans->prph_owned, false);
|
||||
}
|
||||
|
||||
bool ble_log_lbm_init(void)
|
||||
@@ -388,7 +405,6 @@ bool ble_log_lbm_init(void)
|
||||
}
|
||||
|
||||
/* Initialization done */
|
||||
lbm_ref_count = 0;
|
||||
lbm_inited = true;
|
||||
lbm_enabled = false;
|
||||
return true;
|
||||
@@ -448,7 +464,7 @@ ble_log_prph_trans_t **ble_log_lbm_get_trans(ble_log_lbm_t *lbm, size_t log_len)
|
||||
ble_log_prph_trans_t **trans;
|
||||
for (int i = 0; i < BLE_LOG_TRANS_BUF_CNT; i++) {
|
||||
trans = &(lbm->trans[lbm->trans_idx]);
|
||||
if (!__atomic_load_n(&(*trans)->prph_owned, __ATOMIC_ACQUIRE)) {
|
||||
if (!BLE_LOG_ATOMIC_LOAD_ACQUIRE((*trans)->prph_owned)) {
|
||||
/* Return if there's enough free space in current transport */
|
||||
if (BLE_LOG_TRANS_FREE_SPACE((*trans)) >= (log_len + BLE_LOG_FRAME_OVERHEAD)) {
|
||||
return trans;
|
||||
@@ -456,7 +472,7 @@ ble_log_prph_trans_t **ble_log_lbm_get_trans(ble_log_lbm_t *lbm, size_t log_len)
|
||||
|
||||
/* Queue transport if there's insufficient free space */
|
||||
if ((*trans)->pos) {
|
||||
ble_log_rt_queue_trans(trans);
|
||||
ble_log_lbm_submit_trans(trans);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -560,8 +576,8 @@ void ble_log_lbm_stream_flush(ble_log_lbm_t *lbm, ble_log_src_t src_code)
|
||||
int trans_idx = lbm->trans_idx;
|
||||
for (int i = 0; i < BLE_LOG_TRANS_BUF_CNT; i++) {
|
||||
ble_log_prph_trans_t **trans = &(lbm->trans[trans_idx]);
|
||||
if (!__atomic_load_n(&(*trans)->prph_owned, __ATOMIC_ACQUIRE) &&
|
||||
(*trans)->pos > BLE_LOG_FRAME_HEAD_LEN) {
|
||||
if (!BLE_LOG_ATOMIC_LOAD_ACQUIRE((*trans)->prph_owned) &&
|
||||
(*trans)->pos > BLE_LOG_FRAME_HEAD_LEN) {
|
||||
ble_log_lbm_stream_seal(trans, src_code);
|
||||
}
|
||||
trans_idx = (trans_idx + 1) & (BLE_LOG_TRANS_BUF_CNT - 1);
|
||||
@@ -575,8 +591,8 @@ BLE_LOG_STATIC void ble_log_emit_buf_util(ble_log_lbm_t *lbm, uint8_t lbm_id)
|
||||
.int_src_code = BLE_LOG_INT_SRC_BUF_UTIL,
|
||||
.lbm_id = lbm_id,
|
||||
.trans_cnt = BLE_LOG_TRANS_BUF_CNT,
|
||||
.inflight_peak = (uint8_t)__atomic_load_n(
|
||||
&lbm->trans_inflight_peak, __ATOMIC_RELAXED),
|
||||
.inflight_peak = (uint8_t)__atomic_load_n(&lbm->trans_inflight_peak,
|
||||
__ATOMIC_RELAXED),
|
||||
};
|
||||
ble_log_write_hex(BLE_LOG_SRC_INTERNAL,
|
||||
(const uint8_t *)&util, sizeof(ble_log_buf_util_t));
|
||||
|
||||
@@ -174,33 +174,21 @@ void ble_log_rt_deinit(void)
|
||||
}
|
||||
}
|
||||
|
||||
BLE_LOG_IRAM_ATTR void ble_log_rt_queue_trans(ble_log_prph_trans_t **trans)
|
||||
BLE_LOG_IRAM_ATTR void ble_log_rt_submit_trans(ble_log_prph_trans_t *trans)
|
||||
{
|
||||
__atomic_store_n(&(*trans)->prph_owned, true, __ATOMIC_RELAXED);
|
||||
|
||||
ble_log_lbm_t *lbm = (ble_log_lbm_t *)(*trans)->owner;
|
||||
uint32_t inflight = __atomic_add_fetch(&lbm->trans_inflight, 1, __ATOMIC_RELAXED);
|
||||
uint32_t peak = __atomic_load_n(&lbm->trans_inflight_peak, __ATOMIC_RELAXED);
|
||||
while (inflight > peak) {
|
||||
if (__atomic_compare_exchange_n(&lbm->trans_inflight_peak, &peak, inflight,
|
||||
true, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (BLE_LOG_IN_ISR()) {
|
||||
BaseType_t woken = pdFALSE;
|
||||
/* Queue depth == total transport buffer count; queue-full is impossible
|
||||
* for a valid transport, so the return value is not checked. */
|
||||
xQueueSendFromISR(rt_queue_handle, trans, &woken);
|
||||
xQueueSendFromISR(rt_queue_handle, &trans, &woken);
|
||||
portYIELD_FROM_ISR(woken);
|
||||
} else if (xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED) {
|
||||
/* Non-blocking send to avoid configASSERT when scheduler is suspended
|
||||
* (e.g., during light sleep transitions). Queue-full is impossible;
|
||||
* see comment above. */
|
||||
xQueueSend(rt_queue_handle, trans, 0);
|
||||
xQueueSend(rt_queue_handle, &trans, 0);
|
||||
} else {
|
||||
xQueueSend(rt_queue_handle, trans, portMAX_DELAY);
|
||||
xQueueSend(rt_queue_handle, &trans, portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
/* TYPEDEF */
|
||||
typedef struct {
|
||||
bool prph_owned;
|
||||
volatile uint32_t prph_owned;
|
||||
uint8_t *buf;
|
||||
uint16_t size;
|
||||
uint16_t pos;
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
#endif /* CONFIG_BLE_LOG_TS_ENABLED */
|
||||
|
||||
/* INTERFACE */
|
||||
bool ble_log_rt_init();
|
||||
bool ble_log_rt_init(void);
|
||||
void ble_log_rt_deinit(void);
|
||||
void ble_log_rt_queue_trans(ble_log_prph_trans_t **trans);
|
||||
void ble_log_rt_submit_trans(ble_log_prph_trans_t *trans);
|
||||
|
||||
#endif /* __BLE_LOG_RT_H__ */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -25,6 +25,11 @@
|
||||
#endif /* !UNIT_TEST */
|
||||
|
||||
/* MACRO */
|
||||
#define BLE_LOG_ATOMIC_LOAD_ACQUIRE(VAR) __atomic_load_n(&(VAR), __ATOMIC_ACQUIRE)
|
||||
#define BLE_LOG_ATOMIC_LOAD_RELAXED(VAR) __atomic_load_n(&(VAR), __ATOMIC_RELAXED)
|
||||
#define BLE_LOG_ATOMIC_STORE_RELEASE(VAR, VALUE) __atomic_store_n(&(VAR), (VALUE), __ATOMIC_RELEASE)
|
||||
#define BLE_LOG_ATOMIC_STORE_RELAXED(VAR, VALUE) __atomic_store_n(&(VAR), (VALUE), __ATOMIC_RELAXED)
|
||||
|
||||
/* Unit test */
|
||||
#ifndef UNIT_TEST
|
||||
|
||||
|
||||
Reference in New Issue
Block a user