Rev 6082 | Rev 6125 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5270 | serge | 1 | /* |
2 | * workqueue.h --- work queue handling for Linux. |
||
3 | */ |
||
4 | |||
3482 | Serge | 5 | #ifndef _LINUX_WORKQUEUE_H |
6 | #define _LINUX_WORKQUEUE_H |
||
7 | |||
8 | #include |
||
5270 | serge | 9 | #include |
6102 | serge | 10 | #include |
5270 | serge | 11 | #include |
12 | #include |
||
5272 | serge | 13 | #include |
6102 | serge | 14 | #include |
5270 | serge | 15 | |
16 | struct workqueue_struct; |
||
3482 | Serge | 17 | |
18 | struct work_struct; |
||
19 | typedef void (*work_func_t)(struct work_struct *work); |
||
5270 | serge | 20 | void __stdcall delayed_work_timer_fn(unsigned long __data); |
3482 | Serge | 21 | |
22 | /* |
||
6102 | serge | 23 | * The first word is the work queue pointer and the flags rolled into |
24 | * one |
||
3482 | Serge | 25 | */ |
6102 | serge | 26 | #define work_data_bits(work) ((unsigned long *)(&(work)->data)) |
27 | |||
3482 | Serge | 28 | enum { |
6102 | serge | 29 | WORK_STRUCT_PENDING_BIT = 0, /* work item is pending execution */ |
30 | WORK_STRUCT_DELAYED_BIT = 1, /* work item is delayed */ |
||
31 | WORK_STRUCT_PWQ_BIT = 2, /* data points to pwq */ |
||
32 | WORK_STRUCT_LINKED_BIT = 3, /* next work is linked to this one */ |
||
33 | #ifdef CONFIG_DEBUG_OBJECTS_WORK |
||
34 | WORK_STRUCT_STATIC_BIT = 4, /* static initializer (debugobjects) */ |
||
35 | WORK_STRUCT_COLOR_SHIFT = 5, /* color for workqueue flushing */ |
||
36 | #else |
||
37 | WORK_STRUCT_COLOR_SHIFT = 4, /* color for workqueue flushing */ |
||
38 | #endif |
||
3482 | Serge | 39 | |
6102 | serge | 40 | WORK_STRUCT_COLOR_BITS = 4, |
3482 | Serge | 41 | |
6102 | serge | 42 | WORK_STRUCT_PENDING = 1 << WORK_STRUCT_PENDING_BIT, |
43 | WORK_STRUCT_DELAYED = 1 << WORK_STRUCT_DELAYED_BIT, |
||
44 | WORK_STRUCT_PWQ = 1 << WORK_STRUCT_PWQ_BIT, |
||
45 | WORK_STRUCT_LINKED = 1 << WORK_STRUCT_LINKED_BIT, |
||
46 | #ifdef CONFIG_DEBUG_OBJECTS_WORK |
||
47 | WORK_STRUCT_STATIC = 1 << WORK_STRUCT_STATIC_BIT, |
||
48 | #else |
||
49 | WORK_STRUCT_STATIC = 0, |
||
50 | #endif |
||
3482 | Serge | 51 | |
6102 | serge | 52 | /* |
53 | * The last color is no color used for works which don't |
||
54 | * participate in workqueue flushing. |
||
55 | */ |
||
56 | WORK_NR_COLORS = (1 << WORK_STRUCT_COLOR_BITS) - 1, |
||
57 | WORK_NO_COLOR = WORK_NR_COLORS, |
||
3482 | Serge | 58 | |
6102 | serge | 59 | /* not bound to any CPU, prefer the local CPU */ |
60 | WORK_CPU_UNBOUND = NR_CPUS, |
||
61 | |||
62 | /* |
||
63 | * Reserve 7 bits off of pwq pointer w/ debugobjects turned off. |
||
64 | * This makes pwqs aligned to 256 bytes and allows 15 workqueue |
||
65 | * flush colors. |
||
66 | */ |
||
67 | WORK_STRUCT_FLAG_BITS = WORK_STRUCT_COLOR_SHIFT + |
||
68 | WORK_STRUCT_COLOR_BITS, |
||
69 | |||
70 | /* data contains off-queue information when !WORK_STRUCT_PWQ */ |
||
71 | WORK_OFFQ_FLAG_BASE = WORK_STRUCT_COLOR_SHIFT, |
||
72 | |||
73 | __WORK_OFFQ_CANCELING = WORK_OFFQ_FLAG_BASE, |
||
74 | WORK_OFFQ_CANCELING = (1 << __WORK_OFFQ_CANCELING), |
||
75 | |||
76 | /* |
||
77 | * When a work item is off queue, its high bits point to the last |
||
78 | * pool it was on. Cap at 31 bits and use the highest number to |
||
79 | * indicate that no pool is associated. |
||
80 | */ |
||
81 | WORK_OFFQ_FLAG_BITS = 1, |
||
82 | WORK_OFFQ_POOL_SHIFT = WORK_OFFQ_FLAG_BASE + WORK_OFFQ_FLAG_BITS, |
||
83 | WORK_OFFQ_LEFT = BITS_PER_LONG - WORK_OFFQ_POOL_SHIFT, |
||
84 | WORK_OFFQ_POOL_BITS = WORK_OFFQ_LEFT <= 31 ? WORK_OFFQ_LEFT : 31, |
||
85 | WORK_OFFQ_POOL_NONE = (1LU << WORK_OFFQ_POOL_BITS) - 1, |
||
86 | |||
87 | /* convenience constants */ |
||
88 | WORK_STRUCT_FLAG_MASK = (1UL << WORK_STRUCT_FLAG_BITS) - 1, |
||
89 | WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK, |
||
90 | WORK_STRUCT_NO_POOL = (unsigned long)WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT, |
||
91 | |||
92 | /* bit mask for work_busy() return values */ |
||
93 | WORK_BUSY_PENDING = 1 << 0, |
||
94 | WORK_BUSY_RUNNING = 1 << 1, |
||
95 | |||
96 | /* maximum string length for set_worker_desc() */ |
||
97 | WORKER_DESC_LEN = 24, |
||
3482 | Serge | 98 | }; |
99 | |||
100 | struct work_struct { |
||
6102 | serge | 101 | struct list_head entry; |
102 | struct workqueue_struct *data; |
||
103 | work_func_t func; |
||
5270 | serge | 104 | #ifdef CONFIG_LOCKDEP |
105 | struct lockdep_map lockdep_map; |
||
106 | #endif |
||
3482 | Serge | 107 | }; |
108 | |||
6102 | serge | 109 | #define WORK_DATA_INIT() ATOMIC_LONG_INIT(WORK_STRUCT_NO_POOL) |
110 | #define WORK_DATA_STATIC_INIT() \ |
||
111 | ATOMIC_LONG_INIT(WORK_STRUCT_NO_POOL | WORK_STRUCT_STATIC) |
||
112 | |||
3482 | Serge | 113 | struct delayed_work { |
6102 | serge | 114 | struct work_struct work; |
115 | unsigned int delay; |
||
116 | /* target workqueue and CPU ->timer uses to queue ->work */ |
||
117 | struct workqueue_struct *wq; |
||
118 | int cpu; |
||
3482 | Serge | 119 | }; |
120 | |||
121 | static inline struct delayed_work *to_delayed_work(struct work_struct *work) |
||
122 | { |
||
6082 | serge | 123 | return container_of(work, struct delayed_work, work); |
3482 | Serge | 124 | } |
125 | |||
6102 | serge | 126 | struct execute_work { |
127 | struct work_struct work; |
||
128 | }; |
||
129 | |||
130 | struct workqueue_struct { |
||
131 | spinlock_t lock; |
||
132 | struct list_head worklist; |
||
133 | struct list_head delayed_worklist; |
||
134 | }; |
||
3482 | Serge | 135 | extern struct workqueue_struct *system_wq; |
136 | |||
137 | void run_workqueue(struct workqueue_struct *cwq); |
||
138 | |||
139 | struct workqueue_struct *alloc_workqueue_key(const char *fmt, |
||
140 | unsigned int flags, int max_active); |
||
141 | |||
142 | |||
143 | #define alloc_ordered_workqueue(fmt, flags, args...) \ |
||
144 | alloc_workqueue(fmt, WQ_UNBOUND | (flags), 1, ##args) |
||
145 | |||
4125 | Serge | 146 | bool queue_work(struct workqueue_struct *wq, struct work_struct *work); |
3482 | Serge | 147 | int queue_delayed_work(struct workqueue_struct *wq, |
148 | struct delayed_work *dwork, unsigned long delay); |
||
149 | |||
150 | bool schedule_delayed_work(struct delayed_work *dwork, unsigned long delay); |
||
151 | |||
152 | |||
153 | #define INIT_WORK(_work, _func) \ |
||
154 | do { \ |
||
155 | INIT_LIST_HEAD(&(_work)->entry); \ |
||
156 | (_work)->func = _func; \ |
||
157 | } while (0) |
||
158 | |||
159 | |||
160 | #define INIT_DELAYED_WORK(_work, _func) \ |
||
161 | do { \ |
||
162 | INIT_LIST_HEAD(&(_work)->work.entry); \ |
||
163 | (_work)->work.func = _func; \ |
||
164 | } while (0) |
||
165 | |||
4125 | Serge | 166 | static inline bool schedule_work(struct work_struct *work) |
167 | { |
||
168 | return queue_work(system_wq, work); |
||
169 | } |
||
3482 | Serge | 170 | |
171 | |||
172 | #endif /* _LINUX_WORKQUEUE_H */><>><>><>><>><>=>><>><>><>><>><>><>><> |