[esp32_ble] Optimize BLE event hot path performance (#14627)

This commit is contained in:
J. Nick Koston
2026-03-08 13:59:40 -10:00
committed by GitHub
parent d5dc4a39cb
commit e7730cff00
2 changed files with 15 additions and 13 deletions
+6 -12
View File
@@ -155,44 +155,38 @@ class BLEEvent {
void release() {
switch (this->type_) {
case GAP:
// GAP events don't have heap allocations
// GAP events never have heap allocations
break;
case GATTC:
// Param is now stored inline, only delete heap data if it was heap-allocated
if (!this->event_.gattc.is_inline && this->event_.gattc.data.heap_data != nullptr) {
delete[] this->event_.gattc.data.heap_data;
this->event_.gattc.data.heap_data = nullptr;
}
// Clear critical fields to prevent issues if type changes
this->event_.gattc.is_inline = false;
this->event_.gattc.data.heap_data = nullptr;
break;
case GATTS:
// Param is now stored inline, only delete heap data if it was heap-allocated
if (!this->event_.gatts.is_inline && this->event_.gatts.data.heap_data != nullptr) {
delete[] this->event_.gatts.data.heap_data;
this->event_.gatts.data.heap_data = nullptr;
}
// Clear critical fields to prevent issues if type changes
this->event_.gatts.is_inline = false;
this->event_.gatts.data.heap_data = nullptr;
break;
}
}
// Load new event data for reuse (replaces previous event data)
// Note: release() is NOT called here because EventPool::release() already
// calls event->release() before returning to the free list. Every event
// from allocate() is already in a clean state.
void load_gap_event(esp_gap_ble_cb_event_t e, esp_ble_gap_cb_param_t *p) {
this->release();
this->type_ = GAP;
this->init_gap_data_(e, p);
}
void load_gattc_event(esp_gattc_cb_event_t e, esp_gatt_if_t i, esp_ble_gattc_cb_param_t *p) {
this->release();
this->type_ = GATTC;
this->init_gattc_data_(e, i, p);
}
void load_gatts_event(esp_gatts_cb_event_t e, esp_gatt_if_t i, esp_ble_gatts_cb_param_t *p) {
this->release();
this->type_ = GATTS;
this->init_gatts_data_(e, i, p);
}
+9 -1
View File
@@ -104,7 +104,15 @@ template<class T, uint8_t SIZE> class LockFreeQueue {
}
}
uint16_t get_and_reset_dropped_count() { return dropped_count_.exchange(0, std::memory_order_relaxed); }
uint16_t get_and_reset_dropped_count() {
// Fast path: relaxed load is a single instruction on all platforms.
// The atomic exchange (especially for uint16_t on Xtensa) compiles to
// an expensive sub-word CAS retry loop (~25 instructions + memory barriers).
// Since drops are rare, avoid the exchange in the common case.
if (dropped_count_.load(std::memory_order_relaxed) == 0)
return 0;
return dropped_count_.exchange(0, std::memory_order_relaxed);
}
void increment_dropped_count() { dropped_count_.fetch_add(1, std::memory_order_relaxed); }