kern

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