diff --git a/libs/runtime/ebpf_ring_buffer.c b/libs/runtime/ebpf_ring_buffer.c index a6cfe7bb62..0994f51ea9 100644 --- a/libs/runtime/ebpf_ring_buffer.c +++ b/libs/runtime/ebpf_ring_buffer.c @@ -9,6 +9,7 @@ typedef struct _ebpf_ring_buffer { int64_t length; + int64_t mask; volatile int64_t consumer_offset; volatile int64_t producer_offset; uint8_t* shared_buffer; @@ -33,6 +34,7 @@ ebpf_ring_buffer_create(_Outptr_ ebpf_ring_buffer_t** ring, size_t capacity) } local_ring_buffer->length = capacity; + local_ring_buffer->mask = capacity - 1; local_ring_buffer->ring_descriptor = ebpf_allocate_ring_buffer_memory(capacity); if (!local_ring_buffer->ring_descriptor) { @@ -106,7 +108,7 @@ ebpf_ring_buffer_return(_Inout_ ebpf_ring_buffer_t* ring, size_t length) } ebpf_ring_buffer_record_t* record = - (ebpf_ring_buffer_record_t*)(ring->shared_buffer + consumer_offset % ring->length); + (ebpf_ring_buffer_record_t*)(ring->shared_buffer + (consumer_offset & ring->mask)); long size = ReadAcquire(&record->size); @@ -152,7 +154,7 @@ ebpf_ring_buffer_reserve( int64_t producer_offset = ReadAcquire64(&ring->producer_offset); // Record points to the next record to allocate. ebpf_ring_buffer_record_t* record = - (ebpf_ring_buffer_record_t*)(ring->shared_buffer + producer_offset % ring->length); + (ebpf_ring_buffer_record_t*)(ring->shared_buffer + (producer_offset & ring->mask)); int64_t remaining_space = ring->length - (producer_offset - ReadAcquire64(&ring->consumer_offset)); long effective_length = (long)length + 4; @@ -172,7 +174,7 @@ ebpf_ring_buffer_reserve( continue; } - if (InterlockedCompareExchange(&record->size, EBPF_RING_BUFFER_RECORD_FLAG_LOCKED, 0) != 0) { + if (InterlockedBitTestAndSetAcquire(&record->size, 31) != 0) { continue; } diff --git a/libs/runtime/ebpf_ring_buffer.h b/libs/runtime/ebpf_ring_buffer.h index 7d19fd3b82..dab3564157 100644 --- a/libs/runtime/ebpf_ring_buffer.h +++ b/libs/runtime/ebpf_ring_buffer.h @@ -38,6 +38,7 @@ ebpf_ring_buffer_destroy(_Frees_ptr_opt_ ebpf_ring_buffer_t* ring_buffer); * @retval EBPF_SUCCESS Successfully wrote record ring buffer. * @retval EBPF_OUT_OF_SPACE Unable to output to ring buffer due to inadequate space. */ +EBPF_INLINE_HINT _Must_inspect_result_ ebpf_result_t ebpf_ring_buffer_output(_Inout_ ebpf_ring_buffer_t* ring_buffer, _In_reads_bytes_(length) uint8_t* data, size_t length);