1 | #include "data-struct/ring_buffer.h" |
---|
2 | #include <pthread.h> |
---|
3 | #include <assert.h> |
---|
4 | |
---|
5 | #define TEST_SIZE ((char *) 1000000) |
---|
6 | #define RINGBUFFER_SIZE ((char *) 10000) |
---|
7 | |
---|
8 | static void * producer(void * a) { |
---|
9 | libtrace_ringbuffer_t * rb = (libtrace_ringbuffer_t *) a; |
---|
10 | char * i; |
---|
11 | for (i = NULL; i < TEST_SIZE; i++) { |
---|
12 | libtrace_ringbuffer_write(rb, i); |
---|
13 | } |
---|
14 | return 0; |
---|
15 | } |
---|
16 | |
---|
17 | static void * consumer(void * a) { |
---|
18 | libtrace_ringbuffer_t * rb = (libtrace_ringbuffer_t *) a; |
---|
19 | char *i; |
---|
20 | void *value; |
---|
21 | for (i = NULL; i < TEST_SIZE; i++) { |
---|
22 | value = libtrace_ringbuffer_read(rb); |
---|
23 | assert(value == i); |
---|
24 | } |
---|
25 | return 0; |
---|
26 | } |
---|
27 | |
---|
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 | |
---|
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() { |
---|
55 | char *i; |
---|
56 | void *value; |
---|
57 | pthread_t t[4]; |
---|
58 | libtrace_ringbuffer_t rb_block; |
---|
59 | libtrace_ringbuffer_t rb_polling; |
---|
60 | |
---|
61 | libtrace_ringbuffer_init(&rb_block, (size_t) RINGBUFFER_SIZE, LIBTRACE_RINGBUFFER_BLOCKING); |
---|
62 | libtrace_ringbuffer_init(&rb_polling, (size_t) RINGBUFFER_SIZE, LIBTRACE_RINGBUFFER_POLLING); |
---|
63 | assert(libtrace_ringbuffer_is_empty(&rb_block)); |
---|
64 | assert(libtrace_ringbuffer_is_empty(&rb_polling)); |
---|
65 | |
---|
66 | for (i = NULL; i < RINGBUFFER_SIZE; i++) { |
---|
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 |
---|
84 | for (i = NULL; i < TEST_SIZE; i++) { |
---|
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); |
---|
91 | value = (void *) (i + (size_t) RINGBUFFER_SIZE); |
---|
92 | libtrace_ringbuffer_write(&rb_block, value); |
---|
93 | libtrace_ringbuffer_write(&rb_polling, value); |
---|
94 | } |
---|
95 | |
---|
96 | // Empty it completely |
---|
97 | for (i = TEST_SIZE; i < TEST_SIZE + (size_t) RINGBUFFER_SIZE; i++) { |
---|
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 | |
---|
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 | |
---|
140 | return 0; |
---|
141 | } |
---|