mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
fix(bt/ble_log): use aligned counters in ble_log_stat_mgr_t
Replace embedded ble_log_enh_stat_t (packed wire struct) inside ble_log_stat_mgr_t with flat uint32_t counters. Natural 4-byte alignment ensures each load/store compiles to a single l32i/s32i on Xtensa/RISC-V, making individual field access atomic without locks. Build the packed wire format on the stack inside a critical section in ble_log_write_enh_stat() so the full snapshot is consistent.
This commit is contained in:
@@ -137,14 +137,14 @@ void ble_log_stat_mgr_update(ble_log_src_t src_code, uint32_t len, bool lost)
|
||||
/* Get statistic manager by source code */
|
||||
ble_log_stat_mgr_t *stat_mgr = stat_mgr_ctx[src_code];
|
||||
|
||||
/* Update statistics */
|
||||
/* Update aligned counters */
|
||||
uint32_t bytes_cnt = len + BLE_LOG_FRAME_OVERHEAD;
|
||||
if (lost) {
|
||||
stat_mgr->enh_stat.lost_frame_cnt++;
|
||||
stat_mgr->enh_stat.lost_bytes_cnt += bytes_cnt;
|
||||
stat_mgr->lost_frame_cnt++;
|
||||
stat_mgr->lost_bytes_cnt += bytes_cnt;
|
||||
} else {
|
||||
stat_mgr->enh_stat.written_frame_cnt++;
|
||||
stat_mgr->enh_stat.written_bytes_cnt += bytes_cnt;
|
||||
stat_mgr->written_frame_cnt++;
|
||||
stat_mgr->written_bytes_cnt += bytes_cnt;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,9 +212,6 @@ bool ble_log_lbm_init(void)
|
||||
goto exit;
|
||||
}
|
||||
BLE_LOG_MEMSET(stat_mgr_ctx[i], 0, sizeof(ble_log_stat_mgr_t));
|
||||
|
||||
stat_mgr_ctx[i]->enh_stat.int_src_code = BLE_LOG_INT_SRC_ENH_STAT;
|
||||
stat_mgr_ctx[i]->enh_stat.src_code = i;
|
||||
}
|
||||
|
||||
/* Initialization done */
|
||||
@@ -304,9 +301,23 @@ void ble_log_write_enh_stat(void)
|
||||
goto deref;
|
||||
}
|
||||
|
||||
/* Snapshot all sources under one critical section so the set of
|
||||
* counters is mutually consistent, then write outside the lock. */
|
||||
ble_log_enh_stat_t snapshots[BLE_LOG_SRC_MAX];
|
||||
for (int i = 0; i < BLE_LOG_SRC_MAX; i++) {
|
||||
ble_log_enh_stat_t *enh_stat = &(stat_mgr_ctx[i]->enh_stat);
|
||||
ble_log_write_hex(BLE_LOG_SRC_INTERNAL, (const uint8_t *)enh_stat, sizeof(ble_log_enh_stat_t));
|
||||
snapshots[i].int_src_code = BLE_LOG_INT_SRC_ENH_STAT;
|
||||
snapshots[i].src_code = i;
|
||||
}
|
||||
BLE_LOG_ENTER_CRITICAL();
|
||||
for (int i = 0; i < BLE_LOG_SRC_MAX; i++) {
|
||||
BLE_LOG_MEMCPY(&snapshots[i].written_frame_cnt,
|
||||
&stat_mgr_ctx[i]->written_frame_cnt,
|
||||
4 * sizeof(uint32_t));
|
||||
}
|
||||
BLE_LOG_EXIT_CRITICAL();
|
||||
|
||||
for (int i = 0; i < BLE_LOG_SRC_MAX; i++) {
|
||||
ble_log_write_hex(BLE_LOG_SRC_INTERNAL, (const uint8_t *)&snapshots[i], sizeof(ble_log_enh_stat_t));
|
||||
}
|
||||
|
||||
deref:
|
||||
@@ -389,9 +400,6 @@ void ble_log_flush(void)
|
||||
/* Reset statistics manager after all operations complete */
|
||||
for (int i = 0; i < BLE_LOG_SRC_MAX; i++) {
|
||||
BLE_LOG_MEMSET(stat_mgr_ctx[i], 0, sizeof(ble_log_stat_mgr_t));
|
||||
/* Reinitialize enhanced statistics fields */
|
||||
stat_mgr_ctx[i]->enh_stat.int_src_code = BLE_LOG_INT_SRC_ENH_STAT;
|
||||
stat_mgr_ctx[i]->enh_stat.src_code = i;
|
||||
}
|
||||
|
||||
/* Resume enable status */
|
||||
|
||||
@@ -138,7 +138,16 @@ typedef struct {
|
||||
/* -------------------------------------- */
|
||||
typedef struct {
|
||||
uint32_t frame_sn;
|
||||
ble_log_enh_stat_t enh_stat;
|
||||
/* Aligned live counters — updated by ble_log_stat_mgr_update(),
|
||||
* snapshot by ble_log_write_enh_stat(). Natural 4-byte alignment
|
||||
* ensures each load/store compiles to a single l32i/s32i on
|
||||
* Xtensa/RISC-V, so individual field access is atomic without locks.
|
||||
* The packed ble_log_enh_stat_t wire format is built on the stack
|
||||
* only when serializing to UART. */
|
||||
uint32_t written_frame_cnt;
|
||||
uint32_t lost_frame_cnt;
|
||||
uint32_t written_bytes_cnt;
|
||||
uint32_t lost_bytes_cnt;
|
||||
} ble_log_stat_mgr_t;
|
||||
|
||||
#define BLE_LOG_GET_FRAME_SN(VAR) __atomic_fetch_add(VAR, 1, __ATOMIC_RELAXED)
|
||||
|
||||
Reference in New Issue
Block a user