doc/examples: add bp flavor
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 22 Jun 2013 18:49:06 +0000 (14:49 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 22 Jun 2013 18:49:06 +0000 (14:49 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
.gitignore
doc/examples/Makefile.am
doc/examples/urcu-flavors/Makefile
doc/examples/urcu-flavors/Makefile.bp [new file with mode: 0644]
doc/examples/urcu-flavors/bp.c [new file with mode: 0644]

index c7381aaa2d4c5bfae4a91b0ecdcd1cd1cebd9dd8..86ad0c2f755673d64c4fc8f3d3ad9939d7bfa98b 100644 (file)
@@ -77,6 +77,7 @@ doc/examples/urcu-flavors/qsbr
 doc/examples/urcu-flavors/mb
 doc/examples/urcu-flavors/membarrier
 doc/examples/urcu-flavors/signal
+doc/examples/urcu-flavors/bp
 
 doc/examples/list/cds_list_add_rcu
 doc/examples/list/cds_list_add_tail_rcu
index f720e487d68a79173a3da264108b34526b8cc0f3..00ac7e9cc7856723fd1581e14d9e19fc366d3647 100644 (file)
@@ -8,10 +8,12 @@ dist_doc_examples_urcu_flavors_DATA = \
        urcu-flavors/Makefile.mb \
        urcu-flavors/Makefile.membarrier \
        urcu-flavors/Makefile.signal \
+       urcu-flavors/Makefile.bp \
        urcu-flavors/qsbr.c \
        urcu-flavors/mb.c \
        urcu-flavors/membarrier.c \
-       urcu-flavors/signal.c
+       urcu-flavors/signal.c \
+       urcu-flavors/bp.c
 
 dist_doc_examples_DATA = \
        dist-files/Makefile \
index db90df4c96275d63aee75481f7a05b31217b5c28..f4cc0b1b1f3733e8a2b813a36e2034d36a4b0588 100644 (file)
@@ -16,6 +16,7 @@ all:
        $(MAKE) -f Makefile.mb
        $(MAKE) -f Makefile.membarrier
        $(MAKE) -f Makefile.signal
+       $(MAKE) -f Makefile.bp
 
 .PHONY: clean
 clean:
@@ -23,3 +24,4 @@ clean:
        $(MAKE) -f Makefile.mb clean
        $(MAKE) -f Makefile.membarrier clean
        $(MAKE) -f Makefile.signal clean
+       $(MAKE) -f Makefile.bp clean
diff --git a/doc/examples/urcu-flavors/Makefile.bp b/doc/examples/urcu-flavors/Makefile.bp
new file mode 100644 (file)
index 0000000..5170f02
--- /dev/null
@@ -0,0 +1,21 @@
+# 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 = bp
+
+SOURCES = $(EXAMPLE_NAME).c
+OBJECTS = $(EXAMPLE_NAME).o
+BINARY = $(EXAMPLE_NAME)
+LIBS = -lurcu-bp
+
+include ../Makefile.examples.template
diff --git a/doc/examples/urcu-flavors/bp.c b/doc/examples/urcu-flavors/bp.c
new file mode 100644 (file)
index 0000000..64978fc
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * 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 <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <urcu-bp.h>           /* Bulletproof RCU flavor */
+#include <urcu/rculist.h>      /* List example */
+#include <urcu/compiler.h>     /* For CAA_ARRAY_SIZE */
+
+/*
+ * Example showing how to use the Bulletproof 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;
+}
+
+int main(int argc, char **argv)
+{
+       uint64_t values[] = { 42, 36, 24, };
+       unsigned int i;
+       int ret;
+       struct mynode *node, *n;
+
+       /*
+        * Notice that with the bulletproof flavor, there is no need to
+        * register/unregister RCU reader threads.
+        */
+
+       /*
+        * 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;
+       }
+
+       /*
+        * 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);
+
+               /*
+                * Using synchronize_rcu() directly for synchronization
+                * so we keep a minimal impact on the system by not
+                * spawning any call_rcu() thread. It is slower though,
+                * since there is no batching.
+                */
+               synchronize_rcu();
+               free(node);
+       }
+
+       sleep(1);
+
+end:
+       return ret;
+}
This page took 0.028004 seconds and 4 git commands to generate.