Rev 3763 | Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3482 | Serge | 1 | #include |
2 | #include |
||
3 | #include |
||
4 | |||
5 | struct workqueue_struct *alloc_workqueue(const char *fmt, |
||
6 | unsigned int flags, |
||
7 | int max_active) |
||
8 | { |
||
9 | struct workqueue_struct *wq; |
||
10 | |||
11 | wq = kzalloc(sizeof(*wq),0); |
||
12 | if (!wq) |
||
13 | goto err; |
||
14 | |||
15 | INIT_LIST_HEAD(&wq->worklist); |
||
16 | INIT_LIST_HEAD(&wq->delayed_worklist); |
||
17 | |||
18 | return wq; |
||
19 | err: |
||
20 | return NULL; |
||
21 | } |
||
22 | |||
23 | |||
24 | |||
25 | void run_workqueue(struct workqueue_struct *cwq) |
||
26 | { |
||
27 | unsigned long irqflags; |
||
28 | |||
29 | // dbgprintf("wq: %x head %x, next %x\n", |
||
30 | // cwq, &cwq->worklist, cwq->worklist.next); |
||
31 | |||
32 | repeat: |
||
33 | |||
34 | spin_lock_irqsave(&cwq->lock, irqflags); |
||
35 | |||
36 | while (!list_empty(&cwq->worklist)) |
||
37 | { |
||
38 | struct work_struct *work = list_entry(cwq->worklist.next, |
||
39 | struct work_struct, entry); |
||
40 | work_func_t f = work->func; |
||
41 | list_del_init(cwq->worklist.next); |
||
42 | // dbgprintf("head %x, next %x\n", |
||
43 | // &cwq->worklist, cwq->worklist.next); |
||
44 | |||
45 | spin_unlock_irqrestore(&cwq->lock, irqflags); |
||
46 | f(work); |
||
47 | spin_lock_irqsave(&cwq->lock, irqflags); |
||
48 | } |
||
49 | |||
50 | spin_unlock_irqrestore(&cwq->lock, irqflags); |
||
51 | |||
52 | delay(1); |
||
53 | |||
54 | goto repeat; |
||
55 | } |
||
56 | |||
57 | |||
58 | bool queue_work(struct workqueue_struct *wq, struct work_struct *work) |
||
59 | { |
||
60 | unsigned long flags; |
||
61 | |||
62 | if(!list_empty(&work->entry)) |
||
63 | return 0; |
||
64 | |||
65 | // dbgprintf("%s %p queue: %p\n", __FUNCTION__, work, wq); |
||
66 | |||
67 | spin_lock_irqsave(&wq->lock, flags); |
||
68 | |||
69 | list_add_tail(&work->entry, &wq->worklist); |
||
70 | |||
71 | spin_unlock_irqrestore(&wq->lock, flags); |
||
72 | |||
73 | return 1; |
||
74 | }; |
||
75 | |||
76 | |||
77 | void __stdcall delayed_work_timer_fn(unsigned long __data) |
||
78 | { |
||
79 | struct delayed_work *dwork = (struct delayed_work *)__data; |
||
80 | struct workqueue_struct *wq = dwork->work.data; |
||
81 | |||
82 | queue_work(wq, &dwork->work); |
||
83 | } |
||
84 | |||
85 | int queue_delayed_work(struct workqueue_struct *wq, |
||
86 | struct delayed_work *dwork, unsigned long delay) |
||
87 | { |
||
88 | struct work_struct *work = &dwork->work; |
||
89 | |||
90 | if (delay == 0) |
||
91 | return queue_work(wq, &dwork->work); |
||
92 | |||
93 | // dbgprintf("%s %p queue: %p\n", __FUNCTION__, &dwork->work, wq); |
||
94 | |||
95 | work->data = wq; |
||
96 | TimerHs(delay,0, delayed_work_timer_fn, dwork); |
||
97 | return 1; |
||
98 | } |
||
99 | |||
100 | |||
101 | bool schedule_delayed_work(struct delayed_work *dwork, unsigned long delay) |
||
102 | { |
||
103 | return queue_delayed_work(system_wq, dwork, delay); |
||
104 | } |
||
105 |