kern

view src/sched.c @ 51:b1e8c8251884

lalalala
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 01 Aug 2011 06:45:29 +0300
parents
children fa65b4f45366
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 if(EMPTY(runq)) {
25 /* idle "process".
26 * make sure interrupts are enabled before halting
27 */
28 enable_intr();
29 halt_cpu();
30 /* this won't return, it'll just wake up in an interrupt later */
31 }
33 disable_intr();
35 /* if the current process exhausted its timeslice,
36 * move it to the back of the queue.
37 */
38 if(runq.head->ticks_left <= 0) {
39 if(runq.head->next) {
40 struct process *proc = runq.head;
41 remove(&runq, proc);
42 ins_back(&runq, proc);
43 }
45 /* start a new timeslice */
46 runq.head->ticks_left = TIMESLICE_TICKS;
47 }
49 /* no need to re-enable interrupts, they will be enabled with the iret */
50 context_switch(runq.head->id);
51 }
53 int add_proc(int pid, enum proc_state state)
54 {
55 int istate;
56 struct proc_list *q;
57 struct process *proc = get_process(pid);
59 istate = get_intr_state();
60 disable_intr();
62 q = state == STATE_RUNNING ? &runq : &waitq;
64 ins_back(q, proc);
65 proc->state = state;
67 set_intr_state(istate);
68 return 0;
69 }
71 int block_proc(int pid)
72 {
73 int istate;
74 struct process *proc = get_process(pid);
76 if(proc->state != STATE_RUNNING) {
77 printf("block_proc: process %d not running\n", pid);
78 return -1;
79 }
81 istate = get_intr_state();
82 disable_intr();
84 remove(&runq, proc);
85 ins_back(&waitq, proc);
86 proc->state = STATE_BLOCKED;
88 set_intr_state(istate);
89 return 0;
90 }
92 int unblock_proc(int pid)
93 {
94 int istate;
95 struct process *proc = get_process(pid);
97 if(proc->state != STATE_BLOCKED) {
98 printf("unblock_proc: process %d not blocked\n", pid);
99 return -1;
100 }
102 istate = get_intr_state();
103 disable_intr();
105 remove(&waitq, proc);
106 ins_back(&runq, proc);
107 proc->state = STATE_RUNNING;
109 set_intr_state(istate);
110 return 0;
111 }
114 static void ins_back(struct proc_list *q, struct process *proc)
115 {
116 if(EMPTY(*q)) {
117 q->head = proc;
118 } else {
119 q->tail->next = proc;
120 }
122 proc->next = 0;
123 proc->prev = q->tail;
124 q->tail = proc;
125 }
127 static void ins_front(struct proc_list *q, struct process *proc)
128 {
129 if(EMPTY(*q)) {
130 q->tail = proc;
131 } else {
132 q->head->prev = proc;
133 }
135 proc->next = q->head;
136 proc->prev = 0;
137 q->head = proc;
138 }
140 static void remove(struct proc_list *q, struct process *proc)
141 {
142 if(proc->prev) {
143 proc->prev->next = proc->next;
144 }
145 if(proc->next) {
146 proc->next->prev = proc->prev;
147 }
148 if(q->head == proc) {
149 q->head = proc->next;
150 }
151 if(q->tail == proc) {
152 q->tail = proc->prev;
153 }
154 }