-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcircbuf.c
62 lines (57 loc) · 2.07 KB
/
circbuf.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
#include "circbuf.h"
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <xmmintrin.h>
CircBuf *circ_buf_create(size_t len) {
void *mem = malloc(sizeof(CircBuf) + len);
if (!mem) return NULL;
CircBuf *self = mem;
assert(pthread_mutex_init(&self->lock, NULL) == 0);
self->data = (uint8_t*)mem + sizeof(CircBuf);
self->len = len;
self->rd = self->wr = 0;
return self;
}
void circ_buf_destroy(CircBuf *self) {
assert(pthread_mutex_destroy(&self->lock) == 0);
free(self);
}
void circ_buf_read(CircBuf *restrict self, uint8_t *restrict dst, size_t n) {
//printf("readable: %llu, attempt to read: %llu\n", (self->rd <= self->wr ? self->wr - self->rd : self->len - (self->rd - self->wr)), n);
assert(n <= self->len-1);
while (1) {
pthread_mutex_lock(&self->lock);
const size_t readable = self->rd <= self->wr ? self->wr - self->rd : self->len - (self->rd - self->wr);
if (readable >= n)
break;
pthread_mutex_unlock(&self->lock);
_mm_pause();
}
size_t n1 = n > self->len-self->rd ? self->len-self->rd : n;
size_t n2 = n - n1;
memcpy(dst, self->data+self->rd, n1);
self->rd = (self->rd + n1) % self->len;
memcpy(dst+n1, self->data+self->rd, n2);
self->rd = (self->rd + n2) % self->len;
pthread_mutex_unlock(&self->lock);
}
void circ_buf_write(CircBuf *restrict self, const uint8_t *restrict src, size_t n) {
//printf("writeable: %llu, attempt to write: %llu\n", (self->rd <= self->wr ? self->len - (self->wr - self->rd) : self->rd - self->wr)-1, n);
assert(n <= self->len-1);
while (1) {
pthread_mutex_lock(&self->lock);
const size_t writeable = (self->rd <= self->wr ? self->len - (self->wr - self->rd) : self->rd - self->wr) - 1;
if (writeable >= n)
break;
pthread_mutex_unlock(&self->lock);
_mm_pause();
}
size_t n1 = n > self->len-self->wr ? self->len-self->wr : n;
size_t n2 = n - n1;
memcpy(self->data+self->wr, src, n1);
self->wr = (self->wr + n1) % self->len;
memcpy(self->data+self->wr, src+n1, n2);
self->wr = (self->wr + n2) % self->len;
pthread_mutex_unlock(&self->lock);
}