X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=urcu.c;h=5e2d2afff5641c57a80548c1f78469c52ccf7b09;hb=a570e118a8f9ed38d5eaebf8d21b65d2b6f5cf40;hp=8cbdef9e66b386c0b6ac175b2029e194bfe3b43f;hpb=157dca953e2510afa1d16b929472c0f682531355;p=urcu.git diff --git a/urcu.c b/urcu.c index 8cbdef9..5e2d2af 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 */ @@ -73,7 +78,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 +110,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 +139,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 +164,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 +188,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 +201,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 +211,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.