Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 80 lines (71 sloc) 2.323 kB
3f048a8 @nettoyeurny .
nettoyeurny authored
1 //
2 // ringbuffer.c
3 // libpd
4 //
5 // Copyright (c) 2011 Peter Brinkmann (peter.brinkmann@gmail.com)
6 //
7 // For information on usage and redistribution, and for a DISCLAIMER OF ALL
8 // WARRANTIES, see the file, "LICENSE.txt," in this distribution.
9 //
10
c2f38a5 @nettoyeurny new ring buffer
nettoyeurny authored
11 #include <stdlib.h>
12 #include <string.h>
13 #include <libkern/OSAtomic.h>
14
15 #include "ringbuffer.h"
16
17 ring_buffer *rb_create(size_t size) {
18 ring_buffer *buffer = malloc(sizeof(ring_buffer));
19 if (!buffer) return NULL;
20 buffer->buf_ptr = malloc(size);
21 if (!buffer->buf_ptr) {
22 free(buffer);
23 return NULL;
24 }
25 buffer->size = size;
26 buffer->write_idx = 0;
27 buffer->read_idx = 0;
28 return buffer;
29 }
30
31 void rb_free(ring_buffer *buffer) {
32 free(buffer->buf_ptr);
33 free(buffer);
34 }
35
36 size_t rb_available_to_write(ring_buffer *buffer) {
3f048a8 @nettoyeurny .
nettoyeurny authored
37 // Note: The largest possible result is buffer->size - 1 because
38 // we adopt the convention that read_idx == write_idx means that the
39 // buffer is empty.
0f3ae54 @nettoyeurny .
nettoyeurny authored
40 return buffer
41 ? (buffer->size + buffer->read_idx - buffer->write_idx - 1) % buffer->size
42 : 0;
c2f38a5 @nettoyeurny new ring buffer
nettoyeurny authored
43 }
44
45 size_t rb_available_to_read(ring_buffer *buffer) {
0f3ae54 @nettoyeurny .
nettoyeurny authored
46 return buffer
47 ? (buffer->size + buffer->write_idx - buffer->read_idx) % buffer->size
48 : 0;
c2f38a5 @nettoyeurny new ring buffer
nettoyeurny authored
49 }
50
f8e4287 @nettoyeurny replacing void* by char*
nettoyeurny authored
51 int rb_write_to_buffer(ring_buffer *buffer, const char *src, size_t len) {
c2f38a5 @nettoyeurny new ring buffer
nettoyeurny authored
52 if (len > rb_available_to_write(buffer)) return -1;
53 size_t write_idx = buffer->write_idx;
54 if (write_idx + len <= buffer->size) {
55 memcpy(buffer->buf_ptr + write_idx, src, len);
56 } else {
57 size_t d = buffer->size - write_idx;
58 memcpy(buffer->buf_ptr + write_idx, src, d);
59 memcpy(buffer->buf_ptr, src + d, len - d);
60 }
61 OSMemoryBarrier();
62 buffer->write_idx = (write_idx + len) % buffer->size;
63 return 0;
64 }
65
f8e4287 @nettoyeurny replacing void* by char*
nettoyeurny authored
66 int rb_read_from_buffer(ring_buffer *buffer, char *dest, size_t len) {
c2f38a5 @nettoyeurny new ring buffer
nettoyeurny authored
67 if (len > rb_available_to_read(buffer)) return -1;
68 OSMemoryBarrier();
69 size_t read_idx = buffer->read_idx;
70 if (read_idx + len <= buffer->size) {
71 memcpy(dest, buffer->buf_ptr + read_idx, len);
72 } else {
73 size_t d = buffer->size - read_idx;
74 memcpy(dest, buffer->buf_ptr + read_idx, d);
75 memcpy(dest + d, buffer->buf_ptr, len - d);
76 }
77 buffer->read_idx = (read_idx + len) % buffer->size;
78 return 0;
79 }
Something went wrong with that request. Please try again.