X-Git-Url: http://git.liburcu.org/?p=urcu.git;a=blobdiff_plain;f=urcu.c;h=475bebf526dfd1b9cc8cf78b87d8804ded7a1b6f;hp=8cbdef9e66b386c0b6ac175b2029e194bfe3b43f;hb=2d6debff95ad695255d2ea9d590d1e418590b238;hpb=157dca953e2510afa1d16b929472c0f682531355 diff --git a/urcu.c b/urcu.c index 8cbdef9..475bebf 100644 --- a/urcu.c +++ b/urcu.c @@ -23,9 +23,14 @@ pthread_mutex_t urcu_mutex = PTHREAD_MUTEX_INITIALIZER; * Global grace period counter. * Contains the current RCU_GP_CTR_BIT. * Also has a RCU_GP_CTR_BIT of 1, to accelerate the reader fast path. + * Written to only by writer with mutex taken. Read by both writer and readers. */ long urcu_gp_ctr = RCU_GP_COUNT; +/* + * Written to only by each individual reader. Read by both the reader and the + * writers. + */ long __thread urcu_active_readers; /* Thread IDs of registered readers */ @@ -49,12 +54,17 @@ static int sig_done; void internal_urcu_lock(void) { +#if 0 int ret; + /* Mutex sleeping does not play well with busy-waiting loop. */ ret = pthread_mutex_lock(&urcu_mutex); if (ret) { perror("Error in pthread mutex lock"); exit(-1); } +#endif + while (pthread_mutex_trylock(&urcu_mutex) != 0) + cpu_relax(); } void internal_urcu_unlock(void) @@ -73,7 +83,7 @@ void internal_urcu_unlock(void) */ static void switch_next_urcu_qparity(void) { - urcu_gp_ctr ^= RCU_GP_CTR_BIT; + STORE_SHARED(urcu_gp_ctr, urcu_gp_ctr ^ RCU_GP_CTR_BIT); } #ifdef DEBUG_FULL_MB @@ -105,7 +115,7 @@ static void force_mb_single_thread(pthread_t tid) * Wait for sighandler (and thus mb()) to execute on every thread. * BUSY-LOOP. */ - while (LOAD_REMOTE(sig_done) < 1) + while (LOAD_SHARED(sig_done) < 1) cpu_relax(); smp_mb(); /* read sig_done before ending the barrier */ } @@ -134,7 +144,7 @@ static void force_mb_all_threads(void) * Wait for sighandler (and thus mb()) to execute on every thread. * BUSY-LOOP. */ - while (LOAD_REMOTE(sig_done) < num_readers) + while (LOAD_SHARED(sig_done) < num_readers) cpu_relax(); smp_mb(); /* read sig_done before ending the barrier */ } @@ -159,6 +169,8 @@ void wait_for_quiescent_state(void) if (wait_loops++ == KICK_READER_LOOPS) { force_mb_single_thread(index->tid); wait_loops = 0; + } else { + cpu_relax(); } } } @@ -181,8 +193,8 @@ void synchronize_rcu(void) * 0 quiescent state. Failure to do so could result in the writer * waiting forever while new readers are always accessing data (no * progress). + * Ensured by STORE_SHARED and LOAD_SHARED. */ - smp_mc(); /* * Wait for previous parity to be empty of readers. @@ -194,8 +206,8 @@ void synchronize_rcu(void) * committing qparity update to memory. Failure to do so could result in * the writer waiting forever while new readers are always accessing * data (no progress). + * Ensured by STORE_SHARED and LOAD_SHARED. */ - smp_mc(); switch_next_urcu_qparity(); /* 1 -> 0 */ @@ -204,8 +216,8 @@ void synchronize_rcu(void) * 1 quiescent state. Failure to do so could result in the writer * waiting forever while new readers are always accessing data (no * progress). + * Ensured by STORE_SHARED and LOAD_SHARED. */ - smp_mc(); /* * Wait for previous parity to be empty of readers.