doc/examples: hlist
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 22 Jun 2013 16:06:00 +0000 (12:06 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 22 Jun 2013 16:07:13 +0000 (12:07 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
.gitignore
doc/examples/Makefile.am
doc/examples/hlist/Makefile [new file with mode: 0644]
doc/examples/hlist/Makefile.cds_hlist_add_head_rcu [new file with mode: 0644]
doc/examples/hlist/Makefile.cds_hlist_del_rcu [new file with mode: 0644]
doc/examples/hlist/Makefile.cds_hlist_for_each_entry_rcu [new file with mode: 0644]
doc/examples/hlist/Makefile.cds_hlist_for_each_rcu [new file with mode: 0644]
doc/examples/hlist/cds_hlist_add_head_rcu.c [new file with mode: 0644]
doc/examples/hlist/cds_hlist_del_rcu.c [new file with mode: 0644]
doc/examples/hlist/cds_hlist_for_each_entry_rcu.c [new file with mode: 0644]
doc/examples/hlist/cds_hlist_for_each_rcu.c [new file with mode: 0644]

index 58c9ba338fa79842f8193d6d38c6c9b26521f007..f9ab3279760936cdca05cb85b14dd45995b233bb 100644 (file)
@@ -82,6 +82,11 @@ doc/examples/list/cds_list_for_each_rcu
 doc/examples/list/cds_list_for_each_entry_rcu
 doc/examples/list/cds_list_replace_rcu
 
+doc/examples/hlist/cds_hlist_add_head_rcu
+doc/examples/hlist/cds_hlist_del_rcu
+doc/examples/hlist/cds_hlist_for_each_rcu
+doc/examples/hlist/cds_hlist_for_each_entry_rcu
+
 doc/examples/wfcqueue/cds_wfcq_enqueue
 doc/examples/wfcqueue/cds_wfcq_dequeue
 doc/examples/wfcqueue/cds_wfcq_splice
index 9471957f879ae613e7853b9d3f54c87b3d2091d9..d516bb6b1a51b5c74bdd49f52698df5e2779911c 100644 (file)
@@ -26,6 +26,19 @@ dist_doc_examples_list_DATA = \
        list/cds_list_for_each_entry_rcu.c \
        list/cds_list_replace_rcu.c
 
+doc_examples_hlistdir = ${doc_examplesdir}/hlist
+
+dist_doc_examples_hlist_DATA = \
+       hlist/Makefile \
+       hlist/Makefile.cds_hlist_add_head_rcu \
+       hlist/Makefile.cds_hlist_del_rcu \
+       hlist/Makefile.cds_hlist_for_each_rcu \
+       hlist/Makefile.cds_hlist_for_each_entry_rcu \
+       hlist/cds_hlist_add_head_rcu.c \
+       hlist/cds_hlist_del_rcu.c \
+       hlist/cds_hlist_for_each_rcu.c \
+       hlist/cds_hlist_for_each_entry_rcu.c
+
 doc_examples_wfcqueuedir = ${doc_examplesdir}/wfcqueue
 
 dist_doc_examples_wfcqueue_DATA = \
@@ -63,7 +76,7 @@ if NO_SHARED
 # Don't build examples if shared libraries support was explicitly
 # disabled.
 else
-SUBDIRS_PROXY = qsbr-minimal list wfcqueue wfstack
+SUBDIRS_PROXY = qsbr-minimal list hlist wfcqueue wfstack lfstack
 
 all-local:
        for subdir in $(SUBDIRS_PROXY); do \
diff --git a/doc/examples/hlist/Makefile b/doc/examples/hlist/Makefile
new file mode 100644 (file)
index 0000000..d705dac
--- /dev/null
@@ -0,0 +1,25 @@
+# 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.cds_hlist_add_head_rcu
+       $(MAKE) -f Makefile.cds_hlist_del_rcu
+       $(MAKE) -f Makefile.cds_hlist_for_each_rcu
+       $(MAKE) -f Makefile.cds_hlist_for_each_entry_rcu
+
+.PHONY: clean
+clean:
+       $(MAKE) -f Makefile.cds_hlist_add_head_rcu clean
+       $(MAKE) -f Makefile.cds_hlist_del_rcu clean
+       $(MAKE) -f Makefile.cds_hlist_for_each_rcu clean
+       $(MAKE) -f Makefile.cds_hlist_for_each_entry_rcu clean
diff --git a/doc/examples/hlist/Makefile.cds_hlist_add_head_rcu b/doc/examples/hlist/Makefile.cds_hlist_add_head_rcu
new file mode 100644 (file)
index 0000000..f1bf7d7
--- /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 = cds_hlist_add_head_rcu
+
+SOURCES = $(EXAMPLE_NAME).c
+OBJECTS = $(EXAMPLE_NAME).o
+BINARY = $(EXAMPLE_NAME)
+LIBS = -lurcu
+
+include ../Makefile.examples.template
diff --git a/doc/examples/hlist/Makefile.cds_hlist_del_rcu b/doc/examples/hlist/Makefile.cds_hlist_del_rcu
new file mode 100644 (file)
index 0000000..642b04d
--- /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 = cds_hlist_del_rcu
+
+SOURCES = $(EXAMPLE_NAME).c
+OBJECTS = $(EXAMPLE_NAME).o
+BINARY = $(EXAMPLE_NAME)
+LIBS = -lurcu
+
+include ../Makefile.examples.template
diff --git a/doc/examples/hlist/Makefile.cds_hlist_for_each_entry_rcu b/doc/examples/hlist/Makefile.cds_hlist_for_each_entry_rcu
new file mode 100644 (file)
index 0000000..035ecbf
--- /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 = cds_hlist_for_each_entry_rcu
+
+SOURCES = $(EXAMPLE_NAME).c
+OBJECTS = $(EXAMPLE_NAME).o
+BINARY = $(EXAMPLE_NAME)
+LIBS = -lurcu
+
+include ../Makefile.examples.template
diff --git a/doc/examples/hlist/Makefile.cds_hlist_for_each_rcu b/doc/examples/hlist/Makefile.cds_hlist_for_each_rcu
new file mode 100644 (file)
index 0000000..23d0a0c
--- /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 = cds_hlist_for_each_rcu
+
+SOURCES = $(EXAMPLE_NAME).c
+OBJECTS = $(EXAMPLE_NAME).o
+BINARY = $(EXAMPLE_NAME)
+LIBS = -lurcu
+
+include ../Makefile.examples.template
diff --git a/doc/examples/hlist/cds_hlist_add_head_rcu.c b/doc/examples/hlist/cds_hlist_add_head_rcu.c
new file mode 100644 (file)
index 0000000..12161d1
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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 example shows how to add into a non-circular linked-list safely
+ * against concurrent RCU traversals.
+ */
+
+#include <stdio.h>
+
+#include <urcu.h>              /* Userspace RCU flavor */
+#include <urcu/rcuhlist.h>     /* RCU hlist */
+#include <urcu/compiler.h>     /* For CAA_ARRAY_SIZE */
+
+/*
+ * Nodes populated into the list.
+ */
+struct mynode {
+       int value;                      /* Node content */
+       struct cds_hlist_node node;     /* Linked-list chaining */
+};
+
+int main(int argc, char **argv)
+{
+       int values[] = { -5, 42, 36, 24, };
+       CDS_HLIST_HEAD(mylist);         /* Defines an empty hlist head */
+       unsigned int i;
+       int ret = 0;
+       struct mynode *node;
+
+       /*
+        * 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++) {
+               node = malloc(sizeof(*node));
+               if (!node) {
+                       ret = -1;
+                       goto end;
+               }
+               node->value = values[i];
+               cds_hlist_add_head_rcu(&node->node, &mylist);
+       }
+
+       /*
+        * Just show the list content. This is _not_ an RCU-safe
+        * iteration on the list.
+        */
+       printf("mylist content:");
+       cds_hlist_for_each_entry_2(node, &mylist, node) {
+               printf(" %d", node->value);
+       }
+       printf("\n");
+end:
+       return ret;
+}
diff --git a/doc/examples/hlist/cds_hlist_del_rcu.c b/doc/examples/hlist/cds_hlist_del_rcu.c
new file mode 100644 (file)
index 0000000..1995b21
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * 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 example shows how to remove from a non-circular linked-list
+ * safely against concurrent RCU traversals.
+ */
+
+#include <stdio.h>
+
+#include <urcu.h>              /* Userspace RCU flavor */
+#include <urcu/rcuhlist.h>     /* RCU hlist */
+#include <urcu/compiler.h>     /* For CAA_ARRAY_SIZE */
+
+/*
+ * Nodes populated into the list.
+ */
+struct mynode {
+       int value;                      /* Node content */
+       struct cds_hlist_node node;     /* Linked-list chaining */
+       struct rcu_head rcu_head;       /* For call_rcu() */
+};
+
+static
+void free_node_rcu(struct rcu_head *head)
+{
+       struct mynode *node = caa_container_of(head, struct mynode, rcu_head);
+
+       free(node);
+}
+
+int main(int argc, char **argv)
+{
+       int values[] = { -5, 42, 36, 24, };
+       CDS_HLIST_HEAD(mylist);         /* Defines an empty hlist head */
+       unsigned int i;
+       int ret = 0;
+       struct mynode *node, *n;
+
+       /*
+        * 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++) {
+               node = malloc(sizeof(*node));
+               if (!node) {
+                       ret = -1;
+                       goto end;
+               }
+               node->value = values[i];
+               cds_hlist_add_head_rcu(&node->node, &mylist);
+       }
+
+       /*
+        * Removing all positive values. Safe against concurrent RCU
+        * traversals, require mutual exclusion with list updates.
+        * Notice the "safe" iteration: it is safe against removal of
+        * nodes as we iterate on the list.
+        */
+       cds_hlist_for_each_entry_safe_2(node, n, &mylist, node) {
+               if (node->value > 0) {
+                       cds_hlist_del_rcu(&node->node);
+                       /*
+                        * We can only reclaim memory after a grace
+                        * period has passed after cds_hlist_del_rcu().
+                        */
+                       call_rcu(&node->rcu_head, free_node_rcu);
+               }
+       }
+
+       /*
+        * Just show the list content. This is _not_ an RCU-safe
+        * iteration on the list.
+        */
+       printf("mylist content:");
+       cds_hlist_for_each_entry_2(node, &mylist, node) {
+               printf(" %d", node->value);
+       }
+       printf("\n");
+end:
+       return ret;
+}
diff --git a/doc/examples/hlist/cds_hlist_for_each_entry_rcu.c b/doc/examples/hlist/cds_hlist_for_each_entry_rcu.c
new file mode 100644 (file)
index 0000000..f6b744a
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * 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 example shows how to do a non-circular RCU linked list
+ * traversal, safely against concurrent RCU updates.
+ */
+
+#include <stdio.h>
+
+#include <urcu.h>              /* Userspace RCU flavor */
+#include <urcu/rcuhlist.h>     /* RCU hlist */
+#include <urcu/compiler.h>     /* For CAA_ARRAY_SIZE */
+
+/*
+ * Nodes populated into the list.
+ */
+struct mynode {
+       int value;                      /* Node content */
+       struct cds_hlist_node node;     /* Linked-list chaining */
+};
+
+int main(int argc, char **argv)
+{
+       int values[] = { -5, 42, 36, 24, };
+       CDS_HLIST_HEAD(mylist);         /* Defines an empty hlist head */
+       unsigned int i;
+       int ret = 0;
+       struct mynode *node;
+
+       /*
+        * 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++) {
+               node = malloc(sizeof(*node));
+               if (!node) {
+                       ret = -1;
+                       goto end;
+               }
+               node->value = values[i];
+               cds_hlist_add_head_rcu(&node->node, &mylist);
+       }
+
+       /*
+        * RCU-safe iteration on the list.
+        */
+       printf("mylist content:");
+
+       /*
+        * Surround the RCU read-side critical section with rcu_read_lock()
+        * and rcu_read_unlock().
+        */
+       rcu_read_lock();
+
+       /*
+        * This traversal can be performed concurrently with RCU
+        * updates.
+        */
+       cds_hlist_for_each_entry_rcu_2(node, &mylist, node) {
+               printf(" %d", node->value);
+       }
+
+       rcu_read_unlock();
+
+       printf("\n");
+end:
+       rcu_unregister_thread();
+       return ret;
+}
diff --git a/doc/examples/hlist/cds_hlist_for_each_rcu.c b/doc/examples/hlist/cds_hlist_for_each_rcu.c
new file mode 100644 (file)
index 0000000..47baa0e
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * 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 example shows how to do a non-circular RCU linked list
+ * traversal, safely against concurrent RCU updates.
+ * cds_hlist_for_each_rcu() iterates on struct cds_hlist_node, and thus,
+ * either caa_container_of() or cds_hlist_entry() are needed to access
+ * the container structure.
+ */
+
+#include <stdio.h>
+
+#include <urcu.h>              /* Userspace RCU flavor */
+#include <urcu/rcuhlist.h>     /* RCU hlist */
+#include <urcu/compiler.h>     /* For CAA_ARRAY_SIZE */
+
+/*
+ * Nodes populated into the list.
+ */
+struct mynode {
+       int value;                      /* Node content */
+       struct cds_hlist_node node;     /* Linked-list chaining */
+};
+
+int main(int argc, char **argv)
+{
+       int values[] = { -5, 42, 36, 24, };
+       CDS_HLIST_HEAD(mylist);         /* Defines an empty hlist head */
+       unsigned int i;
+       int ret = 0;
+       struct cds_hlist_node *pos;
+
+       /*
+        * 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++) {
+               struct mynode *node;
+
+               node = malloc(sizeof(*node));
+               if (!node) {
+                       ret = -1;
+                       goto end;
+               }
+               node->value = values[i];
+               cds_hlist_add_head_rcu(&node->node, &mylist);
+       }
+
+       /*
+        * RCU-safe iteration on the list.
+        */
+       printf("mylist content:");
+
+       /*
+        * Surround the RCU read-side critical section with rcu_read_lock()
+        * and rcu_read_unlock().
+        */
+       rcu_read_lock();
+
+       /*
+        * This traversal can be performed concurrently with RCU
+        * updates.
+        */
+       cds_hlist_for_each_rcu(pos, &mylist) {
+               struct mynode *node = cds_hlist_entry(pos, struct mynode, node);
+
+               printf(" %d", node->value);
+       }
+
+       rcu_read_unlock();
+
+       printf("\n");
+end:
+       rcu_unregister_thread();
+       return ret;
+}
This page took 0.031619 seconds and 4 git commands to generate.