X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=urcu-call-rcu-impl.h;h=e0a8fd883ee4a24782b3464a970f20be645b5fdc;hb=f377678692caa9f589275eae4f2774104f26a8c6;hp=b9e57cd60a2ba731a2030cd36c9b9b6c211c416e;hpb=f943709861a18d5b473d453e039ed7c433352a76;p=urcu.git diff --git a/urcu-call-rcu-impl.h b/urcu-call-rcu-impl.h index b9e57cd..e0a8fd8 100644 --- a/urcu-call-rcu-impl.h +++ b/urcu-call-rcu-impl.h @@ -215,6 +215,11 @@ static void *call_rcu_thread(void *arg) exit(-1); } + /* + * If callbacks take a read-side lock, we need to be registered. + */ + rcu_register_thread(); + thread_call_rcu_data = crdp; if (!rt) { uatomic_dec(&crdp->futex); @@ -247,6 +252,7 @@ static void *call_rcu_thread(void *arg) } if (uatomic_read(&crdp->flags) & URCU_CALL_RCU_STOP) break; + rcu_thread_offline(); if (!rt) { if (&crdp->cbs.head == _CMM_LOAD_SHARED(crdp->cbs.tail)) { @@ -264,6 +270,7 @@ static void *call_rcu_thread(void *arg) } else { poll(NULL, 0, 10); } + rcu_thread_online(); } if (!rt) { /* @@ -273,6 +280,7 @@ static void *call_rcu_thread(void *arg) uatomic_set(&crdp->futex, 0); } uatomic_or(&crdp->flags, URCU_CALL_RCU_STOPPED); + rcu_unregister_thread(); return NULL; } @@ -375,9 +383,10 @@ struct call_rcu_data *create_call_rcu_data(unsigned long flags, int set_cpu_call_rcu_data(int cpu, struct call_rcu_data *crdp) { - int warned = 0; + static int warned = 0; call_rcu_lock(&call_rcu_mutex); + alloc_cpu_call_rcu_data(); if (cpu < 0 || maxcpus <= cpu) { if (!warned) { fprintf(stderr, "[error] liburcu: set CPU # out of range\n"); @@ -387,7 +396,6 @@ int set_cpu_call_rcu_data(int cpu, struct call_rcu_data *crdp) errno = EINVAL; return -EINVAL; } - alloc_cpu_call_rcu_data(); call_rcu_unlock(&call_rcu_mutex); if (per_cpu_call_rcu_data == NULL) { errno = ENOMEM; @@ -474,7 +482,9 @@ void set_thread_call_rcu_data(struct call_rcu_data *crdp) /* * Create a separate call_rcu thread for each CPU. This does not * replace a pre-existing call_rcu thread -- use the set_cpu_call_rcu_data() - * function if you want that behavior. + * function if you want that behavior. Should be paired with + * free_all_cpu_call_rcu_data() to teardown these call_rcu worker + * threads. */ int create_all_cpu_call_rcu_data(unsigned long flags)