aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/workqueue.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/workqueue.h')
-rw-r--r--include/linux/workqueue.h99
1 files changed, 75 insertions, 24 deletions
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index ecc017d24cf3..4a3ea83c6d16 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -11,18 +11,19 @@
11 11
12struct workqueue_struct; 12struct workqueue_struct;
13 13
14typedef void (*work_func_t)(void *data); 14struct work_struct;
15typedef void (*work_func_t)(struct work_struct *work);
15 16
16struct work_struct { 17struct work_struct {
17 /* the first word is the work queue pointer and the pending flag 18 /* the first word is the work queue pointer and the flags rolled into
18 * rolled into one */ 19 * one */
19 unsigned long management; 20 unsigned long management;
20#define WORK_STRUCT_PENDING 0 /* T if work item pending execution */ 21#define WORK_STRUCT_PENDING 0 /* T if work item pending execution */
22#define WORK_STRUCT_NOAUTOREL 1 /* F if work item automatically released on exec */
21#define WORK_STRUCT_FLAG_MASK (3UL) 23#define WORK_STRUCT_FLAG_MASK (3UL)
22#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK) 24#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
23 struct list_head entry; 25 struct list_head entry;
24 work_func_t func; 26 work_func_t func;
25 void *data;
26}; 27};
27 28
28struct delayed_work { 29struct delayed_work {
@@ -34,48 +35,77 @@ struct execute_work {
34 struct work_struct work; 35 struct work_struct work;
35}; 36};
36 37
37#define __WORK_INITIALIZER(n, f, d) { \ 38#define __WORK_INITIALIZER(n, f) { \
39 .management = 0, \
38 .entry = { &(n).entry, &(n).entry }, \ 40 .entry = { &(n).entry, &(n).entry }, \
39 .func = (f), \ 41 .func = (f), \
40 .data = (d), \
41 } 42 }
42 43
43#define __DELAYED_WORK_INITIALIZER(n, f, d) { \ 44#define __WORK_INITIALIZER_NAR(n, f) { \
44 .work = __WORK_INITIALIZER((n).work, (f), (d)), \ 45 .management = (1 << WORK_STRUCT_NOAUTOREL), \
46 .entry = { &(n).entry, &(n).entry }, \
47 .func = (f), \
48 }
49
50#define __DELAYED_WORK_INITIALIZER(n, f) { \
51 .work = __WORK_INITIALIZER((n).work, (f)), \
52 .timer = TIMER_INITIALIZER(NULL, 0, 0), \
53 }
54
55#define __DELAYED_WORK_INITIALIZER_NAR(n, f) { \
56 .work = __WORK_INITIALIZER_NAR((n).work, (f)), \
45 .timer = TIMER_INITIALIZER(NULL, 0, 0), \ 57 .timer = TIMER_INITIALIZER(NULL, 0, 0), \
46 } 58 }
47 59
48#define DECLARE_WORK(n, f, d) \ 60#define DECLARE_WORK(n, f) \
49 struct work_struct n = __WORK_INITIALIZER(n, f, d) 61 struct work_struct n = __WORK_INITIALIZER(n, f)
62
63#define DECLARE_WORK_NAR(n, f) \
64 struct work_struct n = __WORK_INITIALIZER_NAR(n, f)
50 65
51#define DECLARE_DELAYED_WORK(n, f, d) \ 66#define DECLARE_DELAYED_WORK(n, f) \
52 struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f, d) 67 struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f)
68
69#define DECLARE_DELAYED_WORK_NAR(n, f) \
70 struct dwork_struct n = __DELAYED_WORK_INITIALIZER_NAR(n, f)
53 71
54/* 72/*
55 * initialize a work item's function and data pointers 73 * initialize a work item's function pointer
56 */ 74 */
57#define PREPARE_WORK(_work, _func, _data) \ 75#define PREPARE_WORK(_work, _func) \
58 do { \ 76 do { \
59 (_work)->func = (_func); \ 77 (_work)->func = (_func); \
60 (_work)->data = (_data); \
61 } while (0) 78 } while (0)
62 79
63#define PREPARE_DELAYED_WORK(_work, _func, _data) \ 80#define PREPARE_DELAYED_WORK(_work, _func) \
64 PREPARE_WORK(&(_work)->work, (_func), (_data)) 81 PREPARE_WORK(&(_work)->work, (_func))
65 82
66/* 83/*
67 * initialize all of a work item in one go 84 * initialize all of a work item in one go
68 */ 85 */
69#define INIT_WORK(_work, _func, _data) \ 86#define INIT_WORK(_work, _func) \
70 do { \ 87 do { \
71 INIT_LIST_HEAD(&(_work)->entry); \
72 (_work)->management = 0; \ 88 (_work)->management = 0; \
73 PREPARE_WORK((_work), (_func), (_data)); \ 89 INIT_LIST_HEAD(&(_work)->entry); \
90 PREPARE_WORK((_work), (_func)); \
91 } while (0)
92
93#define INIT_WORK_NAR(_work, _func) \
94 do { \
95 (_work)->management = (1 << WORK_STRUCT_NOAUTOREL); \
96 INIT_LIST_HEAD(&(_work)->entry); \
97 PREPARE_WORK((_work), (_func)); \
98 } while (0)
99
100#define INIT_DELAYED_WORK(_work, _func) \
101 do { \
102 INIT_WORK(&(_work)->work, (_func)); \
103 init_timer(&(_work)->timer); \
74 } while (0) 104 } while (0)
75 105
76#define INIT_DELAYED_WORK(_work, _func, _data) \ 106#define INIT_DELAYED_WORK_NAR(_work, _func) \
77 do { \ 107 do { \
78 INIT_WORK(&(_work)->work, (_func), (_data)); \ 108 INIT_WORK_NAR(&(_work)->work, (_func)); \
79 init_timer(&(_work)->timer); \ 109 init_timer(&(_work)->timer); \
80 } while (0) 110 } while (0)
81 111
@@ -94,6 +124,27 @@ struct execute_work {
94#define delayed_work_pending(work) \ 124#define delayed_work_pending(work) \
95 test_bit(WORK_STRUCT_PENDING, &(work)->work.management) 125 test_bit(WORK_STRUCT_PENDING, &(work)->work.management)
96 126
127/**
128 * work_release - Release a work item under execution
129 * @work: The work item to release
130 *
131 * This is used to release a work item that has been initialised with automatic
132 * release mode disabled (WORK_STRUCT_NOAUTOREL is set). This gives the work
133 * function the opportunity to grab auxiliary data from the container of the
134 * work_struct before clearing the pending bit as the work_struct may be
135 * subject to deallocation the moment the pending bit is cleared.
136 *
137 * In such a case, this should be called in the work function after it has
138 * fetched any data it may require from the containter of the work_struct.
139 * After this function has been called, the work_struct may be scheduled for
140 * further execution or it may be deallocated unless other precautions are
141 * taken.
142 *
143 * This should also be used to release a delayed work item.
144 */
145#define work_release(work) \
146 clear_bit(WORK_STRUCT_PENDING, &(work)->management)
147
97 148
98extern struct workqueue_struct *__create_workqueue(const char *name, 149extern struct workqueue_struct *__create_workqueue(const char *name,
99 int singlethread); 150 int singlethread);
@@ -112,7 +163,7 @@ extern int FASTCALL(schedule_work(struct work_struct *work));
112extern int FASTCALL(schedule_delayed_work(struct delayed_work *work, unsigned long delay)); 163extern int FASTCALL(schedule_delayed_work(struct delayed_work *work, unsigned long delay));
113 164
114extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, unsigned long delay); 165extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, unsigned long delay);
115extern int schedule_on_each_cpu(work_func_t func, void *info); 166extern int schedule_on_each_cpu(work_func_t func);
116extern void flush_scheduled_work(void); 167extern void flush_scheduled_work(void);
117extern int current_is_keventd(void); 168extern int current_is_keventd(void);
118extern int keventd_up(void); 169extern int keventd_up(void);
@@ -121,7 +172,7 @@ extern void init_workqueues(void);
121void cancel_rearming_delayed_work(struct delayed_work *work); 172void cancel_rearming_delayed_work(struct delayed_work *work);
122void cancel_rearming_delayed_workqueue(struct workqueue_struct *, 173void cancel_rearming_delayed_workqueue(struct workqueue_struct *,
123 struct delayed_work *); 174 struct delayed_work *);
124int execute_in_process_context(work_func_t fn, void *, struct execute_work *); 175int execute_in_process_context(work_func_t fn, struct execute_work *);
125 176
126/* 177/*
127 * Kill off a pending schedule_delayed_work(). Note that the work callback 178 * Kill off a pending schedule_delayed_work(). Note that the work callback