Many changes:
[Marmot.git] / task.c
blob4a80670596450b962a33c83193a22905c318c6b1
1 /*
2 * task.c --
4 * Basic task handling.
5 */
8 #include <marmot.h>
10 typedef enum {
11 SCHED_PRIORITY_IRQ,
12 SCHED_PRIORITY_INTERRUPT,
13 SCHED_PRIORITY0,
14 SCHED_PRIORITY1,
15 SCHED_PRIORITY2,
16 SCHED_PRIORITY3,
17 SCHED_PRIORITY4,
18 SCHED_PRIORITY5,
19 SCHED_PRIORITY6,
20 SCHED_PRIORITY7
21 } SchedPriority;
24 typedef struct {
25 UReg rax;
26 UReg rbx;
27 UReg rcx;
28 UReg rdx;
29 UReg rdi;
30 UReg rsi;
31 UReg rbp;
32 UReg rsp;
33 UReg r8;
34 UReg r9;
35 UReg r10;
36 UReg r11;
37 UReg r12;
38 UReg r13;
39 UReg r14;
40 UReg r15;
41 } Registers;
44 struct task {
45 uint64 id;
46 Registers regs;
47 UReg cr3;
51 void
52 SaveTask(void)
57 void
58 SwitchToTaskStack(void)
63 void
64 SwitchToTask(void)
70 typedef struct _DFCArgs {
71 uint64 a1;
72 uint64 a2;
73 uint64 a3;
74 uint64 a4;
75 } *DFCArgs;
77 typedef void (*DFCFcn)(DFCArgs);
79 typedef struct _DFC {
80 struct _DFC *next;
81 DFCFcn fcn;
82 DFCArgs args;
83 } DFC;
85 DFC *dfcHead;
88 void
89 RunDFC(DFCFcn fcn, DFCArgs args)
96 * This is only called from the timer interrupt. As it doesn't
97 * return, it's necessary to unmask the timer IRQ prior to switching
98 * to the new task.
101 void
102 TaskSchedule(uint64 timerIrq)
104 DFC *dfc;
106 SaveTask();
107 SwitchToTaskStack();
110 * Run all DFCs now.
113 sti(); // timer irq is still masked
115 for (dfc = dfcHead; dfc != NULL; dfc = dfcHead) {
116 dfcHead = dfc->next;
118 RunDFC(dfc->fcn, dfc->args);
119 free(dfc->args);
120 free(dfc);
124 * Run regular tasks now.
127 // XXX
130 UnmaskPIC(timerIrq - IRQBASE);
131 SwitchToTask(); // executes an iretq
135 typedef void (*Task)(void);
137 void
138 TaskStart(Task t)
141 * Allocate new stack.
147 void
148 TaskInit(void)
150 dfcHead = NULL;
153 * Create task stack
154 * Create runqueues
155 * Hook TaskSchedule into the timer interrupt.
163 * Defer --
165 * Create a deferred function call. This DFC is placed on the
166 * runqueue of the specified priority and, once scheduled, is
167 * passed the appropriate args.
169 * DFCs run synchronously on the stack of the scheduler which
170 * makes them especially convenient for IRQ/fault handling.
172 * The DFCArgs that is passed
175 void
176 Defer(SchedPriority p, DFCFcn dfc, DFCArgs *args)