1 /*        $NetBSD: workqueue.h,v 1.25 2021/12/19 11:40:13 riastradh Exp $       */
2 
3 /*-
4  * Copyright (c) 2013, 2018 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Taylor R. Campbell.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef _LINUX_WORKQUEUE_H_
33 #define _LINUX_WORKQUEUE_H_
34 
35 #include <sys/queue.h>
36 #include <sys/stdbool.h>
37 
38 #include <linux/kernel.h>     /* container_of */
39 #include <linux/stringify.h>
40 
41 #define   INIT_DELAYED_WORK             linux_INIT_DELAYED_WORK
42 #define   INIT_RCU_WORK                           linux_INIT_RCU_WORK
43 #define   INIT_WORK                     linux_INIT_WORK
44 #define   alloc_ordered_workqueue                 linux_alloc_ordered_workqueue
45 #define   alloc_workqueue                         linux_alloc_workqueue
46 #define   cancel_delayed_work           linux_cancel_delayed_work
47 #define   cancel_delayed_work_sync      linux_cancel_delayed_work_sync
48 #define   cancel_work                             linux_cancel_work
49 #define   cancel_work_sync              linux_cancel_work_sync
50 #define   current_work                            linux_current_work
51 #define   delayed_work_pending                    linux_delayed_work_pending
52 #define   destroy_workqueue             linux_destroy_workqueue
53 #define   drain_workqueue                         linux_drain_workqueue
54 #define   flush_delayed_work            linux_flush_delayed_work
55 #define   flush_scheduled_work                    linux_flush_scheduled_work
56 #define   flush_work                              linux_flush_work
57 #define   flush_workqueue                         linux_flush_workqueue
58 #define   mod_delayed_work              linux_mod_delayed_work
59 #define   queue_delayed_work            linux_queue_delayed_work
60 #define   queue_rcu_work                          linux_queue_rcu_work
61 #define   queue_work                              linux_queue_work
62 #define   schedule_delayed_work                   linux_schedule_delayed_work
63 #define   schedule_work                           linux_schedule_work
64 #define   system_highpri_wq             linux_system_highpri_wq
65 #define   system_long_wq                          linux_system_long_wq
66 #define   system_power_efficient_wq     linux_system_power_efficient_wq
67 #define   system_unbound_wq             linux_system_unbound_wq
68 #define   system_wq                     linux_system_wq
69 #define   to_delayed_work                         linux_to_delayed_work
70 #define   work_pending                            linux_work_pending
71 
72 struct workqueue_struct;
73 
74 struct work_struct {
75           volatile uintptr_t            work_owner;
76           TAILQ_ENTRY(work_struct)      work_entry;
77           void      (*func)(struct work_struct *); /* Linux API name */
78 };
79 
80 struct delayed_work {
81           struct work_struct            work; /* Linux API name */
82           struct callout                          dw_callout;
83           TAILQ_ENTRY(delayed_work)     dw_entry;
84           int                                     dw_resched;
85           enum {
86                     DELAYED_WORK_IDLE,
87                     DELAYED_WORK_SCHEDULED,
88                     DELAYED_WORK_RESCHEDULED,
89                     DELAYED_WORK_CANCELLED,
90           }                                       dw_state;
91 };
92 
93 struct rcu_work {
94           struct work_struct            work; /* Linux API name */
95           struct rcu_head                         rw_rcu;
96 };
97 
98 #define   WQ_FREEZABLE                  __BIT(0)
99 #define   WQ_HIGHPRI                    __BIT(1)
100 #define   WQ_MEM_RECLAIM                __BIT(2)
101 #define   WQ_UNBOUND                    __BIT(3)
102 
103 #define   WQ_UNBOUND_MAX_ACTIVE         0
104 
105 static inline struct delayed_work *
to_delayed_work(struct work_struct * work)106 to_delayed_work(struct work_struct *work)
107 {
108           return container_of(work, struct delayed_work, work);
109 }
110 
111 extern struct workqueue_struct          *system_highpri_wq;
112 extern struct workqueue_struct          *system_long_wq;
113 extern struct workqueue_struct          *system_power_efficient_wq;
114 extern struct workqueue_struct          *system_unbound_wq;
115 extern struct workqueue_struct          *system_wq;
116 
117 int       linux_workqueue_init(void);
118 void      linux_workqueue_fini(void);
119 
120 #define   create_singlethread_workqueue(name)                                         \
121           alloc_ordered_workqueue((name), 0)
122 
123 struct workqueue_struct *
124           alloc_workqueue(const char *, int, unsigned);
125 struct workqueue_struct *
126           alloc_ordered_workqueue(const char *, int);
127 void      destroy_workqueue(struct workqueue_struct *);
128 void      flush_workqueue(struct workqueue_struct *);
129 void      drain_workqueue(struct workqueue_struct *);
130 void      flush_scheduled_work(void);
131 
132 void      INIT_WORK(struct work_struct *, void (*)(struct work_struct *));
133 bool      schedule_work(struct work_struct *);
134 bool      queue_work(struct workqueue_struct *, struct work_struct *);
135 bool      cancel_work(struct work_struct *);
136 bool      cancel_work_sync(struct work_struct *);
137 bool      flush_work(struct work_struct *);
138 bool      work_pending(const struct work_struct *);
139 
140 void      INIT_DELAYED_WORK(struct delayed_work *,
141               void (*)(struct work_struct *));
142 bool      schedule_delayed_work(struct delayed_work *, unsigned long);
143 bool      queue_delayed_work(struct workqueue_struct *, struct delayed_work *,
144               unsigned long ticks);
145 bool      mod_delayed_work(struct workqueue_struct *, struct delayed_work *,
146               unsigned long ticks);
147 bool      cancel_delayed_work(struct delayed_work *);
148 bool      cancel_delayed_work_sync(struct delayed_work *);
149 bool      flush_delayed_work(struct delayed_work *);
150 bool      delayed_work_pending(const struct delayed_work *);
151 
152 void      INIT_RCU_WORK(struct rcu_work *, void (*fn)(struct work_struct *));
153 void      queue_rcu_work(struct workqueue_struct *, struct rcu_work *);
154 
155 struct work_struct *
156           current_work(void);
157 
158 #define   INIT_WORK_ONSTACK             INIT_WORK
159 #define   INIT_DELAYED_WORK_ONSTACK     INIT_DELAYED_WORK
160 #define   destroy_delayed_work_on_stack(dw)       __nothing
161 
162 static inline void
destroy_work_on_stack(struct work_struct * work)163 destroy_work_on_stack(struct work_struct *work)
164 {
165 }
166 
167 #endif  /* _LINUX_WORKQUEUE_H_ */
168