### Install and Link Userspace RCU Source: https://context7.com/urcu/userspace-rcu/llms.txt Instructions for installing Userspace RCU development libraries and compiling applications. Use `-lurcu-memb` or `-lurcu-qsbr` depending on the desired flavor. LGPL/GPL applications can use `-D_LGPL_SOURCE` for inline optimization. ```bash # Install liburcu (Debian/Ubuntu) sudo apt-get install liburcu-dev # Install liburcu (Fedora/RHEL) sudo dnf install userspace-rcu-devel # Build from source git clone https://github.com/urcu/userspace-rcu.git cd userspace-rcu ./bootstrap ./configure make sudo make install sudo ldconfig # Compile application with memb flavor gcc -o myapp myapp.c -lurcu-memb -lpthread # Compile application with qsbr flavor gcc -o myapp myapp.c -lurcu-qsbr -lpthread # Compile with LGPL inline optimization (for LGPL/GPL apps only) gcc -D_LGPL_SOURCE -o myapp myapp.c -lurcu-memb -lpthread # Compile with small function inlining (any license) gcc -DURCU_INLINE_SMALL_FUNCTIONS -o myapp myapp.c -lurcu-memb -lpthread ``` -------------------------------- ### Wait-Free Stack Example Source: https://context7.com/urcu/userspace-rcu/llms.txt Demonstrates a wait-free stack with wait-free push and blocking pop operations. This is suitable for scenarios where push operations must not block. ```c #include #include #include #include struct mynode { int value; struct cds_wfs_node node; }; int main(void) { struct cds_wfs_stack mystack; struct cds_wfs_node *snode; struct mynode *node; cds_wfs_init(&mystack); /* Push nodes (wait-free) */ for (int i = 1; i <= 3; i++) { node = malloc(sizeof(*node)); cds_wfs_node_init(&node->node); node->value = i * 10; cds_wfs_push(&mystack, &node->node); } /* Pop nodes one by one (blocking) */ printf("Stack content (LIFO):"); while ((snode = cds_wfs_pop_blocking(&mystack)) != NULL) { node = caa_container_of(snode, struct mynode, node); printf(" %d", node->value); free(node); } printf("\n"); /* Output: Stack content (LIFO): 30 20 10 */ cds_wfs_destroy(&mystack); return 0; } ``` -------------------------------- ### Build userspace-rcu on Solaris 11 Source: https://github.com/urcu/userspace-rcu/blob/master/doc/solaris-build.md Compile and install userspace-rcu on Solaris 11 using gmake. This process involves bootstrapping, configuring with specific CFLAGS and a prefix, and then executing the build, check, regtest, and install steps. ```bash ./bootstrap CFLAGS="-D_XOPEN_SOURCE=1 -D_XOPEN_SOURCE_EXTENDED=1 -D__EXTENSIONS__=1" MAKE=gmake ./configure --prefix=$PREFIX gmake gmake check gmake regtest gmake install ``` -------------------------------- ### Build userspace-rcu on Solaris 10 Source: https://github.com/urcu/userspace-rcu/blob/master/doc/solaris-build.md Compile and install userspace-rcu on Solaris 10 using gmake. This includes bootstrapping, configuring with specific CFLAGS, and running build, check, regtest, and install targets. ```bash ./bootstrap CFLAGS="-D_XOPEN_SOURCE=1 -D_XOPEN_SOURCE_EXTENDED=1 -D__EXTENSIONS__=1" MAKE=gmake ./configure gmake gmake check gmake regtest gmake install ``` -------------------------------- ### Wait-Free Concurrent Queue Example Source: https://context7.com/urcu/userspace-rcu/llms.txt Demonstrates a wait-free concurrent queue with wait-free enqueue and blocking dequeue operations. Ensure proper memory management for nodes. ```c #include #include #include #include struct mynode { int value; struct cds_wfcq_node node; }; int main(void) { struct cds_wfcq_head queue_head; struct cds_wfcq_tail queue_tail; struct cds_wfcq_node *qnode; struct mynode *node; int values[] = {10, 20, 30, 40}; cds_wfcq_init(&queue_head, &queue_tail); /* Enqueue nodes (wait-free, can be called from multiple threads) */ for (int i = 0; i < 4; i++) { node = malloc(sizeof(*node)); cds_wfcq_node_init(&node->node); node->value = values[i]; cds_wfcq_enqueue(&queue_head, &queue_tail, &node->node); } /* Dequeue nodes (blocking, requires mutual exclusion with other dequeues) */ printf("Queue content (FIFO order):"); while ((qnode = cds_wfcq_dequeue_blocking(&queue_head, &queue_tail)) != NULL) { node = caa_container_of(qnode, struct mynode, node); printf(" %d", node->value); free(node); } printf("\n"); cds_wfcq_destroy(&queue_head, &queue_tail); return 0; } /* Output: Queue content (FIFO order): 10 20 30 40 */ ``` -------------------------------- ### RCU Callback Function Example Source: https://github.com/urcu/userspace-rcu/blob/master/doc/rcu-api.md An example of a typical RCU callback function that uses `container_of` to access the enclosing structure and then frees it. This function is intended to be passed to `call_rcu`. ```c void func(struct rcu_head *head) { struct foo *p = container_of(head, struct foo, rcu); free(p); } ``` -------------------------------- ### Interactive Mode Notice for GPL Programs Source: https://github.com/urcu/userspace-rcu/blob/master/LICENSES/GPL-3.0-or-later.txt Display this notice when a program starts in interactive mode to inform users about its copyright, warranty, and redistribution conditions according to the GNU GPL. The commands 'show w' and 'show c' should display relevant license sections. ```text Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. ``` -------------------------------- ### QSBR Reader Thread Example Source: https://context7.com/urcu/userspace-rcu/llms.txt Illustrates how a reader thread should register, announce quiescent states periodically, and unregister with QSBR. Ensure quiescent state is announced regularly to avoid RCU grace period issues. ```c #include void qsbr_reader_thread(void) { urcu_qsbr_register_thread(); while (running) { /* Access shared data (implicitly in read-side critical section) */ process_shared_data(); /* Announce quiescent state - required periodically */ urcu_qsbr_quiescent_state(); } urcu_qsbr_unregister_thread(); } ``` ```c void qsbr_long_blocking_operation(void) { /* Mark thread as offline before long blocking operation */ urcu_qsbr_thread_offline(); sleep(10); /* Long blocking operation */ /* Mark thread as online again */ urcu_qsbr_thread_online(); } ``` -------------------------------- ### Lock-Free Stack Example Source: https://context7.com/urcu/userspace-rcu/llms.txt Illustrates a lock-free stack with lock-free push and pop operations. Note the different behaviors of single pop versus popping all remaining nodes. ```c #include #include #include #include struct mynode { int value; struct cds_lfs_node node; }; int main(void) { struct cds_lfs_stack mystack; struct cds_lfs_node *snode; struct cds_lfs_head *shead; struct mynode *node; int values[] = {10, 20, 30, 40}; cds_lfs_init(&mystack); /* Push nodes (lock-free) */ for (int i = 0; i < 4; i++) { node = malloc(sizeof(*node)); cds_lfs_node_init(&node->node); node->value = values[i]; cds_lfs_push(&mystack, &node->node); } /* Pop single node (lock-free) */ snode = cds_lfs_pop_blocking(&mystack); if (snode) { node = caa_container_of(snode, struct mynode, node); printf("Popped: %d\n", node->value); /* Output: Popped: 40 */ free(node); } /* Pop all remaining nodes at once (wait-free) */ printf("Remaining (LIFO order):"); shead = cds_lfs_pop_all_blocking(&mystack); cds_lfs_for_each(shead, snode) { node = caa_container_of(snode, struct mynode, node); printf(" %d", node->value); } printf("\n"); /* Output: Remaining (LIFO order): 30 20 10 */ cds_lfs_destroy(&mystack); return 0; } ``` -------------------------------- ### Atomic Operations Example Source: https://context7.com/urcu/userspace-rcu/llms.txt Shows low-level atomic primitives for implementing custom lock-free algorithms with proper memory ordering. Use these for fine-grained control over shared data. ```c #include #include int main(void) { long counter = 0; long old_val, new_val; /* Atomic read and write */ uatomic_set(&counter, 100); printf("Initial: %ld\n", uatomic_read(&counter)); /* Atomic increment/decrement */ uatomic_inc(&counter); uatomic_add(&counter, 5); printf("After inc+add(5): %ld\n", uatomic_read(&counter)); /* 106 */ /* Atomic exchange - returns old value */ old_val = uatomic_xchg(&counter, 200); printf("Exchanged %ld for 200\n", old_val); /* 106 */ /* Compare-and-swap */ old_val = uatomic_cmpxchg(&counter, 200, 300); if (old_val == 200) { printf("CAS succeeded, now: %ld\n", uatomic_read(&counter)); /* 300 */ } /* Atomic add with return value */ new_val = uatomic_add_return(&counter, 10); printf("Add returned: %ld\n", new_val); /* 310 */ /* Atomic bitwise operations */ uatomic_or(&counter, 0x1); /* Set bit 0 */ uatomic_and(&counter, ~0x2); /* Clear bit 1 */ return 0; } ``` -------------------------------- ### Register RCU Callback Example Source: https://github.com/urcu/userspace-rcu/blob/master/doc/rcu-api.md Demonstrates how to register an RCU callback function `func` for a structure `p` using `call_rcu`. The `rcu` member is assumed to be of type `struct rcu_head`. ```c call_rcu(&p->rcu, func); ``` -------------------------------- ### Start Polling for RCU Grace Period Completion Source: https://github.com/urcu/userspace-rcu/blob/master/doc/rcu-api.md Obtains a handle to poll for RCU grace period completion. Must be called from a registered RCU read-side thread. For QSBR, the caller must be online. ```c struct urcu_gp_poll_state start_poll_synchronize_rcu(void); ``` -------------------------------- ### Include Header for liburcu-qsbr Source: https://github.com/urcu/userspace-rcu/blob/master/README.md Include the necessary header file for using the liburcu-qsbr library. Link with -lurcu-qsbr. ```c #include ``` -------------------------------- ### Program Header for GPL Source: https://github.com/urcu/userspace-rcu/blob/master/LICENSES/GPL-3.0-or-later.txt Include this header at the beginning of each source file to state the program's name, copyright, and licensing terms under the GNU GPL. Ensure a pointer to the full license is provided. ```text Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ``` -------------------------------- ### Get Default Call RCU Data Handle Source: https://github.com/urcu/userspace-rcu/blob/master/doc/rcu-api.md Returns the handle for the default `call_rcu()` helper thread. Creates it if it does not exist. ```c struct call_rcu_data *get_default_call_rcu_data(void); ``` -------------------------------- ### Get Call RCU Thread Identifier Source: https://github.com/urcu/userspace-rcu/blob/master/doc/rcu-api.md Retrieves the pthread identifier for a call_rcu helper thread associated with the provided call_rcu_data. ```c pthread_t get_call_rcu_thread(struct call_rcu_data *crdp); ``` -------------------------------- ### Include Header for liburcu-mb Source: https://github.com/urcu/userspace-rcu/blob/master/README.md Include the necessary header file for using the liburcu-mb library. Link with -lurcu-mb. ```c #include ``` -------------------------------- ### Include Header for liburcu-bp Source: https://github.com/urcu/userspace-rcu/blob/master/README.md Include the necessary header file for using the liburcu-bp library. Link with -lurcu-bp. ```c #include ``` -------------------------------- ### Get Call RCU Thread Source: https://github.com/urcu/userspace-rcu/blob/master/doc/rcu-api.md Retrieves the pthread identifier for the helper thread associated with the provided call RCU data. ```APIDOC ## GET call_rcu_thread ### Description Returns the helper thread's pthread identifier linked to a call rcu helper thread data. ### Method GET ### Endpoint /api/call_rcu_thread ### Parameters #### Query Parameters - **crdp** (struct call_rcu_data *) - Required - Pointer to the call RCU data. ### Response #### Success Response (200) - **pthread_t** - The pthread identifier of the helper thread. ``` -------------------------------- ### RCU Polling Mechanism Source: https://github.com/urcu/userspace-rcu/blob/master/README.md Alternative to synchronize_rcu() for waiting on grace periods using polling. Start polling with start_poll_synchronize_rcu() and check completion with poll_state_synchronize_rcu(). ```c urcu__start_poll_synchronize_rcu() ``` ```c urcu__poll_state_synchronize_rcu() ``` -------------------------------- ### Force 64-bit Build with GCC Source: https://github.com/urcu/userspace-rcu/blob/master/README.md Use this command to force a 64-bit build when compiling with GCC. Ensure CFLAGS are set appropriately. ```bash CFLAGS="-m64 -g -O2" ./configure ``` -------------------------------- ### Synchronize RCU Grace Period Source: https://github.com/urcu/userspace-rcu/blob/master/doc/rcu-api.md This function blocks until all RCU read-side critical sections that were active before this call have completed. It does not wait for sections that start after the call. This is not a reader-writer lock. ```c void synchronize_rcu(void); ``` -------------------------------- ### Include Header for liburcu-memb Source: https://github.com/urcu/userspace-rcu/blob/master/README.md Include the necessary header file for using the liburcu-memb library. Link with -lurcu-memb. ```c #include ``` -------------------------------- ### Include LGPL-compatible library header Source: https://github.com/urcu/userspace-rcu/blob/master/LICENSE.md Define _LGPL_SOURCE to statically use the library header. Omission implies dynamic-only linking, required by LGPL for relinking with newer versions. ```c #define _LGPL_SOURCE #include ``` -------------------------------- ### Get Thread-Assigned Call RCU Data Handle Source: https://github.com/urcu/userspace-rcu/blob/master/doc/rcu-api.md Returns the handle for the current thread's hard-assigned `call_rcu()` helper thread. Returns `NULL` if the thread is using a per-CPU or the default helper thread. ```c struct call_rcu_data *get_thread_call_rcu_data(void); ``` -------------------------------- ### External Licensing Information Source: https://github.com/urcu/userspace-rcu/blob/master/LICENSE.md Links to external resources for licensing details of components like atomic_ops and Boehm GC. ```text http://www.hpl.hp.com/research/linux/atomic_ops/LICENSING.txt http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/ ``` -------------------------------- ### Force 32-bit Build with GCC Source: https://github.com/urcu/userspace-rcu/blob/master/README.md Use this command to force a 32-bit build when compiling with GCC. Ensure CFLAGS are set appropriately. ```bash CFLAGS="-m32 -g -O2" ./configure ``` -------------------------------- ### Get Current Thread's Call RCU Data Handle Source: https://github.com/urcu/userspace-rcu/blob/master/doc/rcu-api.md Returns the handle for the current thread's `call_rcu()` helper thread. It prioritizes the thread-assigned handle, then per-CPU, and finally the default handle. ```c struct call_rcu_data *get_call_rcu_data(void); ``` -------------------------------- ### Compare Shared Object ABI with Serialized Definition Source: https://github.com/urcu/userspace-rcu/blob/master/extras/abi/README.md Use this command to compare a built shared object (e.g., liburcu-memb.so) with its corresponding serialized ABI definition file. This helps in identifying breaking changes in the Application Binary Interface. ```bash abidiff \ extras/abi/0.13/x86_64-pc-linux-gnu/liburcu-memb.so.8.xml \ src/.libs/liburcu-memb.so ``` -------------------------------- ### Get Per-CPU Call RCU Data Handle Source: https://github.com/urcu/userspace-rcu/blob/master/doc/rcu-api.md Returns the handle for the current CPU's `call_rcu()` helper thread. Returns `NULL` if no helper thread is assigned to the current CPU. Use of the returned handle should be protected by an RCU read-side lock. ```c struct call_rcu_data *get_cpu_call_rcu_data(int cpu); ``` -------------------------------- ### Initialize Userspace RCU Source: https://github.com/urcu/userspace-rcu/blob/master/doc/rcu-api.md Call this function once before invoking any other RCU functions. It sets up the necessary internal structures for RCU operations. ```c void rcu_init(void); ``` -------------------------------- ### Define _LGPL_SOURCE for LGPL/GPL Compatibility Source: https://github.com/urcu/userspace-rcu/blob/master/README.md Define _LGPL_SOURCE before including Userspace RCU headers if your code is LGPL or GPL compatible. This ensures function calls are generated instead of inlines for non-compatible licenses. ```c #define _LGPL_SOURCE #include "urcu.h" ``` -------------------------------- ### Lock-Free Hash Table Operations Source: https://context7.com/urcu/userspace-rcu/llms.txt Shows the creation, insertion, lookup, deletion, and iteration of elements in a lock-free hash table. Uses RCU for memory reclamation and supports automatic resizing. ```c #include #include #include #include #include struct mynode { int key; int value; struct cds_lfht_node node; struct rcu_head rcu_head; }; static uint32_t hash_seed; static unsigned long hash_key(int key) { /* Simple hash function - use jhash in production */ return (unsigned long)key * 2654435761UL; } static int match_key(struct cds_lfht_node *ht_node, const void *key) { struct mynode *node = caa_container_of(ht_node, struct mynode, node); return node->key == *(const int *)key; } static void free_node(struct rcu_head *head) { struct mynode *node = caa_container_of(head, struct mynode, rcu_head); free(node); } int main(void) { struct cds_lfht *ht; struct cds_lfht_iter iter; struct cds_lfht_node *ht_node; struct mynode *node; int key; urcu_memb_register_thread(); hash_seed = (uint32_t)time(NULL); /* Create hash table with auto-resize */ ht = cds_lfht_new_flavor(1, 1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, &urcu_memb_flavor, NULL); /* Insert node */ node = malloc(sizeof(*node)); cds_lfht_node_init(&node->node); node->key = 42; node->value = 100; urcu_memb_read_lock(); cds_lfht_add(ht, hash_key(node->key), &node->node); urcu_memb_read_unlock(); /* Lookup node */ key = 42; urcu_memb_read_lock(); cds_lfht_lookup(ht, hash_key(key), match_key, &key, &iter); ht_node = cds_lfht_iter_get_node(&iter); if (ht_node) { node = caa_container_of(ht_node, struct mynode, node); printf("Found key=%d, value=%d\n", node->key, node->value); } urcu_memb_read_unlock(); /* Delete node */ urcu_memb_read_lock(); cds_lfht_lookup(ht, hash_key(key), match_key, &key, &iter); ht_node = cds_lfht_iter_get_node(&iter); if (ht_node) { if (!cds_lfht_del(ht, ht_node)) { node = caa_container_of(ht_node, struct mynode, node); urcu_memb_call_rcu(&node->rcu_head, free_node); } } urcu_memb_read_unlock(); /* Iterate all entries */ urcu_memb_read_lock(); cds_lfht_for_each_entry(ht, &iter, node, node) { printf("key=%d, value=%d\n", node->key, node->value); } urcu_memb_read_unlock(); urcu_memb_barrier(); urcu_memb_unregister_thread(); return 0; } ``` -------------------------------- ### Create All CPU Call RCU Data Source: https://github.com/urcu/userspace-rcu/blob/master/doc/rcu-api.md Creates a dedicated helper thread for each CPU, disabling the global default helper. ```APIDOC ## POST create_all_cpu_call_rcu_data ### Description Creates a separate `call_rcu()` helper thread for each CPU. After this primitive is invoked, the global default `call_rcu()` helper thread will not be called. The `set_thread_call_rcu_data()`, `set_cpu_call_rcu_data()`, and `create_all_cpu_call_rcu_data()` functions may be combined to set up pretty much any desired association between worker and `call_rcu()` helper threads. If a given executable calls only `call_rcu()`, then that executable will have only the single global default `call_rcu()` helper thread. This will suffice in most cases. ### Method POST ### Endpoint /api/create_all_cpu_call_rcu_data ### Parameters #### Request Body - **flags** (unsigned long) - Optional - Flags to control thread creation. ### Request Example { "flags": 1 } ### Response #### Success Response (200) - **status** (string) - Indicates success or failure of the operation. ``` -------------------------------- ### Force 32-bit Sparcv9 Build Source: https://github.com/urcu/userspace-rcu/blob/master/README.md This command forces a 32-bit build specifically for Sparcv9 architectures, including assembler flags. ```bash CFLAGS="-m32 -Wa,-Av9a -g -O2" ./configure ``` -------------------------------- ### Schedule RCU Callback Source: https://github.com/urcu/userspace-rcu/blob/master/doc/rcu-api.md Registers a callback function `func` to be invoked after a future RCU grace period. The `head` structure is typically part of an RCU-protected object. Must be called from registered RCU read-side threads; for QSBR, the caller should be online. ```c void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *head)); ``` -------------------------------- ### Inline Small Functions with URCU_INLINE_SMALL_FUNCTIONS Source: https://github.com/urcu/userspace-rcu/blob/master/README.md Define URCU_INLINE_SMALL_FUNCTIONS before including Userspace RCU headers to inline small functions (10 lines or less). This can be used by applications under any license and does not make the application a derived work. Ensure headers match the library's major version. ```c #define URCU_INLINE_SMALL_FUNCTIONS #include "urcu.h" ``` -------------------------------- ### Update and Read RCU-Protected Configuration Source: https://context7.com/urcu/userspace-rcu/llms.txt Safely update and read configuration pointers using RCU. `rcu_xchg_pointer` atomically publishes a new configuration, and `rcu_dereference` safely accesses it. Ensure `urcu_memb_synchronize_rcu` is called after updates to free old configurations. ```c #include #include struct config { int timeout; int max_connections; }; struct config *global_config; void update_config(int timeout, int max_conn) { struct config *new_config, *old_config; new_config = malloc(sizeof(*new_config)); new_config->timeout = timeout; new_config->max_connections = max_conn; /* Atomically publish new config (includes write barrier) */ old_config = rcu_xchg_pointer(&global_config, new_config); /* Wait for readers, then free old config */ urcu_memb_synchronize_rcu(); free(old_config); } void read_config(void) { struct config *cfg; urcu_memb_read_lock(); /* Safely dereference RCU-protected pointer (includes read barrier) */ cfg = rcu_dereference(global_config); if (cfg) { printf("timeout=%d, max_conn=%d\n", cfg->timeout, cfg->max_connections); } urcu_memb_read_unlock(); } ``` ```c /* Alternative: assign without getting old value */ void init_config(void) { struct config *cfg = malloc(sizeof(*cfg)); cfg->timeout = 30; cfg->max_connections = 100; /* Publish pointer (includes write barrier) */ rcu_assign_pointer(global_config, cfg); } ``` -------------------------------- ### Atomic Add and Return Source: https://github.com/urcu/userspace-rcu/blob/master/doc/uatomic-api.md Atomically adds `v` to the value at `addr` and returns the resulting value. Implies full memory barriers. ```c type uatomic_add_return(type *addr, type v); ``` -------------------------------- ### RCU Initialization and Thread Registration Source: https://github.com/urcu/userspace-rcu/blob/master/doc/rcu-api.md Functions for initializing RCU and registering/unregistering threads that will use RCU read-side operations. ```APIDOC ## rcu_init() ### Description Initializes the Userspace RCU subsystem. This function must be called before any other RCU functions are invoked. ### Method void ### Endpoint N/A (Library function) ### Parameters None ### Request Example ```c rcu_init(); ``` ### Response None ``` ```APIDOC ## rcu_read_lock() ### Description Begins an RCU read-side critical section. These critical sections can be nested. ### Method void ### Endpoint N/A (Library function) ### Parameters None ### Request Example ```c rcu_read_lock(); // ... RCU-protected read operations ... ``` ### Response None ``` ```APIDOC ## rcu_read_unlock() ### Description Ends an RCU read-side critical section. ### Method void ### Endpoint N/A (Library function) ### Parameters None ### Request Example ```c rcu_read_unlock(); ``` ### Response None ``` ```APIDOC ## rcu_register_thread() ### Description Registers the current thread for RCU read-side operations. This must be called before the first `rcu_read_lock()` invocation by a thread. Threads not using `rcu_read_lock()` do not need to call this. Note: `rcu-bp` (bullet proof RCU) does not require this call. ### Method void ### Endpoint N/A (Library function) ### Parameters None ### Request Example ```c rcu_register_thread(); ``` ### Response None ``` ```APIDOC ## rcu_unregister_thread() ### Description Unregisters the current thread from RCU read-side operations. This must be called before `pthread_exit()` or returning from the thread's top-level function if `rcu_register_thread()` was previously called. ### Method void ### Endpoint N/A (Library function) ### Parameters None ### Request Example ```c rcu_unregister_thread(); ``` ### Response None ``` -------------------------------- ### RCU Callback and Barrier Functions Source: https://github.com/urcu/userspace-rcu/blob/master/doc/rcu-api.md Functions for scheduling callbacks to be executed after an RCU grace period and for ensuring all callbacks are completed. ```APIDOC ## call_rcu() ### Description Registers a callback function (`func`) to be invoked after a future RCU grace period. The `head` parameter is typically a field within an RCU-protected structure. ### Method void ### Endpoint N/A (Library function) ### Parameters - **head** (`struct rcu_head *`) - Required - Pointer to an `rcu_head` structure. - **func** (`void (*)(struct rcu_head *head)`) - Required - The callback function to execute. ### Request Example ```c struct foo { // ... other fields ... struct rcu_head rcu; }; void my_rcu_callback(struct rcu_head *head) { struct foo *p = container_of(head, struct foo, rcu); free(p); } // ... later, to schedule the callback ... struct foo *my_foo_ptr = /* ... */; call_rcu(&my_foo_ptr->rcu, my_rcu_callback); ``` ### Response None ``` ```APIDOC ## rcu_barrier() ### Description Waits for all `call_rcu()` work initiated before this call by any thread to complete. This function should not be called from within a `call_rcu()` thread. ### Method void ### Endpoint N/A (Library function) ### Parameters None ### Request Example ```c rcu_barrier(); ``` ### Response None ```