12 * Function signature to execute with user data, thread context, and thread id.
14 typedef void (work_fn_t
)(void *, void *, size_t);
17 * Function signature to free a worker thread's ctx.
19 typedef void (worker_ctx_free_fn_t
)(void *);
22 * Function signature for receiving error strings.
24 typedef int (printf_fn_t
) (const char *format
, ...);
27 * Flag type for controlling worker behavior.
30 typedef uint_fast8_t workqueue_flags_t
;
33 * Internal unit of work.
36 STAILQ_ENTRY(work
) stailq
;
41 enum workqueue_flags
{
42 WQF_TERMINATE
= (1<<0), /* worker thread will exit when out of work */
43 WQF_NOCOMPLETE
= (1<<1), /* worker thread will not finish all work before exiting */
44 WQF_NORECYCLE
= (1<<2), /* do not reuse work allocations */
48 * A worker thread, with related data.
52 struct workqueue
*workqueue
;
54 LIST_ENTRY(worker
) list
;
56 volatile workqueue_flags_t flags
;
58 /* Queue of worker-specific work to perform, before consuming general work queue. */
59 /* Guarded by workqueue->work_mutex */
60 STAILQ_HEAD(priority_work_head
, work
) priority_work_head
;
61 size_t n_priority_work
;
62 /* End of workqueue->work_mutex guard */
69 /* List of active worker threads. */
70 pthread_mutex_t workers_mutex
;
71 LIST_HEAD(workers_head
, worker
) workers_head
;
73 size_t workers_next_id
;
74 /* End of workers_mutex guard */
76 worker_ctx_free_fn_t
*worker_ctx_free_fn
;
78 /* Queue of work units awaiting processing. */
79 pthread_mutex_t work_mutex
;
80 pthread_cond_t work_cond
;
81 STAILQ_HEAD(work_head
, work
) work_head
;
83 size_t n_work_highwater
;
84 /* End of work_mutex guard */
86 /* Queue of allocated unutilized work units. */
87 pthread_mutex_t free_mutex
;
88 STAILQ_HEAD(free_head
, work
) free_head
;
90 /* End of free_mutex guard */
92 volatile workqueue_flags_t flags
;
96 * Initialize a workqueue.
98 int workqueue_init(struct workqueue
*, worker_ctx_free_fn_t
*, workqueue_flags_t
);
99 void workqueue_fini(struct workqueue
*, bool);
101 ssize_t
workqueue_worker_add(struct workqueue
*, void *, workqueue_flags_t
);
102 ssize_t
workqueue_worker_remove(struct workqueue
*);
104 ssize_t
workqueue_release_work(struct workqueue
*, size_t);
106 int workqueue_add(struct workqueue
*, work_fn_t
*, void *);
108 #endif /* _WORKQUEUE_H_ */