-
Notifications
You must be signed in to change notification settings - Fork 80
/
test.c
97 lines (70 loc) · 1.85 KB
/
test.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
/* A benchmark of thread-rcu linked list */
#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "rculist.h"
struct test {
int count;
struct list_head node;
};
static struct list_head head;
static struct test *test_alloc(int val)
{
struct test *new = (struct test *) malloc(sizeof(struct test));
if (!new) {
fprintf(stderr, "test_alloc failed\n");
abort();
}
new->count = val;
list_init_rcu(&new->node);
return new;
}
static void *reader_side(void *argv)
{
struct test __allow_unused *tmp;
rcu_init();
rcu_read_lock();
list_for_each_entry_rcu(tmp, &head, node) {}
rcu_read_unlock();
pthread_exit(NULL);
}
static void *updater_side(void *argv)
{
struct test *newval = test_alloc(current_tid());
list_add_tail_rcu(&newval->node, &head);
synchronize_rcu();
pthread_exit(NULL);
}
static inline void benchmark(void)
{
pthread_t reader[READER_NUM];
pthread_t updater[UPDATER_NUM];
struct list_head *node, *pos;
struct test *tmp;
int i;
list_init_rcu(&head);
for (i = 0; i < READER_NUM / 2; i++)
pthread_create(&reader[i], NULL, reader_side, NULL);
for (i = 0; i < UPDATER_NUM; i++)
pthread_create(&updater[i], NULL, updater_side, NULL);
for (i = READER_NUM / 2; i < READER_NUM; i++)
pthread_create(&reader[i], NULL, reader_side, NULL);
for (i = 0; i < READER_NUM; i++)
pthread_join(reader[i], NULL);
for (i = 0; i < UPDATER_NUM; i++)
pthread_join(updater[i], NULL);
list_for_each_safe (pos, node, &head) {
tmp = container_of(pos, struct test, node);
free(tmp);
}
list_init_rcu(&head);
rcu_clean();
}
#include "tracer.h"
int main(int argc, char *argv[])
{
time_check_loop(benchmark(), TRACE_LOOP);
return 0;
}