|
version 1.5.2.1, 2026/02/10 18:23:53
|
version 1.8, 2026/02/18 11:41:47
|
|
Line 61 rbuf_init(ringbuf_t *rbuf, int num)
|
Line 61 rbuf_init(ringbuf_t *rbuf, int num)
|
| |
|
| atomic_store_explicit((atomic_int*) &rbuf->rb_head, 0, memory_order_relaxed); |
atomic_store_explicit((atomic_int*) &rbuf->rb_head, 0, memory_order_relaxed); |
| atomic_store_explicit((atomic_int*) &rbuf->rb_tail, 0, memory_order_relaxed); |
atomic_store_explicit((atomic_int*) &rbuf->rb_tail, 0, memory_order_relaxed); |
| |
atomic_store_explicit((atomic_int*) &rbuf->rb_full, 0, memory_order_relaxed); |
| |
|
| rbuf->rb_buffer = e_calloc(num, sizeof(struct iovec)); |
rbuf->rb_buffer = e_calloc(num, sizeof(struct iovec)); |
| if (!rbuf->rb_buffer) |
if (!rbuf->rb_buffer) |
|
Line 92 rbuf_free(ringbuf_t *rbuf)
|
Line 93 rbuf_free(ringbuf_t *rbuf)
|
| |
|
| atomic_store_explicit((atomic_int*) &rbuf->rb_head, 0, memory_order_relaxed); |
atomic_store_explicit((atomic_int*) &rbuf->rb_head, 0, memory_order_relaxed); |
| atomic_store_explicit((atomic_int*) &rbuf->rb_tail, 0, memory_order_relaxed); |
atomic_store_explicit((atomic_int*) &rbuf->rb_tail, 0, memory_order_relaxed); |
| |
atomic_store_explicit((atomic_int*) &rbuf->rb_full, 0, memory_order_relaxed); |
| } |
} |
| |
|
| /* |
/* |
|
Line 111 rbuf_purge(ringbuf_t *rbuf)
|
Line 113 rbuf_purge(ringbuf_t *rbuf)
|
| |
|
| atomic_store_explicit((atomic_int*) &rbuf->rb_head, 0, memory_order_relaxed); |
atomic_store_explicit((atomic_int*) &rbuf->rb_head, 0, memory_order_relaxed); |
| atomic_store_explicit((atomic_int*) &rbuf->rb_tail, 0, memory_order_relaxed); |
atomic_store_explicit((atomic_int*) &rbuf->rb_tail, 0, memory_order_relaxed); |
| |
atomic_store_explicit((atomic_int*) &rbuf->rb_full, 0, memory_order_relaxed); |
| } |
} |
| |
|
| /* |
/* |
|
Line 122 rbuf_purge(ringbuf_t *rbuf)
|
Line 125 rbuf_purge(ringbuf_t *rbuf)
|
| int |
int |
| rbuf_isempty(ringbuf_t *rbuf) |
rbuf_isempty(ringbuf_t *rbuf) |
| { |
{ |
| if (!rbuf) | if (!rbuf || !rbuf->rb_bufnum) |
| return -1; |
return -1; |
| |
|
| |
if (atomic_load_explicit((atomic_int*) &rbuf->rb_full, memory_order_acquire)) |
| |
return 0; |
| |
|
| return (atomic_load_explicit((atomic_int*) &rbuf->rb_head, memory_order_acquire) == |
return (atomic_load_explicit((atomic_int*) &rbuf->rb_head, memory_order_acquire) == |
| atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_acquire)); | atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_acquire)); |
| } |
} |
| |
|
| /* |
/* |
|
Line 140 rbuf_isfull(ringbuf_t *rbuf)
|
Line 146 rbuf_isfull(ringbuf_t *rbuf)
|
| { |
{ |
| int h, t; |
int h, t; |
| |
|
| if (!rbuf) | if (!rbuf || !rbuf->rb_bufnum) |
| return -1; |
return -1; |
| if (!rbuf->rb_bufnum) |
|
| return 1; |
|
| |
|
| t = atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_acquire); | if (!atomic_load_explicit((atomic_int*) &rbuf->rb_full, memory_order_acquire)) |
| h = atomic_load_explicit((atomic_int*) &rbuf->rb_head, memory_order_relaxed) + 1; | return 0; |
| if (h >= rbuf->rb_bufnum) | |
| h ^= h; | |
| |
|
| |
t = atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_acquire); |
| |
h = atomic_load_explicit((atomic_int*) &rbuf->rb_head, memory_order_acquire); |
| return (h == t); |
return (h == t); |
| } |
} |
| |
|
|
Line 159 rbuf_isfull(ringbuf_t *rbuf)
|
Line 163 rbuf_isfull(ringbuf_t *rbuf)
|
| * @rbuf = Ring buffer |
* @rbuf = Ring buffer |
| * @data = Data |
* @data = Data |
| * @len = Length |
* @len = Length |
| |
* @lost = Permit to lost data |
| * return: -1 error, 1 buffer is full or 0 ok |
* return: -1 error, 1 buffer is full or 0 ok |
| */ |
*/ |
| int |
int |
| rbuf_enqueue(ringbuf_t *rbuf, void *data, size_t len) | rbuf_enqueue(ringbuf_t *rbuf, void *data, size_t len, int lost) |
| { |
{ |
| int h, t, n; | int h, t, f, n, t2, drop = 0; |
| struct iovec *iov; |
struct iovec *iov; |
| |
|
| if (!rbuf || !rbuf->rb_buffer) | if (!rbuf || !rbuf->rb_buffer || !rbuf->rb_bufnum) |
| return -1; |
return -1; |
| if (!rbuf->rb_bufnum) |
|
| return 1; |
|
| |
|
| h = atomic_load_explicit((atomic_int*) &rbuf->rb_head, memory_order_relaxed); | f = atomic_load_explicit((atomic_int*) &rbuf->rb_full, memory_order_acquire); |
| t = atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_acquire); |
t = atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_acquire); |
| n = (h + 1) % rbuf->rb_bufnum; | h = atomic_load_explicit((atomic_int*) &rbuf->rb_head, memory_order_acquire); |
| |
|
| if (n == t) | if (f && h == t) { |
| return 1; | if (!lost) |
| | return 1; |
| | else |
| | drop = 1; |
| | } |
| |
|
| |
n = (h + 1) % rbuf->rb_bufnum; |
| |
|
| iov = rbuf->rb_buffer + h; |
iov = rbuf->rb_buffer + h; |
| iov->iov_len = len; |
iov->iov_len = len; |
| iov->iov_base = data; |
iov->iov_base = data; |
| |
|
| atomic_store_explicit((atomic_int*) &rbuf->rb_head, n, memory_order_release); |
atomic_store_explicit((atomic_int*) &rbuf->rb_head, n, memory_order_release); |
| |
if (drop) { |
| |
t2 = (t + 1) % rbuf->rb_bufnum; |
| |
while (42) { |
| |
drop = t; |
| |
if (atomic_compare_exchange_weak_explicit((atomic_int*) &rbuf->rb_tail, |
| |
&drop, t2, memory_order_release, memory_order_relaxed)) |
| |
break; |
| |
t = drop; |
| |
t2 = (t + 1) % rbuf->rb_bufnum; |
| |
} |
| |
} else |
| |
t2 = atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_acquire); |
| |
atomic_store_explicit((atomic_int*) &rbuf->rb_full, (n == t2), memory_order_release); |
| return 0; |
return 0; |
| } |
} |
| |
|
|
Line 197 rbuf_enqueue(ringbuf_t *rbuf, void *data, size_t len)
|
Line 219 rbuf_enqueue(ringbuf_t *rbuf, void *data, size_t len)
|
| int |
int |
| rbuf_dequeue(ringbuf_t *rbuf, struct iovec **out) |
rbuf_dequeue(ringbuf_t *rbuf, struct iovec **out) |
| { |
{ |
| int h, t, n; | int h, t, n, f; |
| |
|
| if (!rbuf || !rbuf->rb_buffer) | if (!rbuf || !rbuf->rb_buffer || !rbuf->rb_bufnum) |
| return -1; |
return -1; |
| if (!rbuf->rb_bufnum) |
|
| return 1; |
|
| |
|
| h = atomic_load_explicit((atomic_int*) &rbuf->rb_head, memory_order_acquire); | while (42) { |
| t = atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_relaxed); | h = atomic_load_explicit((atomic_int*) &rbuf->rb_head, memory_order_acquire); |
| n = (t + 1) % rbuf->rb_bufnum; | f = atomic_load_explicit((atomic_int*) &rbuf->rb_full, memory_order_acquire); |
| | t = atomic_load_explicit((atomic_int*) &rbuf->rb_tail, memory_order_acquire); |
| |
|
| if (h == t) | if (!f && h == t) |
| return 1; | return 1; |
| |
|
| if (out) | n = (t + 1) % rbuf->rb_bufnum; |
| *out = rbuf->rb_buffer + t; | |
| |
|
| atomic_store_explicit((atomic_int*) &rbuf->rb_tail, n, memory_order_release); | f = t; |
| | if (atomic_compare_exchange_weak_explicit((atomic_int*) &rbuf->rb_tail, |
| | &f, n, memory_order_release, memory_order_relaxed)) { |
| | if (out) |
| | *out = rbuf->rb_buffer + t; |
| | |
| | atomic_store_explicit((atomic_int*) &rbuf->rb_full, 0, memory_order_release); |
| | break; |
| | } |
| | } |
| | |
| return 0; |
return 0; |
| } |
} |
| |
|
|
Line 234 lrb_init(lrbuf_t *lrb, u_int size)
|
Line 264 lrb_init(lrbuf_t *lrb, u_int size)
|
| |
|
| atomic_store_explicit((atomic_int*) &lrb->lrb_head, 0, memory_order_relaxed); |
atomic_store_explicit((atomic_int*) &lrb->lrb_head, 0, memory_order_relaxed); |
| atomic_store_explicit((atomic_int*) &lrb->lrb_tail, 0, memory_order_relaxed); |
atomic_store_explicit((atomic_int*) &lrb->lrb_tail, 0, memory_order_relaxed); |
| |
atomic_store_explicit((atomic_int*) &lrb->lrb_full, 0, memory_order_relaxed); |
| |
|
| lrb->lrb_data = e_malloc(size); |
lrb->lrb_data = e_malloc(size); |
| if (!lrb->lrb_data) |
if (!lrb->lrb_data) |
|
Line 265 lrb_free(lrbuf_t *lrb)
|
Line 296 lrb_free(lrbuf_t *lrb)
|
| |
|
| atomic_store_explicit((atomic_int*) &lrb->lrb_head, 0, memory_order_relaxed); |
atomic_store_explicit((atomic_int*) &lrb->lrb_head, 0, memory_order_relaxed); |
| atomic_store_explicit((atomic_int*) &lrb->lrb_tail, 0, memory_order_relaxed); |
atomic_store_explicit((atomic_int*) &lrb->lrb_tail, 0, memory_order_relaxed); |
| |
atomic_store_explicit((atomic_int*) &lrb->lrb_full, 0, memory_order_relaxed); |
| } |
} |
| |
|
| /* |
/* |
|
Line 296 lrb_purge(lrbuf_t *lrb)
|
Line 328 lrb_purge(lrbuf_t *lrb)
|
| int |
int |
| lrb_isempty(lrbuf_t *lrb) |
lrb_isempty(lrbuf_t *lrb) |
| { |
{ |
| if (!lrb) | if (!lrb || !lrb->lrb_size) |
| return -1; |
return -1; |
| |
|
| return (!atomic_load_explicit((atomic_int*) &lrb->lrb_full, memory_order_acquire) && | if (atomic_load_explicit((atomic_int*) &lrb->lrb_full, memory_order_acquire)) |
| (atomic_load_explicit((atomic_int*) &lrb->lrb_head, memory_order_acquire) == | return 0; |
| atomic_load_explicit((atomic_int*) &lrb->lrb_tail, memory_order_acquire))); | |
| | return (atomic_load_explicit((atomic_int*) &lrb->lrb_head, memory_order_acquire) == |
| | atomic_load_explicit((atomic_int*) &lrb->lrb_tail, memory_order_acquire)); |
| } |
} |
| |
|
| /* |
/* |
|
Line 315 lrb_isfull(lrbuf_t *lrb)
|
Line 349 lrb_isfull(lrbuf_t *lrb)
|
| { |
{ |
| int h, t; |
int h, t; |
| |
|
| if (!lrb) | if (!lrb || !lrb->lrb_size) |
| return -1; |
return -1; |
| if (!lrb->lrb_size) |
|
| return 1; |
|
| |
|
| if (!atomic_load_explicit((atomic_int*) &lrb->lrb_full, memory_order_acquire)) |
if (!atomic_load_explicit((atomic_int*) &lrb->lrb_full, memory_order_acquire)) |
| return 0; |
return 0; |
|
Line 329 lrb_isfull(lrbuf_t *lrb)
|
Line 361 lrb_isfull(lrbuf_t *lrb)
|
| } |
} |
| |
|
| /* |
/* |
| |
* lrb_getw() - Get address for write |
| |
* |
| |
* @lrb = Linear ring buffer |
| |
* @len = Return available buffer length for write |
| |
* return: NULL error or !=NULL pointer for write |
| |
* remark: After use of lrb_getw() and write to pointer. |
| |
* You should update ring buffer with lrb_enqueue(,NULL,wrote_len,) |
| |
*/ |
| |
void * |
| |
lrb_getw(lrbuf_t *lrb, size_t *len) |
| |
{ |
| |
int h; |
| |
|
| |
if (!lrb || !lrb->lrb_data || !lrb->lrb_size) |
| |
return NULL; |
| |
|
| |
h = atomic_load_explicit((atomic_int*) &lrb->lrb_head, memory_order_relaxed); |
| |
if (len) |
| |
*len = lrb->lrb_size - h; |
| |
|
| |
return (lrb->lrb_data + h); |
| |
} |
| |
|
| |
/* |
| * lrb_enqueue() - Enqueue data to buffer |
* lrb_enqueue() - Enqueue data to buffer |
| * |
* |
| * @lrb = Linear ring buffer |
* @lrb = Linear ring buffer |
|
Line 342 lrb_enqueue(lrbuf_t *lrb, void *data, size_t len, int
|
Line 398 lrb_enqueue(lrbuf_t *lrb, void *data, size_t len, int
|
| { |
{ |
| int h, t = 0, n, t2 = 0, unused, drop = 0; |
int h, t = 0, n, t2 = 0, unused, drop = 0; |
| |
|
| if (!lrb || !lrb->lrb_data) | if (!lrb || !lrb->lrb_data || !lrb->lrb_size) |
| return -1; |
return -1; |
| if (!lrb->lrb_size || lrb->lrb_size <= len) | if (lrb->lrb_size <= len) |
| return 1; |
return 1; |
| |
|
| lrb_unused(lrb, unused); |
lrb_unused(lrb, unused); |
|
Line 364 lrb_enqueue(lrbuf_t *lrb, void *data, size_t len, int
|
Line 420 lrb_enqueue(lrbuf_t *lrb, void *data, size_t len, int
|
| h = atomic_load_explicit((atomic_int*) &lrb->lrb_head, memory_order_relaxed); |
h = atomic_load_explicit((atomic_int*) &lrb->lrb_head, memory_order_relaxed); |
| n = lrb->lrb_size - h; |
n = lrb->lrb_size - h; |
| if (len < n) { |
if (len < n) { |
| memcpy(lrb->lrb_data + h, data, len); | if (data) |
| | memcpy(lrb->lrb_data + h, data, len); |
| n = h + len; |
n = h + len; |
| } else { |
} else { |
| memcpy(lrb->lrb_data + h, data, n); | if (data) { |
| memcpy(lrb->lrb_data, data + n, len - n); | memcpy(lrb->lrb_data + h, data, n); |
| | memcpy(lrb->lrb_data, data + n, len - n); |
| | } |
| n = len - n; |
n = len - n; |
| } |
} |
| |
|
|
Line 390 lrb_enqueue(lrbuf_t *lrb, void *data, size_t len, int
|
Line 449 lrb_enqueue(lrbuf_t *lrb, void *data, size_t len, int
|
| } |
} |
| |
|
| /* |
/* |
| |
* lrb_getr() - Get address for read |
| |
* |
| |
* @lrb = Linear ring buffer |
| |
* @len = Return available data length for read |
| |
* return: NULL error or !=NULL pointer for read |
| |
* remark: After use of lrb_getr() and read from pointer. |
| |
* You could update ring buffer with lrb_dequeue(,NULL,read_len) |
| |
*/ |
| |
void * |
| |
lrb_getr(lrbuf_t *lrb, size_t *len) |
| |
{ |
| |
int t; |
| |
|
| |
if (!lrb || !lrb->lrb_data || !lrb->lrb_size) |
| |
return NULL; |
| |
|
| |
t = atomic_load_explicit((atomic_int*) &lrb->lrb_tail, memory_order_acquire); |
| |
if (len) |
| |
lrb_queued(lrb, *len); |
| |
|
| |
return (lrb->lrb_data + t); |
| |
} |
| |
|
| |
/* |
| * lrb_dequeue() - Dequeue data from buffer |
* lrb_dequeue() - Dequeue data from buffer |
| * |
* |
| * @lrb = Linear ring buffer |
* @lrb = Linear ring buffer |
|
Line 402 lrb_dequeue(lrbuf_t *lrb, void *data, size_t len)
|
Line 485 lrb_dequeue(lrbuf_t *lrb, void *data, size_t len)
|
| { |
{ |
| int h, t, t2, n, l, f; |
int h, t, t2, n, l, f; |
| |
|
| if (!lrb) | if (!lrb || !lrb->lrb_size) |
| return -1; |
return -1; |
| if (!lrb->lrb_size || !len || lrb_isempty(lrb)) | if (!len || lrb_isempty(lrb)) |
| return 0; |
return 0; |
| if (lrb->lrb_size <= len) |
if (lrb->lrb_size <= len) |
| len = lrb->lrb_size - 1; |
len = lrb->lrb_size - 1; |
|
Line 433 lrb_dequeue(lrbuf_t *lrb, void *data, size_t len)
|
Line 516 lrb_dequeue(lrbuf_t *lrb, void *data, size_t len)
|
| } else { |
} else { |
| if (data) { |
if (data) { |
| memcpy(data, lrb->lrb_data + t, n); |
memcpy(data, lrb->lrb_data + t, n); |
| memcpy(data + n, lrb->lrb_data, l - n); | memcpy(((u_char*) data) + n, lrb->lrb_data, l - n); |
| } |
} |
| t2 = l - n; |
t2 = l - n; |
| } |
} |