tests: improve RCU test
Now tests synchronize_rcu()
#include <runtime/rcu.h>
#define N 1000000
-#define NCORES 4
+#define NTHREADS 100
#define FIRST_VAL 0x1000000
#define SECOND_VAL 0x2000000
@@ -52,39 +52,65 @@ static void read_handler(void *arg)
waitgroup_done(wg_parent);
}
+static void spawn_rcu_readers(waitgroup_t *wg, int readers)
+{
+ int ret, i;
+
+ log_info("creating %d threads to read an RCU object.", readers);
+
+ waitgroup_add(wg, readers);
+ for (i = 0; i < readers; i++) {
+ ret = thread_spawn(read_handler, wg);
+ BUG_ON(ret);
+ }
+
+ thread_yield();
+}
+
static void main_handler(void *arg)
{
struct test_obj *o, *o2;
waitgroup_t wg;
- int i, ret;
log_info("started main_handler() thread");
waitgroup_init(&release_wg);
waitgroup_add(&release_wg, 1);
+ waitgroup_init(&wg);
+
o = malloc(sizeof(*o));
BUG_ON(!o);
o->foo = FIRST_VAL;
RCU_INIT_POINTER(test_ptr, o);
- log_info("creating threads to read RCU object.");
-
- waitgroup_init(&wg);
- waitgroup_add(&wg, NCORES);
- for (i = 0; i < NCORES; i++) {
- ret = thread_spawn(read_handler, &wg);
- BUG_ON(ret);
- }
-
- thread_yield();
+ /* test rcu_free() */
+ log_info("testing rcu_free()...");
+ spawn_rcu_readers(&wg, NTHREADS);
o2 = malloc(sizeof(*o));
o2->foo = SECOND_VAL;
rcu_assign_pointer(test_ptr, o2);
rcu_free(&o->rcu, test_release);
-
waitgroup_wait(&wg);
log_info("readers finished.");
waitgroup_wait(&release_wg);
log_info("RCU release finished.");
+
+ free(o2);
+ o = malloc(sizeof(*o));
+ BUG_ON(!o);
+ o->foo = FIRST_VAL;
+ RCU_INIT_POINTER(test_ptr, o);
+
+ /* test synchronize_rcu() */
+ log_info("testing synchronize_rcu()...");
+ spawn_rcu_readers(&wg, NTHREADS);
+ o2 = malloc(sizeof(*o));
+ o2->foo = SECOND_VAL;
+ rcu_assign_pointer(test_ptr, o2);
+ synchronize_rcu();
+ o->foo = FIRST_VAL;
+ free(o);
+ waitgroup_wait(&wg);
+ log_info("readers finished.");
}
int main(int argc, char *argv[])
