1 // SPDX-FileCopyrightText: 2009,2017 Mathieu Desnoyers <mathieu.desnoyers (at) efficios.com> 2 // SPDX-FileCopyrightText: 2009 Paul E. McKenney, IBM Corporation. 3 // 4 // SPDX-License-Identifier: LGPL-2.1-or-later 5 6 #ifndef _URCU_WORKQUEUE_H 7 #define _URCU_WORKQUEUE_H 8 9 /* 10 * Userspace RCU header - Userspace workqueues 11 */ 12 13 #include <stdlib.h> 14 #include <pthread.h> 15 16 #include <urcu/wfcqueue.h> 17 18 #ifdef __cplusplus 19 extern "C" { 20 #endif 21 22 /* Note that struct urcu_workqueue is opaque to callers. */ 23 24 struct urcu_workqueue; 25 struct urcu_workqueue_completion; 26 27 /* Flag values. */ 28 29 #define URCU_WORKQUEUE_RT (1U << 0) 30 #define URCU_WORKQUEUE_STOP (1U << 1) 31 #define URCU_WORKQUEUE_PAUSE (1U << 2) 32 #define URCU_WORKQUEUE_PAUSED (1U << 3) 33 34 /* 35 * The urcu_work data structure is placed in the structure to be acted 36 * upon via urcu_workqueue_queue_work(). 37 */ 38 39 struct urcu_work { 40 struct cds_wfcq_node next; 41 void (*func)(struct urcu_work *head); 42 }; 43 44 /* 45 * Exported functions 46 */ 47 48 struct urcu_workqueue *urcu_workqueue_create(unsigned long flags, 49 int cpu_affinity, void *priv, 50 void (*grace_period_fct)(struct urcu_workqueue *workqueue, void *priv), 51 void (*initialize_worker_fct)(struct urcu_workqueue *workqueue, void *priv), 52 void (*finalize_worker_fct)(struct urcu_workqueue *workqueue, void *priv), 53 void (*worker_before_wait_fct)(struct urcu_workqueue *workqueue, void *priv), 54 void (*worker_after_wake_up_fct)(struct urcu_workqueue *workqueue, void *priv), 55 void (*worker_before_pause_fct)(struct urcu_workqueue *workqueue, void *priv), 56 void (*worker_after_resume_fct)(struct urcu_workqueue *workqueue, void *priv)); 57 void urcu_workqueue_destroy(struct urcu_workqueue *workqueue); 58 59 /* 60 * Never fails. Should not be used to enqueue work from worker threads 61 * after the application invokes urcu_workqueue_free. 62 */ 63 void urcu_workqueue_queue_work(struct urcu_workqueue *workqueue, 64 struct urcu_work *work, 65 void (*func)(struct urcu_work *work)); 66 67 struct urcu_workqueue_completion *urcu_workqueue_create_completion(void); 68 void urcu_workqueue_destroy_completion(struct urcu_workqueue_completion *completion); 69 70 void urcu_workqueue_queue_completion(struct urcu_workqueue *workqueue, 71 struct urcu_workqueue_completion *completion); 72 void urcu_workqueue_wait_completion(struct urcu_workqueue_completion *completion); 73 74 void urcu_workqueue_flush_queued_work(struct urcu_workqueue *workqueue); 75 76 /* 77 * pause/resume/create worker threads. Can be used to pause worker 78 * threads across fork/clone while keeping the workqueue in place. 79 * Pause is used in parent pre-fork, resume in parent post-fork, create 80 * in child after-fork. 81 */ 82 void urcu_workqueue_pause_worker(struct urcu_workqueue *workqueue); 83 void urcu_workqueue_resume_worker(struct urcu_workqueue *workqueue); 84 void urcu_workqueue_create_worker(struct urcu_workqueue *workqueue); 85 86 #ifdef __cplusplus 87 } 88 #endif 89 90 #endif /* _URCU_WORKQUEUE_H */ 91