kern

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