-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstress.c
144 lines (120 loc) · 2.64 KB
/
stress.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#define _XOPEN_SOURCE 600
#include <assert.h>
#include <limits.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include "ringbuf.h"
struct ringbuf *rb;
uint32_t seed;
#define MSG_MAX_LEN 255
/* Taken from hash-prospector */
static uint32_t
hash32 (uint32_t x)
{
x ^= x >> 16;
x *= UINT32_C(0x7feb352d);
x ^= x >> 15;
x *= UINT32_C(0x846ca68b);
x ^= x >> 16;
return x;
}
/* Simple xor-shift fake random as random() is too slow. */
static uint32_t
fast_rand_32 ()
{
seed = hash32(seed);
return seed;
}
/* Return the number of bytes the message contains. */
size_t
msg_gen (uint8_t *buf, size_t buf_size)
{
size_t i = 0;
uint8_t cksum = 0;
size_t size = (buf_size < MSG_MAX_LEN) ? buf_size : MSG_MAX_LEN;
size = fast_rand_32() % (size-2);
buf[i] = size;
while (size > 0) {
buf[++i] = fast_rand_32();
cksum ^= buf[i];
--size;
}
buf[++i] = cksum;
return buf[0] + 2;
}
/* Return the number of bytes to advance in the buffer.
* Return 0 indicates the message in incomplete. */
size_t
msg_verify (uint8_t *buf, size_t buf_size)
{
size_t i = 0;
uint8_t cksum = 0;
if (buf_size < 2)
return 0;
size_t size = buf[i];
if (buf_size < size + 2)
return 0;
while (size > 0) {
cksum ^= buf[++i];
--size;
}
assert(buf[++i] == cksum);
return buf[0] + 2;
}
void *
stress_read (void *arg)
{
size_t num_msgs = *(size_t*)arg;
uint8_t buf[MSG_MAX_LEN];
size_t advance = 0;
size_t read = 0;
while (num_msgs > 0) {
read += ringbuf_read(rb, buf+read, MSG_MAX_LEN-read);
advance = msg_verify(buf, read);
if (advance != 0)
--num_msgs;
read -= advance;
memmove(buf, buf+advance, read);
// assert we make progress
if (read == MSG_MAX_LEN)
assert(advance != 0);
}
return NULL;
}
void *
stress_write (void *arg)
{
size_t i;
size_t num_msgs = *(size_t*)arg;
uint8_t buf[MSG_MAX_LEN];
for (i = 0; i < num_msgs; ++i) {
size_t written = 0;
size_t size = msg_gen(buf, MSG_MAX_LEN);
while (written < size)
written += ringbuf_write(rb, buf+written, size-written);
}
return NULL;
}
int
main (void)
{
size_t i;
size_t size;
size_t num_msgs;
pthread_t thread_read;
pthread_t thread_write;
seed = random();
for (i = 1; i < 32; i*=2) {
size = 1024 * i;
num_msgs = size * 1024;
rb = ringbuf_new(size);
printf("Stress test ringbuf size %zu, number of messages %zu\n", size, num_msgs);
assert(pthread_create(&thread_write, NULL, stress_write, &num_msgs) == 0);
assert(pthread_create(&thread_read, NULL, stress_read, &num_msgs) == 0);
assert(pthread_join(thread_write, NULL) == 0);
assert(pthread_join(thread_read, NULL) == 0);
ringbuf_free(rb);
}
return 0;
}