diff options
-rw-r--r-- | raul/RingBuffer.hpp | 2 | ||||
-rw-r--r-- | test/ringbuffer_test.cpp | 172 |
2 files changed, 120 insertions, 54 deletions
diff --git a/raul/RingBuffer.hpp b/raul/RingBuffer.hpp index 8642514..faf1142 100644 --- a/raul/RingBuffer.hpp +++ b/raul/RingBuffer.hpp @@ -199,7 +199,7 @@ private: } else { const uint32_t first_size = _size - r; memcpy(dst, &_buf[r], first_size); - memcpy(dst, &_buf[0], size - first_size); + memcpy((char*)dst + first_size, &_buf[0], size - first_size); } return size; diff --git a/test/ringbuffer_test.cpp b/test/ringbuffer_test.cpp index ea1088c..c843ed2 100644 --- a/test/ringbuffer_test.cpp +++ b/test/ringbuffer_test.cpp @@ -1,6 +1,7 @@ -#include <iostream> -#include <cstring> +#include <cstdio> #include <cstdlib> +#include <cstring> +#include <iostream> #include "raul/log.hpp" #include "raul/RingBuffer.hpp" @@ -8,67 +9,132 @@ using namespace std; using namespace Raul; -int -main() +#define MSG_SIZE 20 + +Raul::RingBuffer* ring = 0; +size_t n_writes = 0; +bool ring_error = false; + +static int +gen_msg(int* msg, int start) { - static const int n_tests = 32; - for (int i = 0; i < n_tests; ++i) { - const int size = (rand() % 2000) + 8; - RingBuffer rb(size); - - for (int j = 0; j < size * 32; ++j) { - char ev1[] = { 'a', 'b', 'c' }; - rb.write(3, ev1); - - char buf[3]; - uint32_t read = rb.read(3, buf); - if (read != 3 || strncmp(buf, "abc", 3)) { - error << "Corrupt event " << i << ".1: " - << buf[0] << buf[1] << buf[2] << endl; - return 1; - } - - char ev2[] = { 'd', 'e', 'f' }; - if (!rb.write(3, ev2)) { - error << "Failed write " << i << ".2" << endl; - return 1; - } + for (int i = 0; i < MSG_SIZE; ++i) { + msg[i] = start; + start = (start + 1) % INT_MAX; + } + return start; +} - char ev3[] = { 'g', 'h' }; - if (!rb.write(2, ev3)) { - error << "Failed write " << i << ".3" << endl; - return 1; - } +static int +cmp_msg(int* msg1, int* msg2) +{ + for (int i = 0; i < MSG_SIZE; ++i) { + if (msg1[i] != msg2[i]) { + fprintf(stderr, "ERROR: %d != %d @ %d\n", msg1[i], msg2[i], i); + return 0; + } + } - if (rb.skip(1) != 1) { - error << "Failed skip " << i << endl; - return 1; - } + return 1; +} - uint32_t n_read = rb.read(2, buf); - if (n_read != 2 || strncmp(buf, "ef", 2)) { - error << "Corrupt event " << i << ".4: " - << buf[0] << buf[1] << buf[2] << endl; - return 1; - } +static void* +reader(void* arg) +{ + printf("Reader starting\n"); - n_read = rb.peek(2, buf); - if (n_read != 2 || strncmp(buf, "gh", 2)) { - error << "Corrupt peek event " << i << ".5: " - << buf[0] << buf[1] << endl; - return 1; + int ref_msg[MSG_SIZE]; // Reference generated for comparison + int read_msg[MSG_SIZE]; // Read from ring + size_t count = 0; + int start = gen_msg(ref_msg, 0); + for (size_t i = 0; i < n_writes; ++i) { + if (ring->read_space() >= MSG_SIZE * sizeof(int)) { + const uint32_t n_read = ring->read(MSG_SIZE * sizeof(int), read_msg); + if (n_read != MSG_SIZE * sizeof(int)) { + fprintf(stderr, "FAIL: Read size incorrect\n"); + ring_error = true; + return NULL; + } + if (!cmp_msg(ref_msg, read_msg)) { + fprintf(stderr, "FAIL: Message %zu is corrupt\n", count); + ring_error = true; + return NULL; } + start = gen_msg(ref_msg, start); + ++count; + } + } + + printf("Reader finished\n"); + return NULL; +} + +static void* +writer(void* arg) +{ + printf("Writer starting\n"); - n_read = rb.read(2, buf); - if (n_read != 2 || strncmp(buf, "gh", 2)) { - error << "Corrupt event " << i << ".6: " - << buf[0] << buf[1] << endl; - return 1; + int write_msg[MSG_SIZE]; // Written to ring + int start = gen_msg(write_msg, 0); + for (size_t i = 0; i < n_writes; ++i) { + if (ring->write_space() >= MSG_SIZE * sizeof(int)) { + const uint32_t n_write = ring->write(MSG_SIZE * sizeof(int), write_msg); + if (n_write != MSG_SIZE * sizeof(int)) { + fprintf(stderr, "FAIL: Write size incorrect\n"); + ring_error = true; + return NULL; } + start = gen_msg(write_msg, start); } } - info << "Successfully ran " << n_tests << " tests." << endl; - return 0; + printf("Writer finished\n"); + return NULL; } +int +main(int argc, char** argv) +{ + if (argc > 1 && argv[1][0] == '-') { + printf("Usage: %s SIZE N_WRITES\n", argv[0]); + return 1; + } + + int size = 1024; + if (argc > 1) { + size = atoi(argv[1]); + } + + n_writes = size * 1024; + if (argc > 2) { + n_writes = atoi(argv[2]); + } + + printf("Testing %zu writes of %d ints to a %d int ring...\n", + n_writes, MSG_SIZE, size); + + ring = new Raul::RingBuffer(size); + + pthread_t reader_thread; + if (pthread_create(&reader_thread, NULL, reader, NULL)) { + fprintf(stderr, "Failed to create reader thread\n"); + return 1; + } + + pthread_t writer_thread; + if (pthread_create(&writer_thread, NULL, writer, NULL)) { + fprintf(stderr, "Failed to create writer thread\n"); + return 1; + } + + pthread_join(reader_thread, NULL); + pthread_join(writer_thread, NULL); + + if (ring_error) { + fprintf(stderr, "FAIL: Error occurred\n"); + return 1; + } + + delete ring; + return 0; +} |