aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/workqueue.h
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2006-11-22 09:54:01 -0500
committerDavid Howells <dhowells@redhat.com>2006-11-22 09:54:01 -0500
commit52bad64d95bd89e08c49ec5a071fa6dcbe5a1a9c (patch)
tree5849b4e3c17daa70a7e81cfdeaddac9ac8a0e953 /include/linux/workqueue.h
parent0f9005a6f7a82f4aacbd72f7b92322a8ca1c3f97 (diff)
WorkStruct: Separate delayable and non-delayable events.
Separate delayable work items from non-delayable work items be splitting them into a separate structure (delayed_work), which incorporates a work_struct and the timer_list removed from work_struct. The work_struct struct is huge, and this limits it's usefulness. On a 64-bit architecture it's nearly 100 bytes in size. This reduces that by half for the non-delayable type of event. Signed-Off-By: David Howells <dhowells@redhat.com>
Diffstat (limited to 'include/linux/workqueue.h')
-rw-r--r--include/linux/workqueue.h44
1 files changed, 32 insertions, 12 deletions
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index 9bca3539a1e5..9faaccae570e 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -17,6 +17,10 @@ struct work_struct {
17 void (*func)(void *); 17 void (*func)(void *);
18 void *data; 18 void *data;
19 void *wq_data; 19 void *wq_data;
20};
21
22struct delayed_work {
23 struct work_struct work;
20 struct timer_list timer; 24 struct timer_list timer;
21}; 25};
22 26
@@ -28,32 +32,48 @@ struct execute_work {
28 .entry = { &(n).entry, &(n).entry }, \ 32 .entry = { &(n).entry, &(n).entry }, \
29 .func = (f), \ 33 .func = (f), \
30 .data = (d), \ 34 .data = (d), \
35 }
36
37#define __DELAYED_WORK_INITIALIZER(n, f, d) { \
38 .work = __WORK_INITIALIZER((n).work, (f), (d)), \
31 .timer = TIMER_INITIALIZER(NULL, 0, 0), \ 39 .timer = TIMER_INITIALIZER(NULL, 0, 0), \
32 } 40 }
33 41
34#define DECLARE_WORK(n, f, d) \ 42#define DECLARE_WORK(n, f, d) \
35 struct work_struct n = __WORK_INITIALIZER(n, f, d) 43 struct work_struct n = __WORK_INITIALIZER(n, f, d)
36 44
45#define DECLARE_DELAYED_WORK(n, f, d) \
46 struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f, d)
47
37/* 48/*
38 * initialize a work-struct's func and data pointers: 49 * initialize a work item's function and data pointers
39 */ 50 */
40#define PREPARE_WORK(_work, _func, _data) \ 51#define PREPARE_WORK(_work, _func, _data) \
41 do { \ 52 do { \
42 (_work)->func = _func; \ 53 (_work)->func = (_func); \
43 (_work)->data = _data; \ 54 (_work)->data = (_data); \
44 } while (0) 55 } while (0)
45 56
57#define PREPARE_DELAYED_WORK(_work, _func, _data) \
58 PREPARE_WORK(&(_work)->work, (_func), (_data))
59
46/* 60/*
47 * initialize all of a work-struct: 61 * initialize all of a work item in one go
48 */ 62 */
49#define INIT_WORK(_work, _func, _data) \ 63#define INIT_WORK(_work, _func, _data) \
50 do { \ 64 do { \
51 INIT_LIST_HEAD(&(_work)->entry); \ 65 INIT_LIST_HEAD(&(_work)->entry); \
52 (_work)->pending = 0; \ 66 (_work)->pending = 0; \
53 PREPARE_WORK((_work), (_func), (_data)); \ 67 PREPARE_WORK((_work), (_func), (_data)); \
68 } while (0)
69
70#define INIT_DELAYED_WORK(_work, _func, _data) \
71 do { \
72 INIT_WORK(&(_work)->work, (_func), (_data)); \
54 init_timer(&(_work)->timer); \ 73 init_timer(&(_work)->timer); \
55 } while (0) 74 } while (0)
56 75
76
57extern struct workqueue_struct *__create_workqueue(const char *name, 77extern struct workqueue_struct *__create_workqueue(const char *name,
58 int singlethread); 78 int singlethread);
59#define create_workqueue(name) __create_workqueue((name), 0) 79#define create_workqueue(name) __create_workqueue((name), 0)
@@ -62,24 +82,24 @@ extern struct workqueue_struct *__create_workqueue(const char *name,
62extern void destroy_workqueue(struct workqueue_struct *wq); 82extern void destroy_workqueue(struct workqueue_struct *wq);
63 83
64extern int FASTCALL(queue_work(struct workqueue_struct *wq, struct work_struct *work)); 84extern int FASTCALL(queue_work(struct workqueue_struct *wq, struct work_struct *work));
65extern int FASTCALL(queue_delayed_work(struct workqueue_struct *wq, struct work_struct *work, unsigned long delay)); 85extern int FASTCALL(queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *work, unsigned long delay));
66extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, 86extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
67 struct work_struct *work, unsigned long delay); 87 struct delayed_work *work, unsigned long delay);
68extern void FASTCALL(flush_workqueue(struct workqueue_struct *wq)); 88extern void FASTCALL(flush_workqueue(struct workqueue_struct *wq));
69 89
70extern int FASTCALL(schedule_work(struct work_struct *work)); 90extern int FASTCALL(schedule_work(struct work_struct *work));
71extern int FASTCALL(schedule_delayed_work(struct work_struct *work, unsigned long delay)); 91extern int FASTCALL(schedule_delayed_work(struct delayed_work *work, unsigned long delay));
72 92
73extern int schedule_delayed_work_on(int cpu, struct work_struct *work, unsigned long delay); 93extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, unsigned long delay);
74extern int schedule_on_each_cpu(void (*func)(void *info), void *info); 94extern int schedule_on_each_cpu(void (*func)(void *info), void *info);
75extern void flush_scheduled_work(void); 95extern void flush_scheduled_work(void);
76extern int current_is_keventd(void); 96extern int current_is_keventd(void);
77extern int keventd_up(void); 97extern int keventd_up(void);
78 98
79extern void init_workqueues(void); 99extern void init_workqueues(void);
80void cancel_rearming_delayed_work(struct work_struct *work); 100void cancel_rearming_delayed_work(struct delayed_work *work);
81void cancel_rearming_delayed_workqueue(struct workqueue_struct *, 101void cancel_rearming_delayed_workqueue(struct workqueue_struct *,
82 struct work_struct *); 102 struct delayed_work *);
83int execute_in_process_context(void (*fn)(void *), void *, 103int execute_in_process_context(void (*fn)(void *), void *,
84 struct execute_work *); 104 struct execute_work *);
85 105
@@ -88,13 +108,13 @@ int execute_in_process_context(void (*fn)(void *), void *,
88 * function may still be running on return from cancel_delayed_work(). Run 108 * function may still be running on return from cancel_delayed_work(). Run
89 * flush_scheduled_work() to wait on it. 109 * flush_scheduled_work() to wait on it.
90 */ 110 */
91static inline int cancel_delayed_work(struct work_struct *work) 111static inline int cancel_delayed_work(struct delayed_work *work)
92{ 112{
93 int ret; 113 int ret;
94 114
95 ret = del_timer_sync(&work->timer); 115 ret = del_timer_sync(&work->timer);
96 if (ret) 116 if (ret)
97 clear_bit(0, &work->pending); 117 clear_bit(0, &work->work.pending);
98 return ret; 118 return ret;
99} 119}
100 120