mirror of
https://github.com/esphome/esphome.git
synced 2026-09-02 02:56:01 +00:00
[esp32_ble] Optimize BLE event hot path performance (#14627)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user