kern

view src/sched.c @ 52:fa65b4f45366

picking this up again, let's fix it
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 07 Aug 2011 06:42:00 +0300
parents b1e8c8251884
children 23abbeea4d5f
line source
1 #include <stdio.h>
2 #include "sched.h"
3 #include "proc.h"
4 #include "intr.h"
5 #include "asmops.h"
6 #include "config.h"
8 #define EMPTY(q) ((q).head == 0)
10 struct proc_list {
11 struct process *head, *tail;
12 };
14 static void ins_back(struct proc_list *q, struct process *proc);
15 static void ins_front(struct proc_list *q, struct process *proc);
16 static void remove(struct proc_list *q, struct process *proc);
18 static struct proc_list runq;
19 static struct proc_list waitq;
20 static struct proc_list zombieq;
22 void schedule(void)
23 {
24 disable_intr();
26 if(EMPTY(runq)) {
27 /* idle "process".
28 * make sure interrupts are enabled before halting
29 */
30 enable_intr();
31 halt_cpu();
32 printf("fuck you!\n");
33 /* this won't return, it'll just wake up in an interrupt later */
34 }
36 /* if the current process exhausted its timeslice,
37 * move it to the back of the queue.
38 */
39 if(runq.head->ticks_left <= 0) {
40 if(runq.head->next) {
41 struct process *proc = runq.head;
42 remove(&runq, proc);
43 ins_back(&runq, proc);
44 }
46 /* start a new timeslice */
47 runq.head->ticks_left = TIMESLICE_TICKS;
48 }
50 /* no need to re-enable interrupts, they will be enabled with the iret */
51 context_switch(runq.head->id);
52 }
54 int add_proc(int pid, enum proc_state state)
55 {
56 int istate;
57 struct proc_list *q;
58 struct process *proc;
60 istate = get_intr_state();
61 disable_intr();
63 proc = get_process(pid);
65 q = state == STATE_RUNNING ? &runq : &waitq;
67 ins_back(q, proc);
68 proc->state = state;
70 set_intr_state(istate);
71 return 0;
72 }
74 int block_proc(int pid)
75 {
76 int istate;
77 struct process *proc = get_process(pid);
79 if(proc->state != STATE_RUNNING) {
80 printf("block_proc: process %d not running\n", pid);
81 return -1;
82 }
84 istate = get_intr_state();
85 disable_intr();
87 remove(&runq, proc);
88 ins_back(&waitq, proc);
89 proc->state = STATE_BLOCKED;
91 set_intr_state(istate);
92 return 0;
93 }
95 int unblock_proc(int pid)
96 {
97 int istate;
98 struct process *proc = get_process(pid);
100 if(proc->state != STATE_BLOCKED) {
101 printf("unblock_proc: process %d not blocked\n", pid);
102 return -1;
103 }
105 istate = get_intr_state();
106 disable_intr();
108 remove(&waitq, proc);
109 ins_back(&runq, proc);
110 proc->state = STATE_RUNNING;
112 set_intr_state(istate);
113 return 0;
114 }
117 static void ins_back(struct proc_list *q, struct process *proc)
118 {
119 if(EMPTY(*q)) {
120 q->head = proc;
121 } else {
122 q->tail->next = proc;
123 }
125 proc->next = 0;
126 proc->prev = q->tail;
127 q->tail = proc;
128 }
130 static void ins_front(struct proc_list *q, struct process *proc)
131 {
132 if(EMPTY(*q)) {
133 q->tail = proc;
134 } else {
135 q->head->prev = proc;
136 }
138 proc->next = q->head;
139 proc->prev = 0;
140 q->head = proc;
141 }
143 static void remove(struct proc_list *q, struct process *proc)
144 {
145 if(proc->prev) {
146 proc->prev->next = proc->next;
147 }
148 if(proc->next) {
149 proc->next->prev = proc->prev;
150 }
151 if(q->head == proc) {
152 q->head = proc->next;
153 }
154 if(q->tail == proc) {
155 q->tail = proc->prev;
156 }
157 }