fix(nimble): Fixes for AI reported issues

This commit is contained in:
Rahul Tank
2026-07-07 16:28:48 +05:30
parent 581bc0c5ce
commit a3aeccbed4
7 changed files with 112 additions and 129 deletions
@@ -17,6 +17,8 @@ void *nimble_mem_malloc(size_t size);
void *nimble_mem_calloc(size_t n, size_t size);
void *nimble_mem_realloc(void *ptr, size_t size);
void nimble_mem_free(void *ptr);
#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
@@ -89,17 +91,6 @@ void nimble_mem_dbg_set_section_end(uint8_t index);
*/
uint32_t nimble_mem_dbg_get_max_size_section(uint8_t index);
/**
* @brief Reallocate memory with debug tracking
*
* @param ptr Pointer to memory to reallocate
* @param new_size New size of allocation
* @param func Function name where realloc occurred
* @param line Line number where realloc occurred
* @return Pointer to reallocated memory
*/
void *nimble_mem_dbg_realloc(void *ptr, size_t new_size, const char *func, int line);
#endif // CONFIG_BT_NIMBLE_MEM_DEBUG
@@ -127,11 +118,17 @@ void *nimble_mem_dbg_realloc(void *ptr, size_t new_size, const char *func, int l
#define nimble_platform_mem_realloc(ptr, new_size) \
({ \
void *p; \
do { \
p = nimble_mem_dbg_realloc(ptr, new_size, __func__, __LINE__); \
} while (0); \
p; \
void *_old = (void *)(ptr); \
size_t _nsz = (size_t)(new_size); \
void *_new = nimble_mem_realloc(_old, _nsz); \
if (_new == NULL && _nsz > 0) { \
/* realloc failed: original block still alive, keep its debug record */ \
} else { \
/* success or free (new_size==0): clean old, record new */ \
if (_old) nimble_mem_dbg_clean(_old, __func__, __LINE__); \
if (_new) nimble_mem_dbg_record(_new, _nsz, __func__, __LINE__); \
} \
_new; \
})
#define nimble_platform_mem_free(ptr) \
@@ -145,7 +142,7 @@ do { \
#define nimble_platform_mem_malloc nimble_mem_malloc
#define nimble_platform_mem_calloc nimble_mem_calloc
#define nimble_platform_mem_realloc realloc
#define nimble_platform_mem_realloc nimble_mem_realloc
#define nimble_platform_mem_free nimble_mem_free
#endif // CONFIG_BT_NIMBLE_MEM_DEBUG
@@ -79,6 +79,7 @@ void nimble_mem_dbg_record(void *p, int size, const char *func, int line)
if (i >= NIMBLE_MEM_DBG_INFO_MAX) {
ESP_LOGE("BT_NIMBLE_MEM", "%s full %s %d !!\n", __func__, func, line);
return;
}
nimble_mem_dbg_current_size += size;
@@ -190,66 +191,6 @@ uint32_t nimble_mem_dbg_get_max_size_section(uint8_t index)
return nimble_mem_dbg_max_size_section[index].max_size;
}
void *nimble_mem_dbg_realloc(void *ptr, size_t new_size, const char *func, int line)
{
size_t old_size = 0;
int i;
void *new_ptr = realloc(ptr, new_size);
if (new_ptr == NULL && new_size > 0) {
// realloc failed, keep old ptr record
return NULL;
}
// Find and clean old record if ptr is not NULL
if (ptr != NULL) {
for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) {
if (nimble_mem_dbg_info[i].p == ptr) {
old_size = nimble_mem_dbg_info[i].size;
nimble_mem_dbg_current_size -= old_size;
nimble_mem_dbg_info[i].p = NULL;
nimble_mem_dbg_info[i].size = 0;
nimble_mem_dbg_info[i].func = NULL;
nimble_mem_dbg_info[i].line = 0;
nimble_mem_dbg_count--;
break;
}
}
}
// Record the new allocation if new_size > 0
if (new_ptr != NULL && new_size > 0) {
for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) {
if (nimble_mem_dbg_info[i].p == NULL) {
nimble_mem_dbg_info[i].p = new_ptr;
nimble_mem_dbg_info[i].size = new_size;
nimble_mem_dbg_info[i].func = func;
nimble_mem_dbg_info[i].line = line;
nimble_mem_dbg_count++;
break;
}
}
if (i >= NIMBLE_MEM_DBG_INFO_MAX) {
ESP_LOGE("BT_NIMBLE_MEM", "%s full %s %d !!\n", __func__, func, line);
}
nimble_mem_dbg_current_size += new_size;
if (nimble_mem_dbg_max_size < nimble_mem_dbg_current_size) {
nimble_mem_dbg_max_size = nimble_mem_dbg_current_size;
}
for (i = 0; i < NIMBLE_MEM_DBG_MAX_SECTION_NUM; i++) {
if (nimble_mem_dbg_max_size_section[i].used &&
nimble_mem_dbg_max_size_section[i].max_size < nimble_mem_dbg_current_size) {
nimble_mem_dbg_max_size_section[i].max_size = nimble_mem_dbg_current_size;
}
}
}
return new_ptr;
}
#endif // CONFIG_BT_NIMBLE_MEM_DEBUG
#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE
@@ -306,6 +247,44 @@ void *nimble_mem_calloc(size_t n, size_t size)
return mem;
}
#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE
IRAM_ATTR
#endif
void *nimble_mem_realloc(void *ptr, size_t size)
{
void *mem = NULL;
#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
size_t old_size = 0;
if (ptr) {
old_size = heap_caps_get_allocated_size(ptr);
}
#endif
#ifdef CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL
mem = heap_caps_realloc(ptr, size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL
mem = heap_caps_realloc(ptr, size, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT);
#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_IRAM_8BIT
mem = heap_caps_realloc_prefer(ptr, size, 2,
MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT,
MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
#else
mem = realloc(ptr, size);
#endif
#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
if (mem) {
size_t new_size = heap_caps_get_allocated_size(mem);
host_mem_used_size = host_mem_used_size - old_size + new_size;
} else if (ptr && size == 0) {
host_mem_used_size -= old_size;
}
#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED
return mem;
}
#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE
IRAM_ATTR
#endif
@@ -247,28 +247,6 @@ npl_eventq_queued_get_isr(struct ble_npl_event_freertos *event)
return queued;
}
static void IRAM_ATTR
npl_eventq_queued_set_isr(struct ble_npl_event_freertos *event, bool queued)
{
portENTER_CRITICAL_ISR(&ble_port_mutex);
event->queued = queued;
portEXIT_CRITICAL_ISR(&ble_port_mutex);
}
static bool IRAM_ATTR
npl_eventq_queued_claim_isr(struct ble_npl_event_freertos *event)
{
bool already;
portENTER_CRITICAL_ISR(&ble_port_mutex);
already = event->queued;
if (!already) {
event->queued = true;
}
portEXIT_CRITICAL_ISR(&ble_port_mutex);
return already;
}
static void IRAM_ATTR
npl_eventq_queued_set_task(struct ble_npl_event_freertos *event, bool queued)
{
@@ -329,18 +307,22 @@ IRAM_ATTR npl_freertos_eventq_get(struct ble_npl_eventq *evq, ble_npl_time_t tmo
if (in_isr()) {
BLE_LL_ASSERT(tmo == 0);
woken = pdFALSE;
portENTER_CRITICAL_ISR(&ble_port_mutex);
ret = xQueueReceiveFromISR(eventq->q, &ev, &woken);
if( woken == pdTRUE ) {
if (ret == pdPASS && ev != NULL) {
struct ble_npl_event_freertos *event = (struct ble_npl_event_freertos *)ev->event;
if (event) {
event->queued = false;
}
}
portEXIT_CRITICAL_ISR(&ble_port_mutex);
if (woken == pdTRUE) {
portYIELD_FROM_ISR();
}
BLE_LL_ASSERT(ret == pdPASS || ret == errQUEUE_EMPTY);
if (ev) {
struct ble_npl_event_freertos *event = (struct ble_npl_event_freertos *)ev->event;
if (event) {
npl_eventq_queued_set_isr(event, false);
}
}
} else if (tmo == 0) {
bool locked = npl_eventq_lock();
@@ -407,16 +389,24 @@ IRAM_ATTR npl_freertos_eventq_put(struct ble_npl_eventq *evq, struct ble_npl_eve
struct ble_npl_event_freertos *event = (struct ble_npl_event_freertos *)ev->event;
if (in_isr()) {
if (npl_eventq_queued_claim_isr(event)) {
woken = pdFALSE;
portENTER_CRITICAL_ISR(&ble_port_mutex);
if (event->queued) {
portEXIT_CRITICAL_ISR(&ble_port_mutex);
return;
}
event->queued = true;
ret = xQueueSendToBackFromISR(eventq->q, &ev, &woken);
if (ret != pdPASS) {
npl_eventq_queued_set_isr(event, false);
event->queued = false;
portEXIT_CRITICAL_ISR(&ble_port_mutex);
return;
}
if( woken == pdTRUE ) {
portEXIT_CRITICAL_ISR(&ble_port_mutex);
if (woken == pdTRUE) {
portYIELD_FROM_ISR();
}
return;
@@ -446,16 +436,24 @@ IRAM_ATTR npl_freertos_eventq_put_to_front(struct ble_npl_eventq *evq, struct bl
struct ble_npl_event_freertos *event = (struct ble_npl_event_freertos *)ev->event;
if (in_isr()) {
if (npl_eventq_queued_claim_isr(event)) {
woken = pdFALSE;
portENTER_CRITICAL_ISR(&ble_port_mutex);
if (event->queued) {
portEXIT_CRITICAL_ISR(&ble_port_mutex);
return;
}
event->queued = true;
ret = xQueueSendToFrontFromISR(eventq->q, &ev, &woken);
if (ret != pdPASS) {
npl_eventq_queued_set_isr(event, false);
event->queued = false;
portEXIT_CRITICAL_ISR(&ble_port_mutex);
return;
}
if( woken == pdTRUE ) {
portEXIT_CRITICAL_ISR(&ble_port_mutex);
if (woken == pdTRUE) {
portYIELD_FROM_ISR();
}
return;
@@ -1059,9 +1057,19 @@ IRAM_ATTR npl_freertos_callout_stop(struct ble_npl_callout *co)
}
#if BLE_NPL_USE_ESP_TIMER
esp_timer_stop(callout->handle);
if (!in_isr()) {
esp_timer_stop(callout->handle);
}
#else
xTimerStop(callout->handle, portMAX_DELAY);
if (in_isr()) {
BaseType_t woken = pdFALSE;
xTimerStopFromISR(callout->handle, &woken);
if (woken == pdTRUE) {
portYIELD_FROM_ISR();
}
} else {
xTimerStop(callout->handle, portMAX_DELAY);
}
#endif
if (callout->evq) {