-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathringbuffer_ptr.c
82 lines (70 loc) · 1.9 KB
/
ringbuffer_ptr.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
* Implementation of ringbuffer_ptr module.
* Adapted from ringbuffer by Javier Garcia Nieto <[email protected]>
*
* The ring buffer data structure allows lock-free concurrent
* access by one reader and one writer.
*
* Author: Philip Levis <[email protected]>
* Julie Zelenski <[email protected]>
*/
#include "ringbuffer_ptr.h"
#include "assert.h"
#include "malloc.h"
#include <stdint.h>
#define LENGTH 512
struct ringbuffer_ptr {
uintptr_t entries[LENGTH];
int head, tail;
};
/*
* Added by Javier Garcia Nieto <[email protected]>
*/
void rb_ptr_clear_free(rb_ptr_t *rb) {
while (!rb_ptr_empty(rb)) {
uintptr_t elem;
rb_ptr_dequeue(rb, &elem);
free((void *)elem);
}
}
// Below is the original code from ringbuffer.c, replacing int with uintptr_t
rb_ptr_t *rb_ptr_new(void) {
rb_ptr_t *rb = malloc(sizeof(struct ringbuffer_ptr));
assert(rb != NULL);
rb->head = rb->tail = 0;
return rb;
}
bool rb_ptr_empty(rb_ptr_t *rb) {
assert(rb != NULL);
return rb->head == rb->tail;
}
bool rb_ptr_full(rb_ptr_t *rb) {
assert(rb != NULL);
return (rb->tail + 1) % LENGTH == rb->head;
}
/*
* Note: enqueue is called by writer. enqueue advances rb->tail,
* no changes to rb->head. This design allows safe concurrent access.
*/
bool rb_ptr_enqueue(rb_ptr_t *rb, uintptr_t elem) {
assert(rb != NULL);
if (rb_ptr_full(rb)) {
return false;
}
rb->entries[rb->tail] = elem;
rb->tail = (rb->tail + 1) % LENGTH;
return true;
}
/*
* Note: dequeue is called by reader. dequeue advances rb->head,
* no changes to rb->tail. This design allows safe concurrent access.
*/
bool rb_ptr_dequeue(rb_ptr_t *rb, uintptr_t *p_elem) {
assert(rb != NULL && p_elem != NULL);
if (rb_ptr_empty(rb)) {
return false;
}
*p_elem = rb->entries[rb->head];
rb->head = (rb->head + 1) % LENGTH;
return true;
}