4 * Userspace RCU library - test program
6 * Copyright February 2009 - Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
8 * Distributed under GPLv2
15 #include <sys/types.h>
20 #include <sys/syscall.h>
22 #if defined(_syscall0)
23 _syscall0(pid_t
, gettid
)
24 #elif defined(__NR_gettid)
25 static inline pid_t
gettid(void)
27 return syscall(__NR_gettid
);
30 #warning "use pid as tid"
31 static inline pid_t
gettid(void)
43 static struct test_array
*test_rcu_pointer
;
45 static unsigned long duration
;
46 static time_t start_time
;
47 static unsigned long __thread duration_interval
;
48 #define DURATION_TEST_DELAY 100
51 * returns 0 if test should end.
53 static int test_duration(void)
55 if (duration_interval
++ >= DURATION_TEST_DELAY
) {
56 duration_interval
= 0;
57 if (time(NULL
) - start_time
>= duration
)
66 pthread_mutex_t rcu_copy_mutex
= PTHREAD_MUTEX_INITIALIZER
;
68 void rcu_copy_mutex_lock(void)
71 ret
= pthread_mutex_lock(&rcu_copy_mutex
);
73 perror("Error in pthread mutex lock");
78 void rcu_copy_mutex_unlock(void)
82 ret
= pthread_mutex_unlock(&rcu_copy_mutex
);
84 perror("Error in pthread mutex unlock");
89 void *thr_reader(void *arg
)
91 struct test_array
*local_ptr
;
93 printf("thread_begin %s, thread id : %lx, tid %lu\n",
94 "reader", pthread_self(), (unsigned long)gettid());
96 urcu_register_thread();
100 local_ptr
= rcu_dereference(test_rcu_pointer
);
102 assert(local_ptr
->a
== 8);
104 if (!test_duration())
108 urcu_unregister_thread();
110 printf("thread_end %s, thread id : %lx, tid %lu\n",
111 "reader", pthread_self(), (unsigned long)gettid());
116 void *thr_writer(void *arg
)
118 struct test_array
*new, *old
;
120 printf("thread_begin %s, thread id : %lx, tid %lu\n",
121 "writer", pthread_self(), (unsigned long)gettid());
124 new = malloc(sizeof(struct test_array
));
125 rcu_copy_mutex_lock();
126 old
= test_rcu_pointer
;
130 old
= urcu_publish_content(&test_rcu_pointer
, new);
131 rcu_copy_mutex_unlock();
132 /* can be done after unlock */
136 if (!test_duration())
141 printf("thread_end %s, thread id : %lx, tid %lu\n",
142 "writer", pthread_self(), (unsigned long)gettid());
146 void show_usage(int argc
, char **argv
)
148 printf("Usage : %s duration (s)", argv
[0]);
150 printf(" [-r] [-w] (yield reader and/or writer)");
155 int main(int argc
, char **argv
)
158 pthread_t tid_reader
[NR_READ
], tid_writer
[NR_WRITE
];
163 show_usage(argc
, argv
);
167 err
= sscanf(argv
[1], "%lu", &duration
);
169 show_usage(argc
, argv
);
174 for (i
= 2; i
< argc
; i
++) {
175 if (argv
[i
][0] != '-')
177 switch (argv
[i
][1]) {
179 yield_active
|= YIELD_READ
;
182 yield_active
|= YIELD_WRITE
;
188 printf("running test for %lu seconds.\n", duration
);
189 start_time
= time(NULL
);
190 printf("thread %-6s, thread id : %lx, tid %lu\n",
191 "main", pthread_self(), (unsigned long)gettid());
193 for (i
= 0; i
< NR_READ
; i
++) {
194 err
= pthread_create(&tid_reader
[i
], NULL
, thr_reader
, NULL
);
198 for (i
= 0; i
< NR_WRITE
; i
++) {
199 err
= pthread_create(&tid_writer
[i
], NULL
, thr_writer
, NULL
);
204 for (i
= 0; i
< NR_READ
; i
++) {
205 err
= pthread_join(tid_reader
[i
], &tret
);
209 for (i
= 0; i
< NR_WRITE
; i
++) {
210 err
= pthread_join(tid_writer
[i
], &tret
);
214 free(test_rcu_pointer
);