test: store curproc at top of stack
I don't actually think this is worthwhile, but I figured I would check it in before reverting it, so that it can be in the revision history. Pros: * curproc doesn't need to turn on/off interrupts * scheduler doesn't have to edit curproc anymore Cons: * it's ugly * all the stack computation is more complicated. * it doesn't actually simplify anything but curproc, and even curproc is harder to follow.
This commit is contained in:
parent
aefc13f8ba
commit
ce2e751555
3 changed files with 16 additions and 14 deletions
8
main.c
8
main.c
|
@ -42,12 +42,14 @@ main(void)
|
||||||
userinit(); // first user process
|
userinit(); // first user process
|
||||||
|
|
||||||
// Allocate scheduler stacks and boot the other CPUs.
|
// Allocate scheduler stacks and boot the other CPUs.
|
||||||
for(i=0; i<ncpu; i++)
|
for(i=0; i<ncpu; i++){
|
||||||
cpus[i].stack = kalloc(KSTACKSIZE);
|
cpus[i].stack = kalloc(KSTACKSIZE);
|
||||||
|
*(void**)(cpus[i].stack + KSTACKTOP) = 0;
|
||||||
|
}
|
||||||
bootothers();
|
bootothers();
|
||||||
|
|
||||||
// Switch to our scheduler stack and continue with mpmain.
|
// Switch to our scheduler stack and continue with mpmain.
|
||||||
asm volatile("movl %0, %%esp" : : "r" (cpus[bcpu].stack+KSTACKSIZE));
|
asm volatile("movl %0, %%esp" : : "r" (cpus[bcpu].stack+KSTACKTOP));
|
||||||
mpmain();
|
mpmain();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +86,7 @@ bootothers(void)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Fill in %esp, %eip and start code on cpu.
|
// Fill in %esp, %eip and start code on cpu.
|
||||||
*(void**)(code-4) = c->stack + KSTACKSIZE;
|
*(void**)(code-4) = c->stack + KSTACKTOP;
|
||||||
*(void**)(code-8) = mpmain;
|
*(void**)(code-8) = mpmain;
|
||||||
lapic_startap(c->apicid, (uint)code);
|
lapic_startap(c->apicid, (uint)code);
|
||||||
|
|
||||||
|
|
17
proc.c
17
proc.c
|
@ -75,7 +75,7 @@ setupsegs(struct proc *p)
|
||||||
c = &cpus[cpu()];
|
c = &cpus[cpu()];
|
||||||
c->ts.ss0 = SEG_PROCSTACK << 3;
|
c->ts.ss0 = SEG_PROCSTACK << 3;
|
||||||
if(p)
|
if(p)
|
||||||
c->ts.esp0 = (uint)(p->kstack + KSTACKSIZE);
|
c->ts.esp0 = (uint)(p->kstack + KSTACKTOP);
|
||||||
else
|
else
|
||||||
c->ts.esp0 = 0xffffffff;
|
c->ts.esp0 = 0xffffffff;
|
||||||
|
|
||||||
|
@ -118,7 +118,8 @@ copyproc(struct proc *p)
|
||||||
np->state = UNUSED;
|
np->state = UNUSED;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
np->tf = (struct trapframe*)(np->kstack + KSTACKSIZE) - 1;
|
*(void**)(np->kstack + KSTACKTOP) = np;
|
||||||
|
np->tf = (struct trapframe*)(np->kstack + KSTACKTOP) - 1;
|
||||||
|
|
||||||
if(p){ // Copy process state from p.
|
if(p){ // Copy process state from p.
|
||||||
np->parent = p;
|
np->parent = p;
|
||||||
|
@ -187,12 +188,10 @@ userinit(void)
|
||||||
struct proc*
|
struct proc*
|
||||||
curproc(void)
|
curproc(void)
|
||||||
{
|
{
|
||||||
struct proc *p;
|
uint esp;
|
||||||
|
|
||||||
pushcli();
|
asm volatile("movl %%esp, %0" : "=a" (esp));
|
||||||
p = cpus[cpu()].curproc;
|
return *(struct proc**)((esp & ~(KSTACKSIZE-1)) + KSTACKTOP);
|
||||||
popcli();
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//PAGEBREAK: 42
|
//PAGEBREAK: 42
|
||||||
|
@ -223,14 +222,12 @@ scheduler(void)
|
||||||
// Switch to chosen process. It is the process's job
|
// Switch to chosen process. It is the process's job
|
||||||
// to release proc_table_lock and then reacquire it
|
// to release proc_table_lock and then reacquire it
|
||||||
// before jumping back to us.
|
// before jumping back to us.
|
||||||
c->curproc = p;
|
|
||||||
setupsegs(p);
|
setupsegs(p);
|
||||||
p->state = RUNNING;
|
p->state = RUNNING;
|
||||||
swtch(&c->context, &p->context);
|
swtch(&c->context, &p->context);
|
||||||
|
|
||||||
// Process is done running for now.
|
// Process is done running for now.
|
||||||
// It should have changed its p->state before coming back.
|
// It should have changed its p->state before coming back.
|
||||||
c->curproc = 0;
|
|
||||||
setupsegs(0);
|
setupsegs(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +236,7 @@ scheduler(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enter scheduler. Must already hold proc_table_lock
|
// Enter scheduler. Must already hold proc_table_lock
|
||||||
// and have changed curproc[cpu()]->state.
|
// and have changed cp->state.
|
||||||
void
|
void
|
||||||
sched(void)
|
sched(void)
|
||||||
{
|
{
|
||||||
|
|
5
proc.h
5
proc.h
|
@ -46,6 +46,10 @@ struct proc {
|
||||||
char name[16]; // Process name (debugging)
|
char name[16]; // Process name (debugging)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The word at kstack + KSTACKTOP is a pointer to the struct proc.
|
||||||
|
#define KSTACKTOP (KSTACKSIZE-4)
|
||||||
|
|
||||||
|
|
||||||
// Process memory is laid out contiguously, low addresses first:
|
// Process memory is laid out contiguously, low addresses first:
|
||||||
// text
|
// text
|
||||||
// original data and bss
|
// original data and bss
|
||||||
|
@ -55,7 +59,6 @@ struct proc {
|
||||||
// Per-CPU state
|
// Per-CPU state
|
||||||
struct cpu {
|
struct cpu {
|
||||||
uchar apicid; // Local APIC ID
|
uchar apicid; // Local APIC ID
|
||||||
struct proc *curproc; // Process currently running.
|
|
||||||
struct context context; // Switch here to enter scheduler
|
struct context context; // Switch here to enter scheduler
|
||||||
struct taskstate ts; // Used by x86 to find stack for interrupt
|
struct taskstate ts; // Used by x86 to find stack for interrupt
|
||||||
struct segdesc gdt[NSEGS]; // x86 global descriptor table
|
struct segdesc gdt[NSEGS]; // x86 global descriptor table
|
||||||
|
|
Loading…
Reference in a new issue