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)