[df668eb] | 1 | #include "data-struct/ring_buffer.h" |
---|
| 2 | #include <pthread.h> |
---|
| 3 | #include <assert.h> |
---|
| 4 | |
---|
[19135af] | 5 | #define TEST_SIZE ((char *) 1000000) |
---|
| 6 | #define RINGBUFFER_SIZE ((char *) 10000) |
---|
[df668eb] | 7 | |
---|
| 8 | static void * producer(void * a) { |
---|
| 9 | libtrace_ringbuffer_t * rb = (libtrace_ringbuffer_t *) a; |
---|
[19135af] | 10 | char * i; |
---|
| 11 | for (i = NULL; i < TEST_SIZE; i++) { |
---|
| 12 | libtrace_ringbuffer_write(rb, i); |
---|
[df668eb] | 13 | } |
---|
| 14 | return 0; |
---|
| 15 | } |
---|
| 16 | |
---|
| 17 | static void * consumer(void * a) { |
---|
| 18 | libtrace_ringbuffer_t * rb = (libtrace_ringbuffer_t *) a; |
---|
[19135af] | 19 | char *i; |
---|
| 20 | void *value; |
---|
| 21 | for (i = NULL; i < TEST_SIZE; i++) { |
---|
[df668eb] | 22 | value = libtrace_ringbuffer_read(rb); |
---|
[19135af] | 23 | assert(value == i); |
---|
[df668eb] | 24 | } |
---|
| 25 | return 0; |
---|
| 26 | } |
---|
| 27 | |
---|
[a49a9eb] | 28 | static void * producer_bulk(void * a) { |
---|
| 29 | libtrace_ringbuffer_t * rb = (libtrace_ringbuffer_t *) a; |
---|
| 30 | char * i; |
---|
| 31 | for (i = NULL; i < TEST_SIZE; i++) { |
---|
| 32 | assert(libtrace_ringbuffer_write_bulk(rb, (void **) &i, 1, 1) == 1); |
---|
| 33 | } |
---|
| 34 | return 0; |
---|
| 35 | } |
---|
| 36 | |
---|
| 37 | static void * consumer_bulk(void * a) { |
---|
| 38 | libtrace_ringbuffer_t * rb = (libtrace_ringbuffer_t *) a; |
---|
| 39 | char *i; |
---|
| 40 | void *value; |
---|
| 41 | for (i = NULL; i < TEST_SIZE; i++) { |
---|
| 42 | assert (libtrace_ringbuffer_read_bulk(rb, &value, 1, 1) == 1); |
---|
| 43 | assert(value == i); |
---|
| 44 | } |
---|
| 45 | return 0; |
---|
| 46 | } |
---|
| 47 | |
---|
| 48 | |
---|
[df668eb] | 49 | /** |
---|
| 50 | * Tests the ringbuffer data structure, first this establishes that single |
---|
| 51 | * threaded operations work correctly, then does a basic consumer producer |
---|
| 52 | * thread-safety test. |
---|
| 53 | */ |
---|
| 54 | int main() { |
---|
[19135af] | 55 | char *i; |
---|
[df668eb] | 56 | void *value; |
---|
| 57 | pthread_t t[4]; |
---|
| 58 | libtrace_ringbuffer_t rb_block; |
---|
| 59 | libtrace_ringbuffer_t rb_polling; |
---|
| 60 | |
---|
[19135af] | 61 | libtrace_ringbuffer_init(&rb_block, (size_t) RINGBUFFER_SIZE, LIBTRACE_RINGBUFFER_BLOCKING); |
---|
[a49a9eb] | 62 | libtrace_ringbuffer_init(&rb_polling, (size_t) RINGBUFFER_SIZE, LIBTRACE_RINGBUFFER_POLLING); |
---|
[df668eb] | 63 | assert(libtrace_ringbuffer_is_empty(&rb_block)); |
---|
| 64 | assert(libtrace_ringbuffer_is_empty(&rb_polling)); |
---|
| 65 | |
---|
[19135af] | 66 | for (i = NULL; i < RINGBUFFER_SIZE; i++) { |
---|
[df668eb] | 67 | value = (void *) i; |
---|
| 68 | libtrace_ringbuffer_write(&rb_block, value); |
---|
| 69 | libtrace_ringbuffer_write(&rb_polling, value); |
---|
| 70 | } |
---|
| 71 | |
---|
| 72 | assert(libtrace_ringbuffer_is_full(&rb_block)); |
---|
| 73 | assert(libtrace_ringbuffer_is_full(&rb_polling)); |
---|
| 74 | |
---|
| 75 | // Full so trying to write should fail |
---|
| 76 | assert(!libtrace_ringbuffer_try_write(&rb_block, value)); |
---|
| 77 | assert(!libtrace_ringbuffer_try_write(&rb_polling, value)); |
---|
| 78 | assert(!libtrace_ringbuffer_try_swrite(&rb_block, value)); |
---|
| 79 | assert(!libtrace_ringbuffer_try_swrite(&rb_polling, value)); |
---|
| 80 | assert(!libtrace_ringbuffer_try_swrite_bl(&rb_block, value)); |
---|
| 81 | assert(!libtrace_ringbuffer_try_swrite_bl(&rb_polling, value)); |
---|
| 82 | |
---|
| 83 | // Cycle the buffer a few times |
---|
[19135af] | 84 | for (i = NULL; i < TEST_SIZE; i++) { |
---|
[df668eb] | 85 | value = (void *) -1; |
---|
| 86 | value = libtrace_ringbuffer_read(&rb_block); |
---|
| 87 | assert(value == (void *) i); |
---|
| 88 | value = (void *) -1; |
---|
| 89 | value = libtrace_ringbuffer_read(&rb_polling); |
---|
| 90 | assert(value == (void *) i); |
---|
[19135af] | 91 | value = (void *) (i + (size_t) RINGBUFFER_SIZE); |
---|
[df668eb] | 92 | libtrace_ringbuffer_write(&rb_block, value); |
---|
| 93 | libtrace_ringbuffer_write(&rb_polling, value); |
---|
| 94 | } |
---|
| 95 | |
---|
| 96 | // Empty it completely |
---|
[19135af] | 97 | for (i = TEST_SIZE; i < TEST_SIZE + (size_t) RINGBUFFER_SIZE; i++) { |
---|
[df668eb] | 98 | value = libtrace_ringbuffer_read(&rb_block); |
---|
| 99 | assert(value == (void *) i); |
---|
| 100 | value = libtrace_ringbuffer_read(&rb_polling); |
---|
| 101 | assert(value == (void *) i); |
---|
| 102 | } |
---|
| 103 | assert(libtrace_ringbuffer_is_empty(&rb_block)); |
---|
| 104 | assert(libtrace_ringbuffer_is_empty(&rb_polling)); |
---|
| 105 | |
---|
| 106 | // Empty so trying to read should fail |
---|
| 107 | assert(!libtrace_ringbuffer_try_read(&rb_block, &value)); |
---|
| 108 | assert(!libtrace_ringbuffer_try_read(&rb_polling, &value)); |
---|
| 109 | assert(!libtrace_ringbuffer_try_sread(&rb_block, &value)); |
---|
| 110 | assert(!libtrace_ringbuffer_try_sread(&rb_polling, &value)); |
---|
| 111 | assert(!libtrace_ringbuffer_try_sread_bl(&rb_block, &value)); |
---|
| 112 | assert(!libtrace_ringbuffer_try_sread_bl(&rb_polling, &value)); |
---|
| 113 | |
---|
| 114 | // Test thread safety - We only really care about the single producer single |
---|
| 115 | // consumer case |
---|
| 116 | pthread_create(&t[0], NULL, &producer, (void *) &rb_block); |
---|
| 117 | pthread_create(&t[1], NULL, &consumer, (void *) &rb_block); |
---|
| 118 | pthread_join(t[0], NULL); |
---|
| 119 | pthread_join(t[1], NULL); |
---|
| 120 | assert(libtrace_ringbuffer_is_empty(&rb_block)); |
---|
| 121 | |
---|
| 122 | pthread_create(&t[0], NULL, &producer, (void *) &rb_polling); |
---|
| 123 | pthread_create(&t[1], NULL, &consumer, (void *) &rb_polling); |
---|
| 124 | pthread_join(t[0], NULL); |
---|
| 125 | pthread_join(t[1], NULL); |
---|
| 126 | assert(libtrace_ringbuffer_is_empty(&rb_polling)); |
---|
| 127 | |
---|
[a49a9eb] | 128 | pthread_create(&t[0], NULL, &producer_bulk, (void *) &rb_block); |
---|
| 129 | pthread_create(&t[1], NULL, &consumer_bulk, (void *) &rb_block); |
---|
| 130 | pthread_join(t[0], NULL); |
---|
| 131 | pthread_join(t[1], NULL); |
---|
| 132 | assert(libtrace_ringbuffer_is_empty(&rb_block)); |
---|
| 133 | |
---|
| 134 | pthread_create(&t[0], NULL, &producer_bulk, (void *) &rb_polling); |
---|
| 135 | pthread_create(&t[1], NULL, &consumer_bulk, (void *) &rb_polling); |
---|
| 136 | pthread_join(t[0], NULL); |
---|
| 137 | pthread_join(t[1], NULL); |
---|
| 138 | assert(libtrace_ringbuffer_is_empty(&rb_polling)); |
---|
| 139 | |
---|
[df668eb] | 140 | return 0; |
---|
[a49a9eb] | 141 | } |
---|