X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=urcu.c;h=1a276ce33663439b7cb128e1ab6bea147faec1ed;hb=20bf310ac72677961e55867dd64d058f77e0d7e6;hp=7e79207be6a88eaaf6d2b74c0b16b4543368a6fd;hpb=41718ff94c4a07cb5f56d68084267798e471d1b1;p=userspace-rcu.git diff --git a/urcu.c b/urcu.c index 7e79207..1a276ce 100644 --- a/urcu.c +++ b/urcu.c @@ -1,3 +1,13 @@ +/* + * urcu.c + * + * Userspace RCU library + * + * Copyright February 2009 - Mathieu Desnoyers + * + * Distributed under GPLv2 + */ + #include #include #include @@ -91,7 +101,7 @@ void wait_for_quiescent_state(int parity) /* * BUSY-LOOP. */ - while (*index->urcu_active_readers != 0) + while (index->urcu_active_readers[parity] != 0) barrier(); } /* @@ -103,13 +113,35 @@ void wait_for_quiescent_state(int parity) force_mb_all_threads(); } +static void switch_qparity(void) +{ + int prev_parity; + + /* All threads should read qparity before accessing data structure. */ + /* Write ptr before changing the qparity */ + force_mb_all_threads(); + prev_parity = switch_next_urcu_qparity(); + + /* + * Wait for previous parity to be empty of readers. + */ + wait_for_quiescent_state(prev_parity); +} + +void synchronize_rcu(void) +{ + rcu_write_lock(); + switch_qparity(); + switch_qparity(); + rcu_write_unlock(); +} + /* * Return old pointer, OK to free, no more reference exist. * Called under rcu_write_lock. */ void *urcu_publish_content(void **ptr, void *new) { - int ret, prev_parity; void *oldptr; /* @@ -124,19 +156,10 @@ void *urcu_publish_content(void **ptr, void *new) */ oldptr = *ptr; *ptr = new; - wmb(); /* Write ptr before changing the qparity */ - /* All threads should read qparity before ptr */ - force_mb_all_threads(); - prev_parity = switch_next_urcu_qparity(); - /* - * Wait for previous parity to be empty of readers. - */ - wait_for_quiescent_state(prev_parity); - /* - * Deleting old data is ok ! - */ - + switch_qparity(); + switch_qparity(); + return oldptr; } @@ -175,7 +198,7 @@ void urcu_remove_reader(pthread_t id) assert(reader_data != NULL); for (index = reader_data; index < reader_data + num_readers; index++) { - if (index->tid == id) { + if (pthread_equal(index->tid, id)) { memcpy(index, &reader_data[num_readers - 1], sizeof(struct reader_data)); reader_data[num_readers - 1].tid = 0; @@ -197,7 +220,6 @@ void urcu_register_thread(void) void urcu_unregister_thread(void) { - pthread_t self = pthread_self(); rcu_write_lock(); urcu_remove_reader(pthread_self()); rcu_write_unlock();