-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Timofey Titovets <[email protected]>
- Loading branch information
1 parent
80d185c
commit bc24e35
Showing
6 changed files
with
162 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#include <string.h> | ||
#include <stdint.h> | ||
#include <stddef.h> | ||
#include <stdatomic.h> | ||
#include "ringbuf.h" | ||
|
||
// Simple Single Producer Single Consumer Ring Buffer | ||
|
||
void ring_buffer_init(struct ring_buf *rb) | ||
{ | ||
atomic_store(&rb->head, 0); | ||
atomic_store(&rb->tail, 0); | ||
atomic_store(&rb->size, 0); | ||
} | ||
|
||
int ring_buffer_available_to_read(const struct ring_buf *rb) | ||
{ | ||
return atomic_load(&rb->size); | ||
} | ||
|
||
int ring_buffer_available_to_write(const struct ring_buf *rb) | ||
{ | ||
return RING_BUFFER_SIZE - atomic_load(&rb->size); | ||
} | ||
|
||
int ring_buffer_write(struct ring_buf *rb, const uint8_t *data, int length) | ||
{ | ||
int available = ring_buffer_available_to_write(rb); | ||
int to_write = (length < available) ? length : available; | ||
|
||
int head = atomic_load_explicit(&rb->head, memory_order_acquire); | ||
int first_chunk = RING_BUFFER_SIZE - head; | ||
if (first_chunk > to_write) { | ||
first_chunk = to_write; | ||
} | ||
memcpy(&rb->buffer[head], data, first_chunk); | ||
head = (head + first_chunk) % RING_BUFFER_SIZE; | ||
atomic_store_explicit(&rb->head, head, memory_order_release); | ||
atomic_fetch_add(&rb->size, first_chunk); | ||
|
||
int second_chunk = to_write - first_chunk; | ||
if (second_chunk > 0) { | ||
memcpy(&rb->buffer[0], data + first_chunk, second_chunk); | ||
} | ||
head = (head + second_chunk) % RING_BUFFER_SIZE; | ||
atomic_store_explicit(&rb->head, head, memory_order_release); | ||
atomic_fetch_add(&rb->size, second_chunk); | ||
|
||
return to_write; | ||
} | ||
|
||
int ring_buffer_read(struct ring_buf *rb, uint8_t *data, int length) | ||
{ | ||
int available = ring_buffer_available_to_read(rb); | ||
int to_read = (length < available) ? length : available; | ||
|
||
int tail = atomic_load_explicit(&rb->tail, memory_order_acquire); | ||
int first_chunk = RING_BUFFER_SIZE - tail; | ||
if (first_chunk > to_read) { | ||
first_chunk = to_read; | ||
} | ||
memcpy(data, &rb->buffer[tail], first_chunk); | ||
tail = (tail + first_chunk) % RING_BUFFER_SIZE; | ||
atomic_store_explicit(&rb->tail, tail, memory_order_release); | ||
atomic_fetch_sub(&rb->size, first_chunk); | ||
|
||
int second_chunk = to_read - first_chunk; | ||
if (second_chunk > 0) { | ||
memcpy(data + first_chunk, &rb->buffer[0], second_chunk); | ||
tail = second_chunk % RING_BUFFER_SIZE; | ||
} | ||
atomic_store_explicit(&rb->tail, tail, memory_order_release); | ||
atomic_fetch_sub(&rb->size, second_chunk); | ||
|
||
return to_read; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#include <stdint.h> | ||
|
||
#define RING_BUFFER_SIZE 8192 | ||
struct ring_buf | ||
{ | ||
uint8_t buffer[RING_BUFFER_SIZE]; | ||
_Atomic int head; | ||
_Atomic int tail; | ||
_Atomic int size; | ||
}; | ||
|
||
void ring_buffer_init(struct ring_buf *rb); | ||
int ring_buffer_available_to_read(const struct ring_buf *rb); | ||
int ring_buffer_available_to_write(const struct ring_buf *rb); | ||
int ring_buffer_write(struct ring_buf *rb, const uint8_t *data, int length); | ||
int ring_buffer_read(struct ring_buf *rb, uint8_t *data, int length); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters