diff options
author | Matthew Wilcox <willy@linux.intel.com> | 2016-03-17 17:21:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-17 18:09:34 -0400 |
commit | 1366c37ed84b166a0fffe201154b0d3b78a3976b (patch) | |
tree | 3a688edaf09069694db90421f200568b886a4295 /tools/testing/radix-tree/rcupdate.c | |
parent | f67c07f07fca95a7f330b8bb928eabaf9fcce75d (diff) |
radix tree test harness
This code is mostly from Andrew Morton and Nick Piggin; tarball downloaded
from http://ozlabs.org/~akpm/rtth.tar.gz with sha1sum
0ce679db9ec047296b5d1ff7a1dfaa03a7bef1bd
Some small modifications were necessary to the test harness to fix the
build with the current Linux source code.
I also made minor modifications to automatically test the radix-tree.c
and radix-tree.h files that are in the current source tree, as opposed
to a copied and slightly modified version. I am sure more could be done
to tidy up the harness, as well as adding more tests.
[koct9i@gmail.com: fix compilation]
Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Cc: Shuah Khan <shuahkh@osg.samsung.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Matthew Wilcox <willy@linux.intel.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Ross Zwisler <ross.zwisler@linux.intel.com>
Cc: Hugh Dickins <hughd@google.com>
Signed-off-by: Konstantin Khlebnikov <koct9i@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'tools/testing/radix-tree/rcupdate.c')
-rw-r--r-- | tools/testing/radix-tree/rcupdate.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/tools/testing/radix-tree/rcupdate.c b/tools/testing/radix-tree/rcupdate.c new file mode 100644 index 000000000000..31a2d14225d6 --- /dev/null +++ b/tools/testing/radix-tree/rcupdate.c | |||
@@ -0,0 +1,86 @@ | |||
1 | #include <linux/rcupdate.h> | ||
2 | #include <pthread.h> | ||
3 | #include <stdio.h> | ||
4 | #include <assert.h> | ||
5 | |||
6 | static pthread_mutex_t rculock = PTHREAD_MUTEX_INITIALIZER; | ||
7 | static struct rcu_head *rcuhead_global = NULL; | ||
8 | static __thread int nr_rcuhead = 0; | ||
9 | static __thread struct rcu_head *rcuhead = NULL; | ||
10 | static __thread struct rcu_head *rcutail = NULL; | ||
11 | |||
12 | static pthread_cond_t rcu_worker_cond = PTHREAD_COND_INITIALIZER; | ||
13 | |||
14 | /* switch to urcu implementation when it is merged. */ | ||
15 | void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *head)) | ||
16 | { | ||
17 | head->func = func; | ||
18 | head->next = rcuhead; | ||
19 | rcuhead = head; | ||
20 | if (!rcutail) | ||
21 | rcutail = head; | ||
22 | nr_rcuhead++; | ||
23 | if (nr_rcuhead >= 1000) { | ||
24 | int signal = 0; | ||
25 | |||
26 | pthread_mutex_lock(&rculock); | ||
27 | if (!rcuhead_global) | ||
28 | signal = 1; | ||
29 | rcutail->next = rcuhead_global; | ||
30 | rcuhead_global = head; | ||
31 | pthread_mutex_unlock(&rculock); | ||
32 | |||
33 | nr_rcuhead = 0; | ||
34 | rcuhead = NULL; | ||
35 | rcutail = NULL; | ||
36 | |||
37 | if (signal) { | ||
38 | pthread_cond_signal(&rcu_worker_cond); | ||
39 | } | ||
40 | } | ||
41 | } | ||
42 | |||
43 | static void *rcu_worker(void *arg) | ||
44 | { | ||
45 | struct rcu_head *r; | ||
46 | |||
47 | rcupdate_thread_init(); | ||
48 | |||
49 | while (1) { | ||
50 | pthread_mutex_lock(&rculock); | ||
51 | while (!rcuhead_global) { | ||
52 | pthread_cond_wait(&rcu_worker_cond, &rculock); | ||
53 | } | ||
54 | r = rcuhead_global; | ||
55 | rcuhead_global = NULL; | ||
56 | |||
57 | pthread_mutex_unlock(&rculock); | ||
58 | |||
59 | synchronize_rcu(); | ||
60 | |||
61 | while (r) { | ||
62 | struct rcu_head *tmp = r->next; | ||
63 | r->func(r); | ||
64 | r = tmp; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | rcupdate_thread_exit(); | ||
69 | |||
70 | return NULL; | ||
71 | } | ||
72 | |||
73 | static pthread_t worker_thread; | ||
74 | void rcupdate_init(void) | ||
75 | { | ||
76 | pthread_create(&worker_thread, NULL, rcu_worker, NULL); | ||
77 | } | ||
78 | |||
79 | void rcupdate_thread_init(void) | ||
80 | { | ||
81 | rcu_register_thread(); | ||
82 | } | ||
83 | void rcupdate_thread_exit(void) | ||
84 | { | ||
85 | rcu_unregister_thread(); | ||
86 | } | ||