X-Git-Url: http://git.lttng.org/?p=urcu.git;a=blobdiff_plain;f=doc%2Fexamples%2Furcu-flavors%2Fsignal.c;fp=doc%2Fexamples%2Furcu-flavors%2Fsignal.c;h=0000000000000000000000000000000000000000;hp=62c6cf2926804ce9446a2ac7873d5ca0c7eeddba;hb=3d003c571cd461aba1935e5d21e1e04da7183970;hpb=546d9a117ef442847203e82f6b1bf6abd2d13b25 diff --git a/doc/examples/urcu-flavors/signal.c b/doc/examples/urcu-flavors/signal.c deleted file mode 100644 index 62c6cf2..0000000 --- a/doc/examples/urcu-flavors/signal.c +++ /dev/null @@ -1,125 +0,0 @@ -// SPDX-FileCopyrightText: 2013 Mathieu Desnoyers -// -// SPDX-License-Identifier: LGPL-2.1-or-later - -#include -#include -#include -#include -#include - -#include /* Signal-based RCU flavor */ -#include /* List example */ -#include /* For CAA_ARRAY_SIZE */ - -/* - * Example showing how to use the signal-based 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(void) -{ - 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. - */ - urcu_signal_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; - } - - /* - * 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. - */ - urcu_signal_read_lock(); - - /* - * RCU traversal of the linked list. - */ - cds_list_for_each_entry_rcu(node, &mylist, node) { - printf("Value: %" PRIu64 "\n", node->value); - } - urcu_signal_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() 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_signal_call_rcu(&node->rcu_head, rcu_free_node); - } - - /* - * 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() should not. - */ - urcu_signal_synchronize_rcu(); - - sleep(1); - - /* - * Waiting for previously called call_rcu handlers to complete - * before program exits, or in library destructors, is a good - * practice. - */ - urcu_signal_barrier(); - -end: - urcu_signal_unregister_thread(); - return ret; -}