doc_examplesdir = ${docdir}/examples
-doc_examples_rcu_flavor_qsbrdir = ${doc_examplesdir}/rcu-flavor-qsbr
+doc_examples_urcu_flavorsdir = ${doc_examplesdir}/urcu-flavors
-dist_doc_examples_rcu_flavor_qsbr_DATA = \
- rcu-flavor-qsbr/Makefile \
- rcu-flavor-qsbr/Makefile.rcu-flavor-qsbr \
- rcu-flavor-qsbr/rcu-flavor-qsbr.c
+dist_doc_examples_urcu_flavors_DATA = \
+ urcu-flavors/Makefile \
+ urcu-flavors/Makefile.qsbr \
+ urcu-flavors/qsbr.c
dist_doc_examples_DATA = \
Makefile.examples.template
+++ /dev/null
-# Copyright (C) 2013 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
-#
-# THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
-# OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
-#
-# Permission is hereby granted to use or copy this program for any
-# purpose, provided the above notices are retained on all copies.
-# Permission to modify the code and to distribute modified code is
-# granted, provided the above notices are retained, and a notice that
-# the code was modified is included with the above copyright notice.
-#
-# This makefile is purposefully kept simple to support GNU and BSD make.
-
-all:
- $(MAKE) -f Makefile.rcu-flavor-qsbr
-
-.PHONY: clean
-clean:
- $(MAKE) -f Makefile.rcu-flavor-qsbr clean
+++ /dev/null
-# Copyright (C) 2013 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
-#
-# THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
-# OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
-#
-# Permission is hereby granted to use or copy this program for any
-# purpose, provided the above notices are retained on all copies.
-# Permission to modify the code and to distribute modified code is
-# granted, provided the above notices are retained, and a notice that
-# the code was modified is included with the above copyright notice.
-#
-# This makefile is purposefully kept simple to support GNU and BSD make.
-
-EXAMPLE_NAME = rcu-flavor-qsbr
-
-SOURCES = $(EXAMPLE_NAME).c
-OBJECTS = $(EXAMPLE_NAME).o
-BINARY = $(EXAMPLE_NAME)
-LIBS = -lurcu-qsbr
-
-include ../Makefile.examples.template
+++ /dev/null
-/*
- * Copyright (C) 2013 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <inttypes.h>
-
-#include <urcu-qsbr.h> /* QSBR RCU flavor */
-#include <urcu/rculist.h> /* List example */
-#include <urcu/compiler.h> /* For CAA_ARRAY_SIZE */
-
-/*
- * This is a mock-up example where updates and RCU traversals are
- * performed by the same thread to keep things simple on purpose.
- */
-
-static CDS_LIST_HEAD(mylist);
-
-struct mynode {
- uint64_t value;
- struct cds_list_head node; /* linked-list chaining */
- struct rcu_head rcu_head; /* for call_rcu() */
-};
-
-static
-int add_node(uint64_t v)
-{
- struct mynode *node;
-
- node = calloc(sizeof(*node), 1);
- if (!node)
- return -1;
- node->value = v;
- cds_list_add_rcu(&node->node, &mylist);
- return 0;
-}
-
-static
-void rcu_free_node(struct rcu_head *rh)
-{
- struct mynode *node = caa_container_of(rh, struct mynode, rcu_head);
-
- free(node);
-}
-
-int main(int argc, char **argv)
-{
- uint64_t values[] = { 42, 36, 24, };
- unsigned int i;
- int ret;
- struct mynode *node, *n;
-
- /*
- * Each thread need using RCU read-side need to be explicitly
- * registered.
- */
- rcu_register_thread();
-
- /*
- * Adding nodes to the linked-list. Safe against concurrent
- * RCU traversals, require mutual exclusion with list updates.
- */
- for (i = 0; i < CAA_ARRAY_SIZE(values); i++) {
- ret = add_node(values[i]);
- if (ret)
- 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
- * traversals, require mutual exclusion with list updates.
- */
- cds_list_for_each_entry_safe(node, n, &mylist, node) {
- cds_list_del_rcu(&node->node);
- call_rcu(&node->rcu_head, rcu_free_node);
- }
-
- /*
- * For QSBR flavor, we need to explicitly announce quiescent
- * states. Here is how it is done. This should be performed by
- * every online registered RCU threads in the program
- * periodically.
- */
- rcu_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();
-
- sleep(1);
-
- rcu_thread_online();
-
- /*
- * Waiting for previously called call_rcu handlers to complete
- * before program exits, or in library destructors, is a good
- * practice.
- */
- rcu_barrier();
-
-end:
- rcu_unregister_thread();
- return ret;
-}
--- /dev/null
+# Copyright (C) 2013 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+#
+# THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
+# OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+#
+# Permission is hereby granted to use or copy this program for any
+# purpose, provided the above notices are retained on all copies.
+# Permission to modify the code and to distribute modified code is
+# granted, provided the above notices are retained, and a notice that
+# the code was modified is included with the above copyright notice.
+#
+# This makefile is purposefully kept simple to support GNU and BSD make.
+
+all:
+ $(MAKE) -f Makefile.qsbr
+
+.PHONY: clean
+clean:
+ $(MAKE) -f Makefile.qsbr clean
--- /dev/null
+# Copyright (C) 2013 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+#
+# THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
+# OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+#
+# Permission is hereby granted to use or copy this program for any
+# purpose, provided the above notices are retained on all copies.
+# Permission to modify the code and to distribute modified code is
+# granted, provided the above notices are retained, and a notice that
+# the code was modified is included with the above copyright notice.
+#
+# This makefile is purposefully kept simple to support GNU and BSD make.
+
+EXAMPLE_NAME = qsbr
+
+SOURCES = $(EXAMPLE_NAME).c
+OBJECTS = $(EXAMPLE_NAME).o
+BINARY = $(EXAMPLE_NAME)
+LIBS = -lurcu-qsbr
+
+include ../Makefile.examples.template
--- /dev/null
+/*
+ * Copyright (C) 2013 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <urcu-qsbr.h> /* QSBR RCU flavor */
+#include <urcu/rculist.h> /* List example */
+#include <urcu/compiler.h> /* For CAA_ARRAY_SIZE */
+
+/*
+ * Example showing how to use the QSBR Userspace RCU flavor.
+ *
+ * This is a mock-up example where updates and RCU traversals are
+ * performed by the same thread to keep things simple on purpose.
+ */
+
+static CDS_LIST_HEAD(mylist);
+
+struct mynode {
+ uint64_t value;
+ struct cds_list_head node; /* linked-list chaining */
+ struct rcu_head rcu_head; /* for call_rcu() */
+};
+
+static
+int add_node(uint64_t v)
+{
+ struct mynode *node;
+
+ node = calloc(sizeof(*node), 1);
+ if (!node)
+ return -1;
+ node->value = v;
+ cds_list_add_rcu(&node->node, &mylist);
+ return 0;
+}
+
+static
+void rcu_free_node(struct rcu_head *rh)
+{
+ struct mynode *node = caa_container_of(rh, struct mynode, rcu_head);
+
+ free(node);
+}
+
+int main(int argc, char **argv)
+{
+ uint64_t values[] = { 42, 36, 24, };
+ unsigned int i;
+ int ret;
+ struct mynode *node, *n;
+
+ /*
+ * Each thread need using RCU read-side need to be explicitly
+ * registered.
+ */
+ rcu_register_thread();
+
+ /*
+ * Adding nodes to the linked-list. Safe against concurrent
+ * RCU traversals, require mutual exclusion with list updates.
+ */
+ for (i = 0; i < CAA_ARRAY_SIZE(values); i++) {
+ ret = add_node(values[i]);
+ if (ret)
+ 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
+ * traversals, require mutual exclusion with list updates.
+ */
+ cds_list_for_each_entry_safe(node, n, &mylist, node) {
+ cds_list_del_rcu(&node->node);
+ call_rcu(&node->rcu_head, rcu_free_node);
+ }
+
+ /*
+ * For QSBR flavor, we need to explicitly announce quiescent
+ * states. Here is how it is done. This should be performed by
+ * every online registered RCU threads in the program
+ * periodically.
+ */
+ rcu_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();
+
+ sleep(1);
+
+ rcu_thread_online();
+
+ /*
+ * Waiting for previously called call_rcu handlers to complete
+ * before program exits, or in library destructors, is a good
+ * practice.
+ */
+ rcu_barrier();
+
+end:
+ rcu_unregister_thread();
+ return ret;
+}