| 1 | |
| 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 |
|
| 12 | struct workqueue_struct;
|
| 13 |
|
| 14 | struct work_struct;
|
| 15 | typedef void (*work_func_t)(struct work_struct *work);
|
| 16 |
|
| 17 | struct work_struct {
|
| 18 | |
| 19 | * one
|
| 20 | unsigned long management;
|
| 21 | #define WORK_STRUCT_PENDING 0
|
| 22 | #define WORK_STRUCT_NOAUTOREL 1
|
| 23 | #define WORK_STRUCT_FLAG_MASK (3UL)
|
| 24 | #define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
|
| 25 | struct list_head entry;
|
| 26 | work_func_t func;
|
| 27 | };
|
| 28 |
|
| 29 | struct delayed_work {
|
| 30 | struct work_struct work;
|
| 31 | struct timer_list timer;
|
| 32 | };
|
| 33 |
|
| 34 | struct execute_work {
|
| 35 | struct work_struct work;
|
| 36 | };
|
| 37 |
|
| 38 | #define __WORK_INITIALIZER(n, f) { \
|
| 39 | .management = 0, \
|
| 40 | .entry = { &(n).entry, &(n).entry }, \
|
| 41 | .func = (f), \
|
| 42 | }
|
| 43 |
|
| 44 | #define __WORK_INITIALIZER_NAR(n, f) { \
|
| 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)), \
|
| 57 | .timer = TIMER_INITIALIZER(NULL, 0, 0), \
|
| 58 | }
|
| 59 |
|
| 60 | #define DECLARE_WORK(n, f) \
|
| 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)
|
| 65 |
|
| 66 | #define DECLARE_DELAYED_WORK(n, f) \
|
| 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)
|
| 71 |
|
| 72 | |
| 73 | * initialize a work item's function pointer
|
| 74 |
|
| 75 | #define PREPARE_WORK(_work, _func) \
|
| 76 | do { \
|
| 77 | (_work)->func = (_func); \
|
| 78 | } while (0)
|
| 79 |
|
| 80 | #define PREPARE_DELAYED_WORK(_work, _func) \
|
| 81 | PREPARE_WORK(&(_work)->work, (_func))
|
| 82 |
|
| 83 | |
| 84 | * initialize all of a work item in one go
|
| 85 |
|
| 86 | #define INIT_WORK(_work, _func) \
|
| 87 | do { \
|
| 88 | (_work)->management = 0; \
|
| 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); \
|
| 104 | } while (0)
|
| 105 |
|
| 106 | #define INIT_DELAYED_WORK_NAR(_work, _func) \
|
| 107 | do { \
|
| 108 | INIT_WORK_NAR(&(_work)->work, (_func)); \
|
| 109 | init_timer(&(_work)->timer); \
|
| 110 | } while (0)
|
| 111 |
|
| 112 | |
| 113 | * work_pending - Find out whether a work item is currently pending
|
| 114 | * @work: The work item in question
|
| 115 |
|
| 116 | #define work_pending(work) \
|
| 117 | test_bit(WORK_STRUCT_PENDING, &(work)->management)
|
| 118 |
|
| 119 | |
| 120 | * delayed_work_pending - Find out whether a delayable work item is currently
|
| 121 | * pending
|
| 122 | * @work: The work item in question
|
| 123 |
|
| 124 | #define delayed_work_pending(w) \
|
| 125 | work_pending(&(w)->work)
|
| 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 |
|
| 148 |
|
| 149 | extern struct workqueue_struct *__create_workqueue(const char *name,
|
| 150 | int singlethread,
|
| 151 | int freezeable);
|
| 152 | #define create_workqueue(name) __create_workqueue((name), 0, 0)
|
| 153 | #define create_freezeable_workqueue(name) __create_workqueue((name), 0, 1)
|
| 154 | #define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0)
|
| 155 |
|
| 156 | extern void destroy_workqueue(struct workqueue_struct *wq);
|
| 157 |
|
| 158 | extern int FASTCALL(queue_work(struct workqueue_struct *wq, struct work_struct *work));
|
| 159 | extern int FASTCALL(queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *work, unsigned long delay));
|
| 160 | extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
|
| 161 | struct delayed_work *work, unsigned long delay);
|
| 162 | extern void FASTCALL(flush_workqueue(struct workqueue_struct *wq));
|
| 163 |
|
| 164 | extern int FASTCALL(schedule_work(struct work_struct *work));
|
| 165 | extern int FASTCALL(run_scheduled_work(struct work_struct *work));
|
| 166 | extern int FASTCALL(schedule_delayed_work(struct delayed_work *work, unsigned long delay));
|
| 167 |
|
| 168 | extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, unsigned long delay);
|
| 169 | extern int schedule_on_each_cpu(work_func_t func);
|
| 170 | extern void flush_scheduled_work(void);
|
| 171 | extern int current_is_keventd(void);
|
| 172 | extern int keventd_up(void);
|
| 173 |
|
| 174 | extern void init_workqueues(void);
|
| 175 | void cancel_rearming_delayed_work(struct delayed_work *work);
|
| 176 | void cancel_rearming_delayed_workqueue(struct workqueue_struct *,
|
| 177 | struct delayed_work *);
|
| 178 | int execute_in_process_context(work_func_t fn, struct execute_work *);
|
| 179 |
|
| 180 | |
| 181 | * Kill off a pending schedule_delayed_work(). Note that the work callback
|
| 182 | * function may still be running on return from cancel_delayed_work(). Run
|
| 183 | * flush_scheduled_work() to wait on it.
|
| 184 |
|
| 185 | static inline int cancel_delayed_work(struct delayed_work *work)
|
| 186 | {
|
| 187 | int ret;
|
| 188 |
|
| 189 | ret = del_timer_sync(&work->timer);
|
| 190 | if (ret)
|
| 191 | clear_bit(WORK_STRUCT_PENDING, &work->work.management);
|
| 192 | return ret;
|
| 193 | }
|
| 194 |
|
| 195 | #endif
|