blob: cef40b22ff9a43c69e49f31cfa776bccd039c1e7 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * workqueue.h --- work queue handling for Linux.
3 */
4
5#ifndef _LINUX_WORKQUEUE_H
6#define _LINUX_WORKQUEUE_H
7
8#include <linux/timer.h>
9#include <linux/linkage.h>
10#include <linux/bitops.h>
11
12struct workqueue_struct;
13
David Howells6bb49e52006-11-22 14:54:45 +000014typedef void (*work_func_t)(void *data);
15
Linus Torvalds1da177e2005-04-16 15:20:36 -070016struct work_struct {
17 unsigned long pending;
18 struct list_head entry;
David Howells6bb49e52006-11-22 14:54:45 +000019 work_func_t func;
Linus Torvalds1da177e2005-04-16 15:20:36 -070020 void *data;
21 void *wq_data;
David Howells52bad642006-11-22 14:54:01 +000022};
23
24struct delayed_work {
25 struct work_struct work;
Linus Torvalds1da177e2005-04-16 15:20:36 -070026 struct timer_list timer;
27};
28
James Bottomley1fa44ec2006-02-23 12:43:43 -060029struct execute_work {
30 struct work_struct work;
31};
32
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#define __WORK_INITIALIZER(n, f, d) { \
34 .entry = { &(n).entry, &(n).entry }, \
35 .func = (f), \
36 .data = (d), \
David Howells52bad642006-11-22 14:54:01 +000037 }
38
39#define __DELAYED_WORK_INITIALIZER(n, f, d) { \
40 .work = __WORK_INITIALIZER((n).work, (f), (d)), \
Linus Torvalds1da177e2005-04-16 15:20:36 -070041 .timer = TIMER_INITIALIZER(NULL, 0, 0), \
42 }
43
44#define DECLARE_WORK(n, f, d) \
45 struct work_struct n = __WORK_INITIALIZER(n, f, d)
46
David Howells52bad642006-11-22 14:54:01 +000047#define DECLARE_DELAYED_WORK(n, f, d) \
48 struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f, d)
49
Linus Torvalds1da177e2005-04-16 15:20:36 -070050/*
David Howells52bad642006-11-22 14:54:01 +000051 * initialize a work item's function and data pointers
Linus Torvalds1da177e2005-04-16 15:20:36 -070052 */
53#define PREPARE_WORK(_work, _func, _data) \
54 do { \
David Howells52bad642006-11-22 14:54:01 +000055 (_work)->func = (_func); \
56 (_work)->data = (_data); \
Linus Torvalds1da177e2005-04-16 15:20:36 -070057 } while (0)
58
David Howells52bad642006-11-22 14:54:01 +000059#define PREPARE_DELAYED_WORK(_work, _func, _data) \
60 PREPARE_WORK(&(_work)->work, (_func), (_data))
61
Linus Torvalds1da177e2005-04-16 15:20:36 -070062/*
David Howells52bad642006-11-22 14:54:01 +000063 * initialize all of a work item in one go
Linus Torvalds1da177e2005-04-16 15:20:36 -070064 */
65#define INIT_WORK(_work, _func, _data) \
66 do { \
67 INIT_LIST_HEAD(&(_work)->entry); \
68 (_work)->pending = 0; \
69 PREPARE_WORK((_work), (_func), (_data)); \
David Howells52bad642006-11-22 14:54:01 +000070 } while (0)
71
72#define INIT_DELAYED_WORK(_work, _func, _data) \
73 do { \
74 INIT_WORK(&(_work)->work, (_func), (_data)); \
Linus Torvalds1da177e2005-04-16 15:20:36 -070075 init_timer(&(_work)->timer); \
76 } while (0)
77
David Howells52bad642006-11-22 14:54:01 +000078
Linus Torvalds1da177e2005-04-16 15:20:36 -070079extern struct workqueue_struct *__create_workqueue(const char *name,
80 int singlethread);
81#define create_workqueue(name) __create_workqueue((name), 0)
82#define create_singlethread_workqueue(name) __create_workqueue((name), 1)
83
84extern void destroy_workqueue(struct workqueue_struct *wq);
85
86extern int FASTCALL(queue_work(struct workqueue_struct *wq, struct work_struct *work));
David Howells52bad642006-11-22 14:54:01 +000087extern int FASTCALL(queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *work, unsigned long delay));
Venkatesh Pallipadi7a6bc1c2006-06-28 13:50:33 -070088extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
David Howells52bad642006-11-22 14:54:01 +000089 struct delayed_work *work, unsigned long delay);
Linus Torvalds1da177e2005-04-16 15:20:36 -070090extern void FASTCALL(flush_workqueue(struct workqueue_struct *wq));
91
92extern int FASTCALL(schedule_work(struct work_struct *work));
David Howells52bad642006-11-22 14:54:01 +000093extern int FASTCALL(schedule_delayed_work(struct delayed_work *work, unsigned long delay));
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
David Howells52bad642006-11-22 14:54:01 +000095extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, unsigned long delay);
David Howells6bb49e52006-11-22 14:54:45 +000096extern int schedule_on_each_cpu(work_func_t func, void *info);
Linus Torvalds1da177e2005-04-16 15:20:36 -070097extern void flush_scheduled_work(void);
98extern int current_is_keventd(void);
99extern int keventd_up(void);
100
101extern void init_workqueues(void);
David Howells52bad642006-11-22 14:54:01 +0000102void cancel_rearming_delayed_work(struct delayed_work *work);
James Bottomley81ddef72005-04-16 15:23:59 -0700103void cancel_rearming_delayed_workqueue(struct workqueue_struct *,
David Howells52bad642006-11-22 14:54:01 +0000104 struct delayed_work *);
David Howells6bb49e52006-11-22 14:54:45 +0000105int execute_in_process_context(work_func_t fn, void *, struct execute_work *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106
107/*
108 * Kill off a pending schedule_delayed_work(). Note that the work callback
109 * function may still be running on return from cancel_delayed_work(). Run
110 * flush_scheduled_work() to wait on it.
111 */
David Howells52bad642006-11-22 14:54:01 +0000112static inline int cancel_delayed_work(struct delayed_work *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113{
114 int ret;
115
116 ret = del_timer_sync(&work->timer);
117 if (ret)
David Howells52bad642006-11-22 14:54:01 +0000118 clear_bit(0, &work->work.pending);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 return ret;
120}
121
122#endif