X-Git-Url: http://git.liburcu.org/?p=urcu.git;a=blobdiff_plain;f=urcu-call-rcu-impl.h;h=38cc00190f018cf1afd7fac07e42bcedec484af3;hp=8a89295fa44bcc6dc18b84e671ec42705128ff06;hb=765f3eadad5647e6fa853414fc652670f9e00966;hpb=6d841bc23fc94345fe76651d73c1a3f821a85aa7 diff --git a/urcu-call-rcu-impl.h b/urcu-call-rcu-impl.h index 8a89295..38cc001 100644 --- a/urcu-call-rcu-impl.h +++ b/urcu-call-rcu-impl.h @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -89,26 +88,6 @@ static struct call_rcu_data *default_call_rcu_data; static struct call_rcu_data **per_cpu_call_rcu_data; static long maxcpus; -static void call_rcu_wait(struct call_rcu_data *crdp) -{ - /* Read call_rcu list before read futex */ - cmm_smp_mb(); - if (uatomic_read(&crdp->futex) == -1) - futex_async(&crdp->futex, FUTEX_WAIT, -1, - NULL, NULL, 0); -} - -static void call_rcu_wake_up(struct call_rcu_data *crdp) -{ - /* Write to call_rcu list before reading/writing futex */ - cmm_smp_mb(); - if (unlikely(uatomic_read(&crdp->futex) == -1)) { - uatomic_set(&crdp->futex, 0); - futex_async(&crdp->futex, FUTEX_WAKE, 1, - NULL, NULL, 0); - } -} - /* Allocate the array if it has not already been allocated. */ static void alloc_cpu_call_rcu_data(void) @@ -136,7 +115,12 @@ static void alloc_cpu_call_rcu_data(void) #else /* #if defined(HAVE_SCHED_GETCPU) && defined(HAVE_SYSCONF) */ -static const struct call_rcu_data **per_cpu_call_rcu_data = NULL; +/* + * per_cpu_call_rcu_data should be constant, but some functions below, used both + * for cases where cpu number is available and not available, assume it it not + * constant. + */ +static struct call_rcu_data **per_cpu_call_rcu_data = NULL; static const long maxcpus = -1; static void alloc_cpu_call_rcu_data(void) @@ -195,6 +179,26 @@ int set_thread_cpu_affinity(struct call_rcu_data *crdp) } #endif +static void call_rcu_wait(struct call_rcu_data *crdp) +{ + /* Read call_rcu list before read futex */ + cmm_smp_mb(); + if (uatomic_read(&crdp->futex) == -1) + futex_async(&crdp->futex, FUTEX_WAIT, -1, + NULL, NULL, 0); +} + +static void call_rcu_wake_up(struct call_rcu_data *crdp) +{ + /* Write to call_rcu list before reading/writing futex */ + cmm_smp_mb(); + if (unlikely(uatomic_read(&crdp->futex) == -1)) { + uatomic_set(&crdp->futex, 0); + futex_async(&crdp->futex, FUTEX_WAKE, 1, + NULL, NULL, 0); + } +} + /* This is the code run by each call_rcu thread. */ static void *call_rcu_thread(void *arg) @@ -211,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); @@ -243,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)) { @@ -260,6 +270,7 @@ static void *call_rcu_thread(void *arg) } else { poll(NULL, 0, 10); } + rcu_thread_online(); } if (!rt) { /* @@ -269,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; }