kern
diff src/proc.c @ 56:0be4615594df
finally, runqueues, blocking, waking up, idle loop etc, all seem to work fine
on a single user process... Next up: try forking another one :)
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 15 Aug 2011 06:17:58 +0300 |
parents | 88a6c4e192f9 |
children | 437360696883 |
line diff
1.1 --- a/src/proc.c Mon Aug 15 04:03:39 2011 +0300 1.2 +++ b/src/proc.c Mon Aug 15 06:17:58 2011 +0300 1.3 @@ -24,7 +24,13 @@ 1.4 void test_proc_end(void); 1.5 1.6 static struct process proc[MAX_PROC]; 1.7 -static int cur_pid; 1.8 + 1.9 +/* cur_pid: pid of the currently executing process. 1.10 + * when we're in the idle process cur_pid will be 0. 1.11 + * last_pid: pid of the last real process that was running, this should 1.12 + * never become 0. Essentially this defines the active kernel stack. 1.13 + */ 1.14 +static int cur_pid, last_pid; 1.15 1.16 static struct task_state *tss; 1.17 1.18 @@ -121,7 +127,8 @@ 1.19 /* add it to the scheduler queues */ 1.20 add_proc(p->id); 1.21 1.22 - cur_pid = p->id; /* make it current */ 1.23 + /* make it current */ 1.24 + set_current_pid(p->id); 1.25 1.26 /* execute a fake return from interrupt with the fake stack frame */ 1.27 intr_ret(ifrm); 1.28 @@ -130,31 +137,43 @@ 1.29 1.30 void context_switch(int pid) 1.31 { 1.32 - struct process *prev, *new; 1.33 + static struct process *prev, *new; 1.34 1.35 assert(get_intr_state() == 0); 1.36 + assert(pid > 0); 1.37 + assert(last_pid > 0); 1.38 1.39 - if(cur_pid == pid) { 1.40 - return; /* nothing to be done */ 1.41 - } 1.42 - prev = proc + cur_pid; 1.43 + prev = proc + last_pid; 1.44 new = proc + pid; 1.45 1.46 - /* push all registers onto the stack before switching stacks */ 1.47 - push_regs(); 1.48 + if(last_pid != pid) { 1.49 + /* push all registers onto the stack before switching stacks */ 1.50 + push_regs(); 1.51 1.52 - prev->ctx.stack_ptr = switch_stack(new->ctx.stack_ptr); 1.53 + prev->ctx.stack_ptr = switch_stack(new->ctx.stack_ptr); 1.54 1.55 - /* restore registers from the new stack */ 1.56 - pop_regs(); 1.57 + /* restore registers from the new stack */ 1.58 + pop_regs(); 1.59 1.60 - /* switch to the new process' address space */ 1.61 - set_pgdir_addr(new->ctx.pgtbl_paddr); 1.62 + /* switch to the new process' address space */ 1.63 + set_pgdir_addr(new->ctx.pgtbl_paddr); 1.64 1.65 - /* make sure we'll return to the correct kernel stack next time 1.66 - * we enter from userspace 1.67 - */ 1.68 - tss->esp0 = PAGE_TO_ADDR(new->kern_stack_pg) + KERN_STACK_SIZE; 1.69 + /* make sure we'll return to the correct kernel stack next time 1.70 + * we enter from userspace 1.71 + */ 1.72 + tss->esp0 = PAGE_TO_ADDR(new->kern_stack_pg) + KERN_STACK_SIZE; 1.73 + } 1.74 + 1.75 + set_current_pid(new->id); 1.76 +} 1.77 + 1.78 + 1.79 +void set_current_pid(int pid) 1.80 +{ 1.81 + cur_pid = pid; 1.82 + if(pid > 0) { 1.83 + last_pid = pid; 1.84 + } 1.85 } 1.86 1.87 int get_current_pid(void) 1.88 @@ -164,7 +183,7 @@ 1.89 1.90 struct process *get_current_proc(void) 1.91 { 1.92 - return cur_pid ? &proc[cur_pid] : 0; 1.93 + return cur_pid > 0 ? &proc[cur_pid] : 0; 1.94 } 1.95 1.96 struct process *get_process(int pid)