diff options
Diffstat (limited to 'include/linux/workqueue.h')
-rw-r--r-- | include/linux/workqueue.h | 99 |
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 | ||
12 | struct workqueue_struct; | 12 | struct workqueue_struct; |
13 | 13 | ||
14 | typedef void (*work_func_t)(void *data); | 14 | struct work_struct; |
15 | typedef void (*work_func_t)(struct work_struct *work); | ||
15 | 16 | ||
16 | struct work_struct { | 17 | struct 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 | ||
28 | struct delayed_work { | 29 | struct 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 | ||
98 | extern struct workqueue_struct *__create_workqueue(const char *name, | 149 | extern 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)); | |||
112 | extern int FASTCALL(schedule_delayed_work(struct delayed_work *work, unsigned long delay)); | 163 | extern int FASTCALL(schedule_delayed_work(struct delayed_work *work, unsigned long delay)); |
113 | 164 | ||
114 | extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, unsigned long delay); | 165 | extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, unsigned long delay); |
115 | extern int schedule_on_each_cpu(work_func_t func, void *info); | 166 | extern int schedule_on_each_cpu(work_func_t func); |
116 | extern void flush_scheduled_work(void); | 167 | extern void flush_scheduled_work(void); |
117 | extern int current_is_keventd(void); | 168 | extern int current_is_keventd(void); |
118 | extern int keventd_up(void); | 169 | extern int keventd_up(void); |
@@ -121,7 +172,7 @@ extern void init_workqueues(void); | |||
121 | void cancel_rearming_delayed_work(struct delayed_work *work); | 172 | void cancel_rearming_delayed_work(struct delayed_work *work); |
122 | void cancel_rearming_delayed_workqueue(struct workqueue_struct *, | 173 | void cancel_rearming_delayed_workqueue(struct workqueue_struct *, |
123 | struct delayed_work *); | 174 | struct delayed_work *); |
124 | int execute_in_process_context(work_func_t fn, void *, struct execute_work *); | 175 | int 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 |