Add a bulk interface to sem_down()
[akaros.git] / kern / src / taskqueue.c
1 /* Copyright (c) 2015 Google Inc
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Hacked BSD taskqueues.  In lieu of actually running a kproc or something that
6  * sleeps on a queue of tasks, we'll just blast out a kmsg.  We can always
7  * change the implementation if we need more control. */
8
9 #include <taskqueue.h>
10 #include <trap.h>
11 #include <kthread.h>
12
13 /* BSD Taskqueue wrappers. */
14 static void __tq_wrapper(uint32_t srcid, long a0, long a1, long a2)
15 {
16         task_fn_t tq_fn = (task_fn_t)a0;
17         void *tq_arg = (void*)a1;
18         tq_fn(tq_arg, 0);
19 }
20
21 int taskqueue_enqueue(struct taskqueue *queue, struct task *task)
22 {
23         send_kernel_message(core_id(), __tq_wrapper, (long)task->ta_func,
24                             (long)task->ta_context, 0, KMSG_ROUTINE);
25         return 0;
26 }
27
28
29 /* Linux workqueue wrappers */
30 void flush_workqueue(struct workqueue_struct *wq)
31 {
32 }
33
34 void destroy_workqueue(struct workqueue_struct *wq)
35 {
36 }
37
38 struct workqueue_struct *create_singlethread_workqueue(char *name)
39 {
40         /* Non-canonical addr on AMD64.  No one should be derefing this. */
41         return (void*)0xf0f0f0f0f0f0f0f0;
42 }
43
44 static void __wq_wrapper(uint32_t srcid, long a0, long a1, long a2)
45 {
46         struct work_struct *work = (struct work_struct*)a0;
47         work->func(work);
48 }
49
50 /* Linux callers use jiffies as the unit of delay.  We pretend to be a 1000 HZ
51  * machine with 1 msec jiffies. */
52 static void __wq_wrapper_delay(uint32_t srcid, long a0, long a1, long a2)
53 {
54         struct work_struct *work = (struct work_struct*)a0;
55         unsigned long delay = (unsigned long)a1;
56
57         kthread_usleep(delay * 1000);
58         work->func(work);
59 }
60
61 static void send_work(int coreid, struct work_struct *work)
62 {
63         send_kernel_message(coreid, __wq_wrapper, (long)work, 0, 0, KMSG_ROUTINE);
64 }
65
66 static void send_work_delay(int coreid, struct delayed_work *work,
67                             unsigned long delay)
68 {
69         send_kernel_message(coreid, __wq_wrapper_delay, (long)work, (long)delay, 0,
70                             KMSG_ROUTINE);
71 }
72
73 bool queue_work(struct workqueue_struct *wq, struct work_struct *work)
74 {
75         send_work(core_id(), work);
76         return TRUE;
77 }
78
79 bool schedule_work(struct work_struct *work)
80 {
81         send_work(0, work);
82         return TRUE;
83 }
84
85 bool cancel_work(struct work_struct *dwork)
86 {
87         return FALSE;
88 }
89
90 bool cancel_work_sync(struct work_struct *dwork)
91 {
92         return FALSE;
93 }
94
95 bool queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork,
96                         unsigned long delay)
97 {
98         send_work_delay(core_id(), dwork, delay);
99         return TRUE;
100 }
101
102 bool schedule_delayed_work(struct delayed_work *dwork, unsigned long delay)
103 {
104         send_work_delay(0, dwork, delay);
105         return TRUE;
106 }
107
108 bool cancel_delayed_work(struct delayed_work *dwork)
109 {
110         return FALSE;
111 }
112
113 bool cancel_delayed_work_sync(struct delayed_work *dwork)
114 {
115         return FALSE;
116 }