1 // SPDX-FileCopyrightText: 2010 Mathieu Desnoyers <mathieu.desnoyers (at) efficios.com> 2 // 3 // SPDX-License-Identifier: LGPL-2.1-or-later 4 5 #ifndef _URCU_RCULFQUEUE_H 6 #define _URCU_RCULFQUEUE_H 7 8 /* 9 * Userspace RCU library - Lock-Free RCU Queue 10 */ 11 12 13 #ifdef __cplusplus 14 extern "C" { 15 #endif 16 17 struct cds_lfq_queue_rcu; 18 struct rcu_head; 19 20 struct cds_lfq_node_rcu { 21 struct cds_lfq_node_rcu *next; 22 int dummy; 23 }; 24 25 struct cds_lfq_queue_rcu { 26 struct cds_lfq_node_rcu *head, *tail; 27 void (*queue_call_rcu)(struct rcu_head *head, 28 void (*func)(struct rcu_head *head)); 29 }; 30 31 #ifdef _LGPL_SOURCE 32 33 #include <urcu/static/rculfqueue.h> 34 35 #define cds_lfq_node_init_rcu _cds_lfq_node_init_rcu 36 #define cds_lfq_init_rcu _cds_lfq_init_rcu 37 #define cds_lfq_destroy_rcu _cds_lfq_destroy_rcu 38 #define cds_lfq_enqueue_rcu _cds_lfq_enqueue_rcu 39 #define cds_lfq_dequeue_rcu _cds_lfq_dequeue_rcu 40 41 #else /* !_LGPL_SOURCE */ 42 43 extern void cds_lfq_node_init_rcu(struct cds_lfq_node_rcu *node); 44 extern void cds_lfq_init_rcu(struct cds_lfq_queue_rcu *q, 45 void queue_call_rcu(struct rcu_head *head, 46 void (*func)(struct rcu_head *head))); 47 /* 48 * The queue should be emptied before calling destroy. 49 * 50 * Return 0 on success, -EPERM if queue is not empty. 51 */ 52 extern int cds_lfq_destroy_rcu(struct cds_lfq_queue_rcu *q); 53 54 /* 55 * Should be called under rcu read lock critical section. 56 */ 57 extern void cds_lfq_enqueue_rcu(struct cds_lfq_queue_rcu *q, 58 struct cds_lfq_node_rcu *node); 59 60 /* 61 * Should be called under rcu read lock critical section. 62 * 63 * The caller must wait for a grace period to pass before freeing the returned 64 * node or modifying the cds_lfq_node_rcu structure. 65 * Returns NULL if queue is empty. 66 */ 67 extern 68 struct cds_lfq_node_rcu *cds_lfq_dequeue_rcu(struct cds_lfq_queue_rcu *q); 69 70 #endif /* !_LGPL_SOURCE */ 71 72 #ifdef __cplusplus 73 } 74 #endif 75 76 #endif /* _URCU_RCULFQUEUE_H */ 77