source: test/test-datastruct-ringbuffer.c @ 0af3a4e

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivelibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 0af3a4e was a49a9eb, checked in by Richard Sanger <rsangerarj@…>, 7 years ago

Add an object cache with thread local caches
All packets used by a trace are put through this.
Adds bulk read/write operations to the ringbuffer (used by the object cache)
Replace semaphores with condition variables to support these bulk operations.
Internally use bulk read operations from a single threaded formats to reduce lock overhead.
Replaces the asserts around pthread_* functions with a version that will still run the command if NDEBUG

  • Property mode set to 100644
File size: 4.5 KB
Line 
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
8static 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
17static 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
28static 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
37static 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 */
54int 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}
Note: See TracBrowser for help on using the repository browser.