|
|
@@ -35,22 +35,27 @@ |
|
|
|
jack_ringbuffer_t * |
|
|
|
jack_ringbuffer_create (size_t sz) |
|
|
|
{ |
|
|
|
int power_of_two; |
|
|
|
jack_ringbuffer_t *rb; |
|
|
|
|
|
|
|
rb = malloc (sizeof (jack_ringbuffer_t)); |
|
|
|
|
|
|
|
for (power_of_two = 1; 1 << power_of_two < sz; power_of_two++); |
|
|
|
|
|
|
|
rb->size = 1 << power_of_two; |
|
|
|
rb->size_mask = rb->size; |
|
|
|
rb->size_mask -= 1; |
|
|
|
rb->write_ptr = 0; |
|
|
|
rb->read_ptr = 0; |
|
|
|
rb->buf = malloc (rb->size); |
|
|
|
rb->mlocked = 0; |
|
|
|
|
|
|
|
return rb; |
|
|
|
int power_of_two; |
|
|
|
jack_ringbuffer_t *rb; |
|
|
|
|
|
|
|
if ((rb = malloc (sizeof (jack_ringbuffer_t))) == NULL) { |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
for (power_of_two = 1; 1 << power_of_two < sz; power_of_two++); |
|
|
|
|
|
|
|
rb->size = 1 << power_of_two; |
|
|
|
rb->size_mask = rb->size; |
|
|
|
rb->size_mask -= 1; |
|
|
|
rb->write_ptr = 0; |
|
|
|
rb->read_ptr = 0; |
|
|
|
if ((rb->buf = malloc (rb->size)) == NULL) { |
|
|
|
free (rb); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
rb->mlocked = 0; |
|
|
|
|
|
|
|
return rb; |
|
|
|
} |
|
|
|
|
|
|
|
/* Free all data associated with the ringbuffer `rb'. */ |
|
|
@@ -59,12 +64,12 @@ void |
|
|
|
jack_ringbuffer_free (jack_ringbuffer_t * rb) |
|
|
|
{ |
|
|
|
#ifdef USE_MLOCK |
|
|
|
if (rb->mlocked) { |
|
|
|
munlock (rb->buf, rb->size); |
|
|
|
} |
|
|
|
if (rb->mlocked) { |
|
|
|
munlock (rb->buf, rb->size); |
|
|
|
} |
|
|
|
#endif /* USE_MLOCK */ |
|
|
|
free (rb->buf); |
|
|
|
free (rb); |
|
|
|
free (rb->buf); |
|
|
|
free (rb); |
|
|
|
} |
|
|
|
|
|
|
|
/* Lock the data block of `rb' using the system call 'mlock'. */ |
|
|
@@ -73,12 +78,12 @@ int |
|
|
|
jack_ringbuffer_mlock (jack_ringbuffer_t * rb) |
|
|
|
{ |
|
|
|
#ifdef USE_MLOCK |
|
|
|
if (mlock (rb->buf, rb->size)) { |
|
|
|
return -1; |
|
|
|
} |
|
|
|
if (mlock (rb->buf, rb->size)) { |
|
|
|
return -1; |
|
|
|
} |
|
|
|
#endif /* USE_MLOCK */ |
|
|
|
rb->mlocked = 1; |
|
|
|
return 0; |
|
|
|
rb->mlocked = 1; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
/* Reset the read and write pointers to zero. This is not thread |
|
|
@@ -87,8 +92,8 @@ jack_ringbuffer_mlock (jack_ringbuffer_t * rb) |
|
|
|
void |
|
|
|
jack_ringbuffer_reset (jack_ringbuffer_t * rb) |
|
|
|
{ |
|
|
|
rb->read_ptr = 0; |
|
|
|
rb->write_ptr = 0; |
|
|
|
rb->read_ptr = 0; |
|
|
|
rb->write_ptr = 0; |
|
|
|
} |
|
|
|
|
|
|
|
/* Return the number of bytes available for reading. This is the |
|
|
@@ -98,16 +103,16 @@ jack_ringbuffer_reset (jack_ringbuffer_t * rb) |
|
|
|
size_t |
|
|
|
jack_ringbuffer_read_space (const jack_ringbuffer_t * rb) |
|
|
|
{ |
|
|
|
size_t w, r; |
|
|
|
|
|
|
|
w = rb->write_ptr; |
|
|
|
r = rb->read_ptr; |
|
|
|
|
|
|
|
if (w > r) { |
|
|
|
return w - r; |
|
|
|
} else { |
|
|
|
return (w - r + rb->size) & rb->size_mask; |
|
|
|
} |
|
|
|
size_t w, r; |
|
|
|
|
|
|
|
w = rb->write_ptr; |
|
|
|
r = rb->read_ptr; |
|
|
|
|
|
|
|
if (w > r) { |
|
|
|
return w - r; |
|
|
|
} else { |
|
|
|
return (w - r + rb->size) & rb->size_mask; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* Return the number of bytes available for writing. This is the |
|
|
@@ -117,18 +122,18 @@ jack_ringbuffer_read_space (const jack_ringbuffer_t * rb) |
|
|
|
size_t |
|
|
|
jack_ringbuffer_write_space (const jack_ringbuffer_t * rb) |
|
|
|
{ |
|
|
|
size_t w, r; |
|
|
|
|
|
|
|
w = rb->write_ptr; |
|
|
|
r = rb->read_ptr; |
|
|
|
|
|
|
|
if (w > r) { |
|
|
|
return ((r - w + rb->size) & rb->size_mask) - 1; |
|
|
|
} else if (w < r) { |
|
|
|
return (r - w) - 1; |
|
|
|
} else { |
|
|
|
return rb->size - 1; |
|
|
|
} |
|
|
|
size_t w, r; |
|
|
|
|
|
|
|
w = rb->write_ptr; |
|
|
|
r = rb->read_ptr; |
|
|
|
|
|
|
|
if (w > r) { |
|
|
|
return ((r - w + rb->size) & rb->size_mask) - 1; |
|
|
|
} else if (w < r) { |
|
|
|
return (r - w) - 1; |
|
|
|
} else { |
|
|
|
return rb->size - 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* The copying data reader. Copy at most `cnt' bytes from `rb' to |
|
|
@@ -137,77 +142,77 @@ jack_ringbuffer_write_space (const jack_ringbuffer_t * rb) |
|
|
|
size_t |
|
|
|
jack_ringbuffer_read (jack_ringbuffer_t * rb, char *dest, size_t cnt) |
|
|
|
{ |
|
|
|
size_t free_cnt; |
|
|
|
size_t cnt2; |
|
|
|
size_t to_read; |
|
|
|
size_t n1, n2; |
|
|
|
size_t free_cnt; |
|
|
|
size_t cnt2; |
|
|
|
size_t to_read; |
|
|
|
size_t n1, n2; |
|
|
|
|
|
|
|
if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
to_read = cnt > free_cnt ? free_cnt : cnt; |
|
|
|
to_read = cnt > free_cnt ? free_cnt : cnt; |
|
|
|
|
|
|
|
cnt2 = rb->read_ptr + to_read; |
|
|
|
cnt2 = rb->read_ptr + to_read; |
|
|
|
|
|
|
|
if (cnt2 > rb->size) { |
|
|
|
n1 = rb->size - rb->read_ptr; |
|
|
|
n2 = cnt2 & rb->size_mask; |
|
|
|
} else { |
|
|
|
n1 = to_read; |
|
|
|
n2 = 0; |
|
|
|
} |
|
|
|
if (cnt2 > rb->size) { |
|
|
|
n1 = rb->size - rb->read_ptr; |
|
|
|
n2 = cnt2 & rb->size_mask; |
|
|
|
} else { |
|
|
|
n1 = to_read; |
|
|
|
n2 = 0; |
|
|
|
} |
|
|
|
|
|
|
|
memcpy (dest, &(rb->buf[rb->read_ptr]), n1); |
|
|
|
rb->read_ptr = (rb->read_ptr + n1) & rb->size_mask; |
|
|
|
memcpy (dest, &(rb->buf[rb->read_ptr]), n1); |
|
|
|
rb->read_ptr = (rb->read_ptr + n1) & rb->size_mask; |
|
|
|
|
|
|
|
if (n2) { |
|
|
|
memcpy (dest + n1, &(rb->buf[rb->read_ptr]), n2); |
|
|
|
rb->read_ptr = (rb->read_ptr + n2) & rb->size_mask; |
|
|
|
} |
|
|
|
if (n2) { |
|
|
|
memcpy (dest + n1, &(rb->buf[rb->read_ptr]), n2); |
|
|
|
rb->read_ptr = (rb->read_ptr + n2) & rb->size_mask; |
|
|
|
} |
|
|
|
|
|
|
|
return to_read; |
|
|
|
return to_read; |
|
|
|
} |
|
|
|
|
|
|
|
/* The copying data reader w/o read pointer advance. Copy at most |
|
|
|
`cnt' bytes from `rb' to `dest'. Returns the actual number of bytes |
|
|
|
copied. */ |
|
|
|
copied. */ |
|
|
|
|
|
|
|
size_t |
|
|
|
jack_ringbuffer_peek (jack_ringbuffer_t * rb, char *dest, size_t cnt) |
|
|
|
{ |
|
|
|
size_t free_cnt; |
|
|
|
size_t cnt2; |
|
|
|
size_t to_read; |
|
|
|
size_t n1, n2; |
|
|
|
size_t tmp_read_ptr; |
|
|
|
size_t free_cnt; |
|
|
|
size_t cnt2; |
|
|
|
size_t to_read; |
|
|
|
size_t n1, n2; |
|
|
|
size_t tmp_read_ptr; |
|
|
|
|
|
|
|
tmp_read_ptr = rb->read_ptr; |
|
|
|
tmp_read_ptr = rb->read_ptr; |
|
|
|
|
|
|
|
if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
to_read = cnt > free_cnt ? free_cnt : cnt; |
|
|
|
to_read = cnt > free_cnt ? free_cnt : cnt; |
|
|
|
|
|
|
|
cnt2 = tmp_read_ptr + to_read; |
|
|
|
cnt2 = tmp_read_ptr + to_read; |
|
|
|
|
|
|
|
if (cnt2 > rb->size) { |
|
|
|
n1 = rb->size - tmp_read_ptr; |
|
|
|
n2 = cnt2 & rb->size_mask; |
|
|
|
} else { |
|
|
|
n1 = to_read; |
|
|
|
n2 = 0; |
|
|
|
} |
|
|
|
if (cnt2 > rb->size) { |
|
|
|
n1 = rb->size - tmp_read_ptr; |
|
|
|
n2 = cnt2 & rb->size_mask; |
|
|
|
} else { |
|
|
|
n1 = to_read; |
|
|
|
n2 = 0; |
|
|
|
} |
|
|
|
|
|
|
|
memcpy (dest, &(rb->buf[tmp_read_ptr]), n1); |
|
|
|
tmp_read_ptr = (tmp_read_ptr + n1) & rb->size_mask; |
|
|
|
memcpy (dest, &(rb->buf[tmp_read_ptr]), n1); |
|
|
|
tmp_read_ptr = (tmp_read_ptr + n1) & rb->size_mask; |
|
|
|
|
|
|
|
if (n2) { |
|
|
|
memcpy (dest + n1, &(rb->buf[tmp_read_ptr]), n2); |
|
|
|
} |
|
|
|
if (n2) { |
|
|
|
memcpy (dest + n1, &(rb->buf[tmp_read_ptr]), n2); |
|
|
|
} |
|
|
|
|
|
|
|
return to_read; |
|
|
|
return to_read; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@@ -217,36 +222,36 @@ jack_ringbuffer_peek (jack_ringbuffer_t * rb, char *dest, size_t cnt) |
|
|
|
size_t |
|
|
|
jack_ringbuffer_write (jack_ringbuffer_t * rb, const char *src, size_t cnt) |
|
|
|
{ |
|
|
|
size_t free_cnt; |
|
|
|
size_t cnt2; |
|
|
|
size_t to_write; |
|
|
|
size_t n1, n2; |
|
|
|
size_t free_cnt; |
|
|
|
size_t cnt2; |
|
|
|
size_t to_write; |
|
|
|
size_t n1, n2; |
|
|
|
|
|
|
|
if ((free_cnt = jack_ringbuffer_write_space (rb)) == 0) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
if ((free_cnt = jack_ringbuffer_write_space (rb)) == 0) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
to_write = cnt > free_cnt ? free_cnt : cnt; |
|
|
|
to_write = cnt > free_cnt ? free_cnt : cnt; |
|
|
|
|
|
|
|
cnt2 = rb->write_ptr + to_write; |
|
|
|
cnt2 = rb->write_ptr + to_write; |
|
|
|
|
|
|
|
if (cnt2 > rb->size) { |
|
|
|
n1 = rb->size - rb->write_ptr; |
|
|
|
n2 = cnt2 & rb->size_mask; |
|
|
|
} else { |
|
|
|
n1 = to_write; |
|
|
|
n2 = 0; |
|
|
|
} |
|
|
|
if (cnt2 > rb->size) { |
|
|
|
n1 = rb->size - rb->write_ptr; |
|
|
|
n2 = cnt2 & rb->size_mask; |
|
|
|
} else { |
|
|
|
n1 = to_write; |
|
|
|
n2 = 0; |
|
|
|
} |
|
|
|
|
|
|
|
memcpy (&(rb->buf[rb->write_ptr]), src, n1); |
|
|
|
rb->write_ptr = (rb->write_ptr + n1) & rb->size_mask; |
|
|
|
memcpy (&(rb->buf[rb->write_ptr]), src, n1); |
|
|
|
rb->write_ptr = (rb->write_ptr + n1) & rb->size_mask; |
|
|
|
|
|
|
|
if (n2) { |
|
|
|
memcpy (&(rb->buf[rb->write_ptr]), src + n1, n2); |
|
|
|
rb->write_ptr = (rb->write_ptr + n2) & rb->size_mask; |
|
|
|
} |
|
|
|
if (n2) { |
|
|
|
memcpy (&(rb->buf[rb->write_ptr]), src + n1, n2); |
|
|
|
rb->write_ptr = (rb->write_ptr + n2) & rb->size_mask; |
|
|
|
} |
|
|
|
|
|
|
|
return to_write; |
|
|
|
return to_write; |
|
|
|
} |
|
|
|
|
|
|
|
/* Advance the read pointer `cnt' places. */ |
|
|
@@ -254,8 +259,8 @@ jack_ringbuffer_write (jack_ringbuffer_t * rb, const char *src, size_t cnt) |
|
|
|
void |
|
|
|
jack_ringbuffer_read_advance (jack_ringbuffer_t * rb, size_t cnt) |
|
|
|
{ |
|
|
|
size_t tmp = (rb->read_ptr + cnt) & rb->size_mask; |
|
|
|
rb->read_ptr = tmp; |
|
|
|
size_t tmp = (rb->read_ptr + cnt) & rb->size_mask; |
|
|
|
rb->read_ptr = tmp; |
|
|
|
} |
|
|
|
|
|
|
|
/* Advance the write pointer `cnt' places. */ |
|
|
@@ -263,8 +268,8 @@ jack_ringbuffer_read_advance (jack_ringbuffer_t * rb, size_t cnt) |
|
|
|
void |
|
|
|
jack_ringbuffer_write_advance (jack_ringbuffer_t * rb, size_t cnt) |
|
|
|
{ |
|
|
|
size_t tmp = (rb->write_ptr + cnt) & rb->size_mask; |
|
|
|
rb->write_ptr = tmp; |
|
|
|
size_t tmp = (rb->write_ptr + cnt) & rb->size_mask; |
|
|
|
rb->write_ptr = tmp; |
|
|
|
} |
|
|
|
|
|
|
|
/* The non-copying data reader. `vec' is an array of two places. Set |
|
|
@@ -276,39 +281,39 @@ void |
|
|
|
jack_ringbuffer_get_read_vector (const jack_ringbuffer_t * rb, |
|
|
|
jack_ringbuffer_data_t * vec) |
|
|
|
{ |
|
|
|
size_t free_cnt; |
|
|
|
size_t cnt2; |
|
|
|
size_t w, r; |
|
|
|
size_t free_cnt; |
|
|
|
size_t cnt2; |
|
|
|
size_t w, r; |
|
|
|
|
|
|
|
w = rb->write_ptr; |
|
|
|
r = rb->read_ptr; |
|
|
|
w = rb->write_ptr; |
|
|
|
r = rb->read_ptr; |
|
|
|
|
|
|
|
if (w > r) { |
|
|
|
free_cnt = w - r; |
|
|
|
} else { |
|
|
|
free_cnt = (w - r + rb->size) & rb->size_mask; |
|
|
|
} |
|
|
|
if (w > r) { |
|
|
|
free_cnt = w - r; |
|
|
|
} else { |
|
|
|
free_cnt = (w - r + rb->size) & rb->size_mask; |
|
|
|
} |
|
|
|
|
|
|
|
cnt2 = r + free_cnt; |
|
|
|
cnt2 = r + free_cnt; |
|
|
|
|
|
|
|
if (cnt2 > rb->size) { |
|
|
|
if (cnt2 > rb->size) { |
|
|
|
|
|
|
|
/* Two part vector: the rest of the buffer after the current write |
|
|
|
ptr, plus some from the start of the buffer. */ |
|
|
|
/* Two part vector: the rest of the buffer after the current write |
|
|
|
ptr, plus some from the start of the buffer. */ |
|
|
|
|
|
|
|
vec[0].buf = &(rb->buf[r]); |
|
|
|
vec[0].len = rb->size - r; |
|
|
|
vec[1].buf = rb->buf; |
|
|
|
vec[1].len = cnt2 & rb->size_mask; |
|
|
|
vec[0].buf = &(rb->buf[r]); |
|
|
|
vec[0].len = rb->size - r; |
|
|
|
vec[1].buf = rb->buf; |
|
|
|
vec[1].len = cnt2 & rb->size_mask; |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
|
|
|
|
/* Single part vector: just the rest of the buffer */ |
|
|
|
/* Single part vector: just the rest of the buffer */ |
|
|
|
|
|
|
|
vec[0].buf = &(rb->buf[r]); |
|
|
|
vec[0].len = free_cnt; |
|
|
|
vec[1].len = 0; |
|
|
|
} |
|
|
|
vec[0].buf = &(rb->buf[r]); |
|
|
|
vec[0].len = free_cnt; |
|
|
|
vec[1].len = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* The non-copying data writer. `vec' is an array of two places. Set |
|
|
@@ -320,35 +325,35 @@ void |
|
|
|
jack_ringbuffer_get_write_vector (const jack_ringbuffer_t * rb, |
|
|
|
jack_ringbuffer_data_t * vec) |
|
|
|
{ |
|
|
|
size_t free_cnt; |
|
|
|
size_t cnt2; |
|
|
|
size_t w, r; |
|
|
|
|
|
|
|
w = rb->write_ptr; |
|
|
|
r = rb->read_ptr; |
|
|
|
|
|
|
|
if (w > r) { |
|
|
|
free_cnt = ((r - w + rb->size) & rb->size_mask) - 1; |
|
|
|
} else if (w < r) { |
|
|
|
free_cnt = (r - w) - 1; |
|
|
|
} else { |
|
|
|
free_cnt = rb->size - 1; |
|
|
|
} |
|
|
|
|
|
|
|
cnt2 = w + free_cnt; |
|
|
|
|
|
|
|
if (cnt2 > rb->size) { |
|
|
|
|
|
|
|
/* Two part vector: the rest of the buffer after the current write |
|
|
|
ptr, plus some from the start of the buffer. */ |
|
|
|
|
|
|
|
vec[0].buf = &(rb->buf[w]); |
|
|
|
vec[0].len = rb->size - w; |
|
|
|
vec[1].buf = rb->buf; |
|
|
|
vec[1].len = cnt2 & rb->size_mask; |
|
|
|
} else { |
|
|
|
vec[0].buf = &(rb->buf[w]); |
|
|
|
vec[0].len = free_cnt; |
|
|
|
vec[1].len = 0; |
|
|
|
} |
|
|
|
size_t free_cnt; |
|
|
|
size_t cnt2; |
|
|
|
size_t w, r; |
|
|
|
|
|
|
|
w = rb->write_ptr; |
|
|
|
r = rb->read_ptr; |
|
|
|
|
|
|
|
if (w > r) { |
|
|
|
free_cnt = ((r - w + rb->size) & rb->size_mask) - 1; |
|
|
|
} else if (w < r) { |
|
|
|
free_cnt = (r - w) - 1; |
|
|
|
} else { |
|
|
|
free_cnt = rb->size - 1; |
|
|
|
} |
|
|
|
|
|
|
|
cnt2 = w + free_cnt; |
|
|
|
|
|
|
|
if (cnt2 > rb->size) { |
|
|
|
|
|
|
|
/* Two part vector: the rest of the buffer after the current write |
|
|
|
ptr, plus some from the start of the buffer. */ |
|
|
|
|
|
|
|
vec[0].buf = &(rb->buf[w]); |
|
|
|
vec[0].len = rb->size - w; |
|
|
|
vec[1].buf = rb->buf; |
|
|
|
vec[1].len = cnt2 & rb->size_mask; |
|
|
|
} else { |
|
|
|
vec[0].buf = &(rb->buf[w]); |
|
|
|
vec[0].len = free_cnt; |
|
|
|
vec[1].len = 0; |
|
|
|
} |
|
|
|
} |