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
)
92 struct test_array
*local_ptr
;
94 printf("thread_begin %s, thread id : %lx, tid %lu\n",
95 "reader", pthread_self(), (unsigned long)gettid());
97 urcu_register_thread();
100 rcu_read_lock(&qparity
);
101 local_ptr
= rcu_dereference(test_rcu_pointer
);
103 assert(local_ptr
->a
== 8);
104 rcu_read_unlock(&qparity
);
105 if (!test_duration())
109 urcu_unregister_thread();
111 printf("thread_end %s, thread id : %lx, tid %lu\n",
112 "reader", pthread_self(), (unsigned long)gettid());
117 void *thr_writer(void *arg
)
119 struct test_array
*new, *old
;
121 printf("thread_begin %s, thread id : %lx, tid %lu\n",
122 "writer", pthread_self(), (unsigned long)gettid());
125 new = malloc(sizeof(struct test_array
));
126 rcu_copy_mutex_lock();
127 old
= test_rcu_pointer
;
131 old
= urcu_publish_content((void **)&test_rcu_pointer
, new);
132 rcu_copy_mutex_unlock();
133 /* can be done after unlock */
137 if (!test_duration())
142 printf("thread_end %s, thread id : %lx, tid %lu\n",
143 "writer", pthread_self(), (unsigned long)gettid());
147 int main(int argc
, char **argv
)
150 pthread_t tid_reader
[NR_READ
], tid_writer
[NR_WRITE
];
155 printf("Usage : %s duration (s) [-r] [-w] "
156 "(yield reader and/or writer)\n", argv
[0]);
160 err
= sscanf(argv
[1], "%lu", &duration
);
162 printf("Usage : %s duration (s) [-r] [-w] "
163 "(yield reader and/or writer)\n", argv
[0]);
168 for (i
= 2; i
< argc
; i
++) {
169 if (argv
[i
][0] != '-')
171 switch (argv
[i
][1]) {
173 yield_active
|= YIELD_READ
;
176 yield_active
|= YIELD_WRITE
;
182 printf("running test for %lu seconds.\n", duration
);
183 start_time
= time(NULL
);
184 printf("thread %-6s, thread id : %lx, tid %lu\n",
185 "main", pthread_self(), (unsigned long)gettid());
187 for (i
= 0; i
< NR_READ
; i
++) {
188 err
= pthread_create(&tid_reader
[i
], NULL
, thr_reader
, NULL
);
192 for (i
= 0; i
< NR_WRITE
; i
++) {
193 err
= pthread_create(&tid_writer
[i
], NULL
, thr_writer
, NULL
);
198 for (i
= 0; i
< NR_READ
; i
++) {
199 err
= pthread_join(tid_reader
[i
], &tret
);
203 for (i
= 0; i
< NR_WRITE
; i
++) {
204 err
= pthread_join(tid_writer
[i
], &tret
);
208 free(test_rcu_pointer
);