kern
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/sched.c Mon Aug 01 06:45:29 2011 +0300 1.3 @@ -0,0 +1,154 @@ 1.4 +#include <stdio.h> 1.5 +#include "sched.h" 1.6 +#include "proc.h" 1.7 +#include "intr.h" 1.8 +#include "asmops.h" 1.9 +#include "config.h" 1.10 + 1.11 +#define EMPTY(q) ((q).head == 0) 1.12 + 1.13 +struct proc_list { 1.14 + struct process *head, *tail; 1.15 +}; 1.16 + 1.17 +static void ins_back(struct proc_list *q, struct process *proc); 1.18 +static void ins_front(struct proc_list *q, struct process *proc); 1.19 +static void remove(struct proc_list *q, struct process *proc); 1.20 + 1.21 +static struct proc_list runq; 1.22 +static struct proc_list waitq; 1.23 +static struct proc_list zombieq; 1.24 + 1.25 +void schedule(void) 1.26 +{ 1.27 + if(EMPTY(runq)) { 1.28 + /* idle "process". 1.29 + * make sure interrupts are enabled before halting 1.30 + */ 1.31 + enable_intr(); 1.32 + halt_cpu(); 1.33 + /* this won't return, it'll just wake up in an interrupt later */ 1.34 + } 1.35 + 1.36 + disable_intr(); 1.37 + 1.38 + /* if the current process exhausted its timeslice, 1.39 + * move it to the back of the queue. 1.40 + */ 1.41 + if(runq.head->ticks_left <= 0) { 1.42 + if(runq.head->next) { 1.43 + struct process *proc = runq.head; 1.44 + remove(&runq, proc); 1.45 + ins_back(&runq, proc); 1.46 + } 1.47 + 1.48 + /* start a new timeslice */ 1.49 + runq.head->ticks_left = TIMESLICE_TICKS; 1.50 + } 1.51 + 1.52 + /* no need to re-enable interrupts, they will be enabled with the iret */ 1.53 + context_switch(runq.head->id); 1.54 +} 1.55 + 1.56 +int add_proc(int pid, enum proc_state state) 1.57 +{ 1.58 + int istate; 1.59 + struct proc_list *q; 1.60 + struct process *proc = get_process(pid); 1.61 + 1.62 + istate = get_intr_state(); 1.63 + disable_intr(); 1.64 + 1.65 + q = state == STATE_RUNNING ? &runq : &waitq; 1.66 + 1.67 + ins_back(q, proc); 1.68 + proc->state = state; 1.69 + 1.70 + set_intr_state(istate); 1.71 + return 0; 1.72 +} 1.73 + 1.74 +int block_proc(int pid) 1.75 +{ 1.76 + int istate; 1.77 + struct process *proc = get_process(pid); 1.78 + 1.79 + if(proc->state != STATE_RUNNING) { 1.80 + printf("block_proc: process %d not running\n", pid); 1.81 + return -1; 1.82 + } 1.83 + 1.84 + istate = get_intr_state(); 1.85 + disable_intr(); 1.86 + 1.87 + remove(&runq, proc); 1.88 + ins_back(&waitq, proc); 1.89 + proc->state = STATE_BLOCKED; 1.90 + 1.91 + set_intr_state(istate); 1.92 + return 0; 1.93 +} 1.94 + 1.95 +int unblock_proc(int pid) 1.96 +{ 1.97 + int istate; 1.98 + struct process *proc = get_process(pid); 1.99 + 1.100 + if(proc->state != STATE_BLOCKED) { 1.101 + printf("unblock_proc: process %d not blocked\n", pid); 1.102 + return -1; 1.103 + } 1.104 + 1.105 + istate = get_intr_state(); 1.106 + disable_intr(); 1.107 + 1.108 + remove(&waitq, proc); 1.109 + ins_back(&runq, proc); 1.110 + proc->state = STATE_RUNNING; 1.111 + 1.112 + set_intr_state(istate); 1.113 + return 0; 1.114 +} 1.115 + 1.116 + 1.117 +static void ins_back(struct proc_list *q, struct process *proc) 1.118 +{ 1.119 + if(EMPTY(*q)) { 1.120 + q->head = proc; 1.121 + } else { 1.122 + q->tail->next = proc; 1.123 + } 1.124 + 1.125 + proc->next = 0; 1.126 + proc->prev = q->tail; 1.127 + q->tail = proc; 1.128 +} 1.129 + 1.130 +static void ins_front(struct proc_list *q, struct process *proc) 1.131 +{ 1.132 + if(EMPTY(*q)) { 1.133 + q->tail = proc; 1.134 + } else { 1.135 + q->head->prev = proc; 1.136 + } 1.137 + 1.138 + proc->next = q->head; 1.139 + proc->prev = 0; 1.140 + q->head = proc; 1.141 +} 1.142 + 1.143 +static void remove(struct proc_list *q, struct process *proc) 1.144 +{ 1.145 + if(proc->prev) { 1.146 + proc->prev->next = proc->next; 1.147 + } 1.148 + if(proc->next) { 1.149 + proc->next->prev = proc->prev; 1.150 + } 1.151 + if(q->head == proc) { 1.152 + q->head = proc->next; 1.153 + } 1.154 + if(q->tail == proc) { 1.155 + q->tail = proc->prev; 1.156 + } 1.157 +}