* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
-#include <urcu-qsbr.h> /* QSBR RCU flavor */
+#include <urcu/urcu-qsbr.h> /* QSBR RCU flavor */
#include <urcu/rculist.h> /* List example */
#include <urcu/compiler.h> /* For CAA_ARRAY_SIZE */
* Each thread need using RCU read-side need to be explicitly
* registered.
*/
- rcu_register_thread();
+ urcu_qsbr_register_thread();
/*
* Adding nodes to the linked-list. Safe against concurrent
goto end;
}
- /*
- * For all RCU flavors except QSBR, we need to explicitly mark
- * RCU read-side critical sections with rcu_read_lock() and
- * rcu_read_unlock(). They can be nested. Those are no-ops for
- * the QSBR flavor.
- */
- rcu_read_lock();
-
/*
* RCU traversal of the linked list.
*/
cds_list_for_each_entry_rcu(node, &mylist, node) {
printf("Value: %" PRIu64 "\n", node->value);
}
- rcu_read_unlock();
/*
* Removing nodes from linked list. Safe against concurrent RCU
*/
cds_list_for_each_entry_safe(node, n, &mylist, node) {
cds_list_del_rcu(&node->node);
- call_rcu(&node->rcu_head, rcu_free_node);
+ /*
+ * call_rcu() will ensure that the handler
+ * "rcu_free_node" is executed after a grace period.
+ * call_rcu() can be called from RCU read-side critical
+ * sections.
+ */
+ urcu_qsbr_call_rcu(&node->rcu_head, rcu_free_node);
}
/*
* every online registered RCU threads in the program
* periodically.
*/
- rcu_quiescent_state();
+ urcu_qsbr_quiescent_state();
/*
* For QSBR flavor, when a thread needs to be in a quiescent
* state for a long period of time, we use rcu_thread_offline()
* and rcu_thread_online().
*/
- rcu_thread_offline();
+ urcu_qsbr_thread_offline();
sleep(1);
- rcu_thread_online();
+ urcu_qsbr_thread_online();
+
+ /*
+ * We can also wait for a quiescent state by calling
+ * synchronize_rcu() rather than using call_rcu(). It is usually
+ * a slower approach than call_rcu(), because the latter can
+ * batch work. Moreover, call_rcu() can be called from a RCU
+ * read-side critical section, but synchronize_rcu() ensures the
+ * caller thread is offline, thus acting as a quiescent state.
+ */
+ urcu_qsbr_synchronize_rcu();
/*
* Waiting for previously called call_rcu handlers to complete
* before program exits, or in library destructors, is a good
* practice.
*/
- rcu_barrier();
+ urcu_qsbr_barrier();
end:
- rcu_unregister_thread();
+ urcu_qsbr_unregister_thread();
return ret;
}