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