diff options
author | Russ Cox <[email protected]> | 2009-08-08 01:07:30 -0700 |
---|---|---|
committer | Russ Cox <[email protected]> | 2009-08-08 01:07:30 -0700 |
commit | 0aef8914959af9e472852611eb6352c211093d35 (patch) | |
tree | 0658cf47dcb134b79e5311209c2a2840d1a79650 /proc.c | |
parent | b3bebfce8a790975ba941d346e6bcff1b5afecf9 (diff) | |
download | xv6-labs-0aef8914959af9e472852611eb6352c211093d35.tar.gz xv6-labs-0aef8914959af9e472852611eb6352c211093d35.tar.bz2 xv6-labs-0aef8914959af9e472852611eb6352c211093d35.zip |
shuffle and tweak for formatting.
pdf has very good page breaks now.
would be a good copy for fall 2009.
Diffstat (limited to 'proc.c')
-rw-r--r-- | proc.c | 206 |
1 files changed, 104 insertions, 102 deletions
@@ -23,6 +23,79 @@ pinit(void) initlock(&ptable.lock, "ptable"); } +//PAGEBREAK: 36 +// Print a process listing to console. For debugging. +// Runs when user types ^P on console. +// No lock to avoid wedging a stuck machine further. +void +procdump(void) +{ + static char *states[] = { + [UNUSED] "unused", + [EMBRYO] "embryo", + [SLEEPING] "sleep ", + [RUNNABLE] "runble", + [RUNNING] "run ", + [ZOMBIE] "zombie" + }; + int i; + struct proc *p; + char *state; + uint pc[10]; + + for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ + if(p->state == UNUSED) + continue; + if(p->state >= 0 && p->state < NELEM(states) && states[p->state]) + state = states[p->state]; + else + state = "???"; + cprintf("%d %s %s", p->pid, state, p->name); + if(p->state == SLEEPING){ + getcallerpcs((uint*)p->context->ebp+2, pc); + for(i=0; i<10 && pc[i] != 0; i++) + cprintf(" %p", pc[i]); + } + cprintf("\n"); + } +} + +// Set up CPU's kernel segment descriptors. +// Run once at boot time on each CPU. +void +ksegment(void) +{ + struct cpu *c1; + + c1 = &cpus[cpu()]; + c1->gdt[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0x100000 + 64*1024-1, 0); + c1->gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0); + c1->gdt[SEG_KCPU] = SEG(STA_W, (uint)(&c1->tls+1), 0xffffffff, 0); + lgdt(c1->gdt, sizeof(c1->gdt)); + loadfsgs(SEG_KCPU << 3); + + // Initialize cpu-local variables. + c = c1; + cp = 0; +} + +// Set up CPU's segment descriptors and current process task state. +// If cp==0, set up for "idle" state for when scheduler() is running. +void +usegment(void) +{ + pushcli(); + c->gdt[SEG_UCODE] = SEG(STA_X|STA_R, (uint)cp->mem, cp->sz-1, DPL_USER); + c->gdt[SEG_UDATA] = SEG(STA_W, (uint)cp->mem, cp->sz-1, DPL_USER); + c->gdt[SEG_TSS] = SEG16(STS_T32A, (uint)&c->ts, sizeof(c->ts)-1, 0); + c->gdt[SEG_TSS].s = 0; + c->ts.ss0 = SEG_KDATA << 3; + c->ts.esp0 = (uint)cp->kstack + KSTACKSIZE; + ltr(SEG_TSS << 3); + popcli(); +} + +//PAGEBREAK: 15 // Look in the process table for an UNUSED proc. // If found, change state to EMBRYO and return it. // Otherwise return 0. @@ -67,6 +140,37 @@ found: return p; } +// Set up first user process. +void +userinit(void) +{ + struct proc *p; + extern char _binary_initcode_start[], _binary_initcode_size[]; + + p = allocproc(); + initproc = p; + + // Initialize memory from initcode.S + p->sz = PAGE; + p->mem = kalloc(p->sz); + memset(p->mem, 0, p->sz); + memmove(p->mem, _binary_initcode_start, (int)_binary_initcode_size); + + memset(p->tf, 0, sizeof(*p->tf)); + p->tf->cs = (SEG_UCODE << 3) | DPL_USER; + p->tf->ds = (SEG_UDATA << 3) | DPL_USER; + p->tf->es = p->tf->ds; + p->tf->ss = p->tf->ds; + p->tf->eflags = FL_IF; + p->tf->esp = p->sz; + p->tf->eip = 0; // beginning of initcode.S + + safestrcpy(p->name, "initcode", sizeof(p->name)); + p->cwd = namei("/"); + + p->state = RUNNABLE; +} + // Grow current process's memory by n bytes. // Return 0 on success, -1 on failure. int @@ -86,41 +190,6 @@ growproc(int n) return 0; } -// Set up CPU's kernel segment descriptors. -// Run once at boot time on each CPU. -void -ksegment(void) -{ - struct cpu *c1; - - c1 = &cpus[cpu()]; - c1->gdt[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0x100000 + 64*1024-1, 0); - c1->gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0); - c1->gdt[SEG_KCPU] = SEG(STA_W, (uint)(&c1->tls+1), 0xffffffff, 0); - lgdt(c1->gdt, sizeof(c1->gdt)); - loadfsgs(SEG_KCPU << 3); - - // Initialize cpu-local variables. - c = c1; - cp = 0; -} - -// Set up CPU's segment descriptors and task state for the current process. -// If cp==0, set up for "idle" state for when scheduler() is running. -void -usegment(void) -{ - pushcli(); - c->gdt[SEG_UCODE] = SEG(STA_X|STA_R, (uint)cp->mem, cp->sz-1, DPL_USER); - c->gdt[SEG_UDATA] = SEG(STA_W, (uint)cp->mem, cp->sz-1, DPL_USER); - c->gdt[SEG_TSS] = SEG16(STS_T32A, (uint)&c->ts, sizeof(c->ts)-1, 0); - c->gdt[SEG_TSS].s = 0; - c->ts.ss0 = SEG_KDATA << 3; - c->ts.esp0 = (uint)cp->kstack + KSTACKSIZE; - ltr(SEG_TSS << 3); - popcli(); -} - // Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. @@ -160,37 +229,6 @@ fork(void) return pid; } -// Set up first user process. -void -userinit(void) -{ - struct proc *p; - extern char _binary_initcode_start[], _binary_initcode_size[]; - - p = allocproc(); - initproc = p; - - // Initialize memory from initcode.S - p->sz = PAGE; - p->mem = kalloc(p->sz); - memset(p->mem, 0, p->sz); - memmove(p->mem, _binary_initcode_start, (int)_binary_initcode_size); - - memset(p->tf, 0, sizeof(*p->tf)); - p->tf->cs = (SEG_UCODE << 3) | DPL_USER; - p->tf->ds = (SEG_UDATA << 3) | DPL_USER; - p->tf->es = p->tf->ds; - p->tf->ss = p->tf->ds; - p->tf->eflags = FL_IF; - p->tf->esp = p->sz; - p->tf->eip = 0; // beginning of initcode.S - - safestrcpy(p->name, "initcode", sizeof(p->name)); - p->cwd = namei("/"); - - p->state = RUNNABLE; -} - //PAGEBREAK: 42 // Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. @@ -440,39 +478,3 @@ wait(void) } } -// Print a process listing to console. For debugging. -// Runs when user types ^P on console. -// No lock to avoid wedging a stuck machine further. -void -procdump(void) -{ - static char *states[] = { - [UNUSED] "unused", - [EMBRYO] "embryo", - [SLEEPING] "sleep ", - [RUNNABLE] "runble", - [RUNNING] "run ", - [ZOMBIE] "zombie" - }; - int i; - struct proc *p; - char *state; - uint pc[10]; - - for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ - if(p->state == UNUSED) - continue; - if(p->state >= 0 && p->state < NELEM(states) && states[p->state]) - state = states[p->state]; - else - state = "???"; - cprintf("%d %s %s", p->pid, state, p->name); - if(p->state == SLEEPING){ - getcallerpcs((uint*)p->context->ebp+2, pc); - for(i=0; i<10 && pc[i] != 0; i++) - cprintf(" %p", pc[i]); - } - cprintf("\n"); - } -} - |