mirror of
https://github.com/esphome/esphome.git
synced 2025-10-04 02:52:22 +01:00
Merge branch 'guard_trq_allocation' into integration
This commit is contained in:
@@ -361,24 +361,30 @@ TransferRequest *USBClient::get_trq_() {
|
|||||||
uint16_t mask = this->trq_in_use_.load(std::memory_order_relaxed);
|
uint16_t mask = this->trq_in_use_.load(std::memory_order_relaxed);
|
||||||
|
|
||||||
// Find first available slot (bit = 0) and try to claim it atomically
|
// Find first available slot (bit = 0) and try to claim it atomically
|
||||||
for (size_t i = 0; i < MAX_REQUESTS; i++) {
|
// We use a while loop to allow retrying the same slot after CAS failure
|
||||||
if (!(mask & (1U << i))) {
|
size_t i = 0;
|
||||||
// Slot i appears available, try to claim it atomically
|
while (i < MAX_REQUESTS) {
|
||||||
uint16_t expected = mask;
|
if (mask & (1U << i)) {
|
||||||
uint16_t desired = mask | (1U << i); // Set bit i to mark as in-use
|
// Slot is in use, move to next slot
|
||||||
|
i++;
|
||||||
if (this->trq_in_use_.compare_exchange_weak(expected, desired, std::memory_order_acquire,
|
continue;
|
||||||
std::memory_order_relaxed)) {
|
|
||||||
// Successfully claimed slot i - prepare the TransferRequest
|
|
||||||
auto *trq = &this->requests_[i];
|
|
||||||
trq->transfer->context = trq;
|
|
||||||
trq->transfer->device_handle = this->device_handle_;
|
|
||||||
return trq;
|
|
||||||
}
|
|
||||||
// Another thread claimed this slot, retry with updated mask
|
|
||||||
mask = expected;
|
|
||||||
i--; // Retry the same index with new mask value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Slot i appears available, try to claim it atomically
|
||||||
|
uint16_t expected = mask;
|
||||||
|
uint16_t desired = mask | (1U << i); // Set bit i to mark as in-use
|
||||||
|
|
||||||
|
if (this->trq_in_use_.compare_exchange_weak(expected, desired, std::memory_order_acquire,
|
||||||
|
std::memory_order_relaxed)) {
|
||||||
|
// Successfully claimed slot i - prepare the TransferRequest
|
||||||
|
auto *trq = &this->requests_[i];
|
||||||
|
trq->transfer->context = trq;
|
||||||
|
trq->transfer->device_handle = this->device_handle_;
|
||||||
|
return trq;
|
||||||
|
}
|
||||||
|
// Another thread claimed this slot, retry with updated mask
|
||||||
|
// Don't increment i - retry the same slot with the updated mask
|
||||||
|
mask = expected;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGE(TAG, "Too many requests queued (all %d slots in use)", MAX_REQUESTS);
|
ESP_LOGE(TAG, "Too many requests queued (all %d slots in use)", MAX_REQUESTS);
|
||||||
|
Reference in New Issue
Block a user