3 #include <linux/kthread.h>
4 #include <linux/slab.h>
5 #include <linux/workqueue.h>
7 static pthread_mutex_t wq_lock = PTHREAD_MUTEX_INITIALIZER;
8 static pthread_cond_t work_finished = PTHREAD_COND_INITIALIZER;
9 static LIST_HEAD(wq_list);
11 struct workqueue_struct {
12 struct list_head list;
14 struct work_struct *current_work;
15 struct list_head pending_work;
17 struct task_struct *worker;
25 static bool work_pending(struct work_struct *work)
27 return test_bit(WORK_PENDING_BIT, work_data_bits(work));
30 static void clear_work_pending(struct work_struct *work)
32 clear_bit(WORK_PENDING_BIT, work_data_bits(work));
35 static bool set_work_pending(struct work_struct *work)
37 return !test_and_set_bit(WORK_PENDING_BIT, work_data_bits(work));
40 static void __queue_work(struct workqueue_struct *wq,
41 struct work_struct *work)
43 BUG_ON(!work_pending(work));
44 BUG_ON(!list_empty(&work->entry));
46 list_add_tail(&work->entry, &wq->pending_work);
47 wake_up_process(wq->worker);
50 bool queue_work(struct workqueue_struct *wq, struct work_struct *work)
54 pthread_mutex_lock(&wq_lock);
55 if ((ret = set_work_pending(work)))
56 __queue_work(wq, work);
57 pthread_mutex_unlock(&wq_lock);
62 void delayed_work_timer_fn(struct timer_list *timer)
64 struct delayed_work *dwork =
65 container_of(timer, struct delayed_work, timer);
67 pthread_mutex_lock(&wq_lock);
68 __queue_work(dwork->wq, &dwork->work);
69 pthread_mutex_unlock(&wq_lock);
72 static void __queue_delayed_work(struct workqueue_struct *wq,
73 struct delayed_work *dwork,
76 struct timer_list *timer = &dwork->timer;
77 struct work_struct *work = &dwork->work;
79 BUG_ON(timer->function != delayed_work_timer_fn);
80 BUG_ON(timer_pending(timer));
81 BUG_ON(!list_empty(&work->entry));
84 __queue_work(wq, &dwork->work);
87 timer->expires = jiffies + delay;
92 bool queue_delayed_work(struct workqueue_struct *wq,
93 struct delayed_work *dwork,
96 struct work_struct *work = &dwork->work;
99 pthread_mutex_lock(&wq_lock);
100 if ((ret = set_work_pending(work)))
101 __queue_delayed_work(wq, dwork, delay);
102 pthread_mutex_unlock(&wq_lock);
107 static bool grab_pending(struct work_struct *work, bool is_dwork)
110 if (set_work_pending(work)) {
111 BUG_ON(!list_empty(&work->entry));
116 struct delayed_work *dwork = to_delayed_work(work);
118 if (likely(del_timer(&dwork->timer))) {
119 BUG_ON(!list_empty(&work->entry));
124 if (!list_empty(&work->entry)) {
125 list_del_init(&work->entry);
131 pthread_mutex_unlock(&wq_lock);
133 pthread_mutex_lock(&wq_lock);
137 static bool work_running(struct work_struct *work)
139 struct workqueue_struct *wq;
141 list_for_each_entry(wq, &wq_list, list)
142 if (wq->current_work == work)
148 bool flush_work(struct work_struct *work)
152 pthread_mutex_lock(&wq_lock);
153 while (work_pending(work) || work_running(work)) {
154 pthread_cond_wait(&work_finished, &wq_lock);
157 pthread_mutex_unlock(&wq_lock);
162 static bool __flush_work(struct work_struct *work)
166 while (work_running(work)) {
167 pthread_cond_wait(&work_finished, &wq_lock);
174 bool cancel_work_sync(struct work_struct *work)
178 pthread_mutex_lock(&wq_lock);
179 ret = grab_pending(work, false);
182 clear_work_pending(work);
183 pthread_mutex_unlock(&wq_lock);
188 bool mod_delayed_work(struct workqueue_struct *wq,
189 struct delayed_work *dwork,
192 struct work_struct *work = &dwork->work;
195 pthread_mutex_lock(&wq_lock);
196 ret = grab_pending(work, true);
198 __queue_delayed_work(wq, dwork, delay);
199 pthread_mutex_unlock(&wq_lock);
204 bool cancel_delayed_work(struct delayed_work *dwork)
206 struct work_struct *work = &dwork->work;
209 pthread_mutex_lock(&wq_lock);
210 ret = grab_pending(work, true);
212 clear_work_pending(&dwork->work);
213 pthread_mutex_unlock(&wq_lock);
218 bool cancel_delayed_work_sync(struct delayed_work *dwork)
220 struct work_struct *work = &dwork->work;
223 pthread_mutex_lock(&wq_lock);
224 ret = grab_pending(work, true);
227 clear_work_pending(work);
228 pthread_mutex_unlock(&wq_lock);
233 static int worker_thread(void *arg)
235 struct workqueue_struct *wq = arg;
236 struct work_struct *work;
238 pthread_mutex_lock(&wq_lock);
240 __set_current_state(TASK_INTERRUPTIBLE);
241 work = list_first_entry_or_null(&wq->pending_work,
242 struct work_struct, entry);
243 wq->current_work = work;
245 if (kthread_should_stop()) {
246 BUG_ON(wq->current_work);
251 pthread_mutex_unlock(&wq_lock);
253 pthread_mutex_lock(&wq_lock);
257 BUG_ON(!work_pending(work));
258 list_del_init(&work->entry);
259 clear_work_pending(work);
261 pthread_mutex_unlock(&wq_lock);
263 pthread_mutex_lock(&wq_lock);
265 pthread_cond_broadcast(&work_finished);
267 pthread_mutex_unlock(&wq_lock);
272 void destroy_workqueue(struct workqueue_struct *wq)
274 kthread_stop(wq->worker);
276 pthread_mutex_lock(&wq_lock);
278 pthread_mutex_unlock(&wq_lock);
283 struct workqueue_struct *alloc_workqueue(const char *fmt,
289 struct workqueue_struct *wq;
291 wq = kzalloc(sizeof(*wq), GFP_KERNEL);
295 INIT_LIST_HEAD(&wq->list);
296 INIT_LIST_HEAD(&wq->pending_work);
298 va_start(args, max_active);
299 vsnprintf(wq->name, sizeof(wq->name), fmt, args);
302 wq->worker = kthread_run(worker_thread, wq, "%s", wq->name);
303 if (IS_ERR(wq->worker)) {
308 pthread_mutex_lock(&wq_lock);
309 list_add(&wq->list, &wq_list);
310 pthread_mutex_unlock(&wq_lock);
315 struct workqueue_struct *system_wq;
316 struct workqueue_struct *system_highpri_wq;
317 struct workqueue_struct *system_long_wq;
318 struct workqueue_struct *system_unbound_wq;
319 struct workqueue_struct *system_freezable_wq;
321 __attribute__((constructor(102)))
322 static void wq_init(void)
324 system_wq = alloc_workqueue("events", 0, 0);
325 system_highpri_wq = alloc_workqueue("events_highpri", WQ_HIGHPRI, 0);
326 system_long_wq = alloc_workqueue("events_long", 0, 0);
327 system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND,
328 WQ_UNBOUND_MAX_ACTIVE);
329 system_freezable_wq = alloc_workqueue("events_freezable",
331 BUG_ON(!system_wq || !system_highpri_wq || !system_long_wq ||
332 !system_unbound_wq || !system_freezable_wq);
335 __attribute__((destructor(102)))
336 static void wq_cleanup(void)
338 destroy_workqueue(system_freezable_wq);
339 destroy_workqueue(system_unbound_wq);
340 destroy_workqueue(system_long_wq);
341 destroy_workqueue(system_highpri_wq);
342 destroy_workqueue(system_wq);
344 system_wq = system_highpri_wq = system_long_wq = system_unbound_wq =
345 system_freezable_wq = NULL;