tor_multipath_voip/src/utils.c

95 lines
2.5 KiB
C
Raw Normal View History

2019-02-12 10:17:37 +00:00
#include "utils.h"
int ring_buffer_read(struct ring_buffer* rb, char* dest, int size) {
int slice1 = size;
int slice2 = 0;
int used_space = ring_buffer_used_space (rb);
if (used_space < slice1)
slice1 = used_space;
if (RING_BUFFER_SIZE - rb->head < slice1) {
slice1 = RING_BUFFER_SIZE - rb->head;
slice2 = size - slice1;
if (used_space - slice1 < slice2)
slice2 = used_space - slice1;
}
2019-02-12 16:57:51 +00:00
printf("max_buffer=%d, head=%d, tail=%d, size=%d, slice1=%d, slice2=%d\n", RING_BUFFER_SIZE, rb->head, rb->tail, size, slice1, slice2);
2019-02-12 10:17:37 +00:00
memcpy(dest, rb->buffer + rb->head, slice1);
memcpy(dest+slice1, rb->buffer, slice2);
return slice1 + slice2;
}
void ring_buffer_ack_read(struct ring_buffer* rb, int size) {
if (size > ring_buffer_used_space (rb)) {
fprintf(stderr, "You try to ack more data than contained in the ring buffer\n");
exit(EXIT_FAILURE);
}
rb->head = (rb->head + size) % RING_BUFFER_SIZE;
}
int ring_buffer_write(struct ring_buffer* rb, char* source, int size) {
if (size > ring_buffer_free_space (rb)) {
fprintf(stderr, "You try to write more data than available space in the buffer\n");
exit(EXIT_FAILURE);
}
int slice1 = size;
int slice2 = 0;
if (RING_BUFFER_SIZE - rb->tail < slice1) {
slice1 = RING_BUFFER_SIZE - rb->tail;
slice2 = size - slice1;
}
memcpy(rb->buffer + rb->tail, source, slice1);
memcpy(rb->buffer, source + slice1, slice2);
rb->tail = (rb->tail + slice1 + slice2) % RING_BUFFER_SIZE;
return slice1 + slice2;
}
int ring_buffer_free_space(struct ring_buffer* rb) {
if (rb->head > rb->tail) return rb->head - rb->tail;
2019-02-12 16:57:51 +00:00
return RING_BUFFER_SIZE - (rb->tail - rb->head);
2019-02-12 10:17:37 +00:00
}
int ring_buffer_used_space(struct ring_buffer* rb) {
return RING_BUFFER_SIZE - ring_buffer_free_space (rb);
}
2019-03-18 16:58:40 +00:00
2019-03-19 17:22:23 +00:00
// Why we are using modulo, plus and modulo again:
// https://stackoverflow.com/a/1907585
2019-03-18 16:58:40 +00:00
int ring_ge(uint16_t v1, uint16_t v2) {
2019-03-19 19:48:07 +00:00
int64_t vv1 = (int64_t) v1, vv2 = (int64_t) v2;
2019-03-19 17:22:23 +00:00
return (((vv1 - vv2) % UINT16_MAX) + UINT16_MAX) % UINT16_MAX <= UINT16_MAX / 2;
2019-03-18 16:58:40 +00:00
}
2019-03-19 17:22:23 +00:00
int ring_gt(uint16_t v1, uint16_t v2) {
if (v1 == v2) return 0;
return ring_ge(v1,v2);
2019-03-18 16:58:40 +00:00
}
int ring_le(uint16_t v1, uint16_t v2) {
2019-03-20 07:51:40 +00:00
return ring_ge(v2, v1);
2019-03-19 17:22:23 +00:00
}
int ring_lt(uint16_t v1, uint16_t v2) {
2019-03-20 07:51:40 +00:00
return ring_gt(v2, v1);
2019-03-18 16:58:40 +00:00
}
2019-04-01 17:27:40 +00:00
uint64_t elapsed_micros(struct timespec* t1, struct timespec* t2) {
int secs, nsecs;
uint64_t micro_sec;
secs = t2->tv_sec - t1->tv_sec;
nsecs = t2->tv_nsec - t1->tv_nsec;
micro_sec = secs * 1000000 + nsecs / 1000;
return micro_sec;
}