assorted fixes:

* rename c/cp to cpu/proc
 * rename cpu.context to cpu.scheduler
 * fix some comments
 * formatting for printout
This commit is contained in:
Russ Cox 2009-08-30 23:02:08 -07:00
parent 0aef891495
commit 48755214c9
23 changed files with 2437 additions and 2379 deletions

View file

@ -37,7 +37,7 @@ AS = $(TOOLPREFIX)gas
LD = $(TOOLPREFIX)ld LD = $(TOOLPREFIX)ld
OBJCOPY = $(TOOLPREFIX)objcopy OBJCOPY = $(TOOLPREFIX)objcopy
OBJDUMP = $(TOOLPREFIX)objdump OBJDUMP = $(TOOLPREFIX)objdump
CFLAGS = -fno-builtin -O2 -Wall -MD -ggdb -m32 CFLAGS = -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector) CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
ASFLAGS = -m32 ASFLAGS = -m32
# FreeBSD ld wants ``elf_i386_fbsd'' # FreeBSD ld wants ``elf_i386_fbsd''

View file

@ -59,7 +59,7 @@ cprintf(char *fmt, ...)
if(locking) if(locking)
acquire(&cons.lock); acquire(&cons.lock);
argp = (uint*)(void*)&fmt + 1; argp = (uint*)(void*)(&fmt + 1);
state = 0; state = 0;
for(i = 0; (c = fmt[i] & 0xff) != 0; i++){ for(i = 0; (c = fmt[i] & 0xff) != 0; i++){
if(c != '%'){ if(c != '%'){
@ -106,7 +106,7 @@ panic(char *s)
cli(); cli();
cons.locking = 0; cons.locking = 0;
cprintf("cpu%d: panic: ", cpu()); cprintf("cpu%d: panic: ", cpu->id);
cprintf(s); cprintf(s);
cprintf("\n"); cprintf("\n");
getcallerpcs(&s, pcs); getcallerpcs(&s, pcs);
@ -229,7 +229,7 @@ consoleread(struct inode *ip, char *dst, int n)
acquire(&input.lock); acquire(&input.lock);
while(n > 0){ while(n > 0){
while(input.r == input.w){ while(input.r == input.w){
if(cp->killed){ if(proc->killed){
release(&input.lock); release(&input.lock);
ilock(ip); ilock(ip);
return -1; return -1;

2
defs.h
View file

@ -68,7 +68,7 @@ void kinit(void);
void kbdintr(void); void kbdintr(void);
// lapic.c // lapic.c
int cpu(void); int cpunum(void);
extern volatile uint* lapic; extern volatile uint* lapic;
void lapiceoi(void); void lapiceoi(void);
void lapicinit(int); void lapicinit(int);

14
exec.c
View file

@ -11,7 +11,7 @@ exec(char *path, char **argv)
{ {
char *mem, *s, *last; char *mem, *s, *last;
int i, argc, arglen, len, off; int i, argc, arglen, len, off;
uint sz, sp, argp, x; uint sz, sp, argp;
struct elfhdr elf; struct elfhdr elf;
struct inode *ip; struct inode *ip;
struct proghdr ph; struct proghdr ph;
@ -103,14 +103,14 @@ exec(char *path, char **argv)
for(last=s=path; *s; s++) for(last=s=path; *s; s++)
if(*s == '/') if(*s == '/')
last = s+1; last = s+1;
safestrcpy(cp->name, last, sizeof(cp->name)); safestrcpy(proc->name, last, sizeof(proc->name));
// Commit to the new image. // Commit to the new image.
kfree(cp->mem, cp->sz); kfree(proc->mem, proc->sz);
cp->mem = mem; proc->mem = mem;
cp->sz = sz; proc->sz = sz;
cp->tf->eip = elf.entry; // main proc->tf->eip = elf.entry; // main
cp->tf->esp = sp; proc->tf->esp = sp;
usegment(); usegment();
return 0; return 0;

4
fs.c
View file

@ -109,7 +109,7 @@ bfree(int dev, uint b)
// to inodes shared between multiple processes. // to inodes shared between multiple processes.
// //
// ip->ref counts the number of pointer references to this cached // ip->ref counts the number of pointer references to this cached
// inode; references are typically kept in struct file and in cp->cwd. // inode; references are typically kept in struct file and in proc->cwd.
// When ip->ref falls to zero, the inode is no longer cached. // When ip->ref falls to zero, the inode is no longer cached.
// It is an error to use an inode without holding a reference to it. // It is an error to use an inode without holding a reference to it.
// //
@ -578,7 +578,7 @@ namex(char *path, int nameiparent, char *name)
if(*path == '/') if(*path == '/')
ip = iget(ROOTDEV, ROOTINO); ip = iget(ROOTDEV, ROOTINO);
else else
ip = idup(cp->cwd); ip = idup(proc->cwd);
while((path = skipelem(path, name)) != 0){ while((path = skipelem(path, name)) != 0){
ilock(ip); ilock(ip);

2
ide.c
View file

@ -146,7 +146,7 @@ iderw(struct buf *b)
idestart(b); idestart(b);
// Wait for request to finish. // Wait for request to finish.
// Assuming will not sleep too long: ignore cp->killed. // Assuming will not sleep too long: ignore proc->killed.
while((b->flags & (B_VALID|B_DIRTY)) != B_VALID) while((b->flags & (B_VALID|B_DIRTY)) != B_VALID)
sleep(b, &idelock); sleep(b, &idelock);

View file

@ -92,7 +92,7 @@ lapicinit(int c)
} }
int int
cpu(void) cpunum(void)
{ {
// Cannot call cpu when interrupts are enabled: // Cannot call cpu when interrupts are enabled:
// result not guaranteed to last long enough to be used! // result not guaranteed to last long enough to be used!

20
main.c
View file

@ -5,8 +5,8 @@
#include "proc.h" #include "proc.h"
#include "x86.h" #include "x86.h"
__thread struct cpu *c; __thread struct cpu *cpu;
__thread struct proc *cp; __thread struct proc *proc;
static void bootothers(void); static void bootothers(void);
static void mpmain(void) __attribute__((noreturn)); static void mpmain(void) __attribute__((noreturn));
@ -22,7 +22,7 @@ main(void)
ioapicinit(); // another interrupt controller ioapicinit(); // another interrupt controller
consoleinit(); // I/O devices & their interrupts consoleinit(); // I/O devices & their interrupts
uartinit(); // serial port uartinit(); // serial port
cprintf("\ncpu%d: starting xv6\n\n", cpu()); cprintf("\ncpu%d: starting xv6\n\n", cpu->id);
kinit(); // physical memory allocator kinit(); // physical memory allocator
pinit(); // process table pinit(); // process table
@ -45,14 +45,14 @@ main(void)
static void static void
mpmain(void) mpmain(void)
{ {
if(cpu() != mpbcpu()) if(cpunum() != mpbcpu())
lapicinit(cpu()); lapicinit(cpunum());
ksegment(); ksegment();
cprintf("cpu%d: mpmain\n", cpu()); cprintf("cpu%d: mpmain\n", cpu->id);
idtinit(); idtinit();
xchg(&c->booted, 1); xchg(&cpu->booted, 1);
cprintf("cpu%d: scheduling\n", cpu()); cprintf("cpu%d: scheduling\n", cpu->id);
scheduler(); scheduler();
} }
@ -69,14 +69,14 @@ bootothers(void)
memmove(code, _binary_bootother_start, (uint)_binary_bootother_size); memmove(code, _binary_bootother_start, (uint)_binary_bootother_size);
for(c = cpus; c < cpus+ncpu; c++){ for(c = cpus; c < cpus+ncpu; c++){
if(c == cpus+cpu()) // We've started already. if(c == cpus+cpunum()) // We've started already.
continue; continue;
// Fill in %esp, %eip and start code on cpu. // Fill in %esp, %eip and start code on cpu.
stack = kalloc(KSTACKSIZE); stack = kalloc(KSTACKSIZE);
*(void**)(code-4) = stack + KSTACKSIZE; *(void**)(code-4) = stack + KSTACKSIZE;
*(void**)(code-8) = mpmain; *(void**)(code-8) = mpmain;
lapicstartap(c->apicid, (uint)code); lapicstartap(c->id, (uint)code);
// Wait for cpu to get through bootstrap. // Wait for cpu to get through bootstrap.
while(c->booted == 0) while(c->booted == 0)

12
mmu.h
View file

@ -43,14 +43,14 @@ struct segdesc {
// Normal segment // Normal segment
#define SEG(type, base, lim, dpl) (struct segdesc) \ #define SEG(type, base, lim, dpl) (struct segdesc) \
{ ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \ { ((lim) >> 12) & 0xffff, (uint)(base) & 0xffff, \
type, 1, dpl, 1, (uint) (lim) >> 28, 0, 0, 1, 1, \ ((uint)(base) >> 16) & 0xff, type, 1, dpl, 1, \
(uint) (base) >> 24 } (uint)(lim) >> 28, 0, 0, 1, 1, (uint)(base) >> 24 }
#define SEG16(type, base, lim, dpl) (struct segdesc) \ #define SEG16(type, base, lim, dpl) (struct segdesc) \
{ (lim) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \ { (lim) & 0xffff, (uint)(base) & 0xffff, \
type, 1, dpl, 1, (uint) (lim) >> 16, 0, 0, 1, 0, \ ((uint)(base) >> 16) & 0xff, type, 1, dpl, 1, \
(uint) (base) >> 24 } (uint)(lim) >> 16, 0, 0, 1, 0, (uint)(base) >> 24 }
#define DPL_USER 0x3 // User DPL #define DPL_USER 0x3 // User DPL

11
mp.c
View file

@ -103,20 +103,22 @@ mpinit(void)
struct mpproc *proc; struct mpproc *proc;
struct mpioapic *ioapic; struct mpioapic *ioapic;
bcpu = &cpus[ncpu]; bcpu = &cpus[0];
if((conf = mpconfig(&mp)) == 0) if((conf = mpconfig(&mp)) == 0)
return; return;
ismp = 1; ismp = 1;
lapic = (uint*)conf->lapicaddr; lapic = (uint*)conf->lapicaddr;
for(p=(uchar*)(conf+1), e=(uchar*)conf+conf->length; p<e; ){ for(p=(uchar*)(conf+1), e=(uchar*)conf+conf->length; p<e; ){
switch(*p){ switch(*p){
case MPPROC: case MPPROC:
proc = (struct mpproc*)p; proc = (struct mpproc*)p;
cpus[ncpu].apicid = proc->apicid; if(ncpu != proc->apicid) {
cprintf("mpinit: ncpu=%d apicpid=%d", ncpu, proc->apicid);
panic("mpinit");
}
if(proc->flags & MPBOOT) if(proc->flags & MPBOOT)
bcpu = &cpus[ncpu]; bcpu = &cpus[ncpu];
cpus[ncpu].id = ncpu;
ncpu++; ncpu++;
p += sizeof(struct mpproc); p += sizeof(struct mpproc);
continue; continue;
@ -135,7 +137,6 @@ mpinit(void)
panic("mpinit"); panic("mpinit");
} }
} }
if(mp->imcrp){ if(mp->imcrp){
// Bochs doesn't support IMCR, so this doesn't run on Bochs. // Bochs doesn't support IMCR, so this doesn't run on Bochs.
// But it would on real hardware. // But it would on real hardware.

4
pipe.c
View file

@ -82,7 +82,7 @@ pipewrite(struct pipe *p, char *addr, int n)
acquire(&p->lock); acquire(&p->lock);
for(i = 0; i < n; i++){ for(i = 0; i < n; i++){
while(p->nwrite == p->nread + PIPESIZE) { //DOC: pipewrite-full while(p->nwrite == p->nread + PIPESIZE) { //DOC: pipewrite-full
if(p->readopen == 0 || cp->killed){ if(p->readopen == 0 || proc->killed){
release(&p->lock); release(&p->lock);
return -1; return -1;
} }
@ -103,7 +103,7 @@ piperead(struct pipe *p, char *addr, int n)
acquire(&p->lock); acquire(&p->lock);
while(p->nread == p->nwrite && p->writeopen){ //DOC: pipe-empty while(p->nread == p->nwrite && p->writeopen){ //DOC: pipe-empty
if(cp->killed){ if(proc->killed){
release(&p->lock); release(&p->lock);
return -1; return -1;
} }

115
proc.c
View file

@ -65,32 +65,31 @@ procdump(void)
void void
ksegment(void) ksegment(void)
{ {
struct cpu *c1; struct cpu *c;
c1 = &cpus[cpu()]; c = &cpus[cpunum()];
c1->gdt[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0x100000 + 64*1024-1, 0); c->gdt[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0x100000 + 64*1024-1, 0);
c1->gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0); c->gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0);
c1->gdt[SEG_KCPU] = SEG(STA_W, (uint)(&c1->tls+1), 0xffffffff, 0); c->gdt[SEG_KCPU] = SEG(STA_W, (uint)(&c->tls+1), 0xffffffff, 0);
lgdt(c1->gdt, sizeof(c1->gdt)); lgdt(c->gdt, sizeof(c->gdt));
loadfsgs(SEG_KCPU << 3); loadfsgs(SEG_KCPU << 3);
// Initialize cpu-local variables. // Initialize cpu-local variables.
c = c1; cpu = c;
cp = 0; proc = 0;
} }
// Set up CPU's segment descriptors and current process task state. // 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 void
usegment(void) usegment(void)
{ {
pushcli(); pushcli();
c->gdt[SEG_UCODE] = SEG(STA_X|STA_R, (uint)cp->mem, cp->sz-1, DPL_USER); cpu->gdt[SEG_UCODE] = SEG(STA_X|STA_R, proc->mem, proc->sz-1, DPL_USER);
c->gdt[SEG_UDATA] = SEG(STA_W, (uint)cp->mem, cp->sz-1, DPL_USER); cpu->gdt[SEG_UDATA] = SEG(STA_W, proc->mem, proc->sz-1, DPL_USER);
c->gdt[SEG_TSS] = SEG16(STS_T32A, (uint)&c->ts, sizeof(c->ts)-1, 0); cpu->gdt[SEG_TSS] = SEG16(STS_T32A, &cpu->ts, sizeof(cpu->ts)-1, 0);
c->gdt[SEG_TSS].s = 0; cpu->gdt[SEG_TSS].s = 0;
c->ts.ss0 = SEG_KDATA << 3; cpu->ts.ss0 = SEG_KDATA << 3;
c->ts.esp0 = (uint)cp->kstack + KSTACKSIZE; cpu->ts.esp0 = (uint)proc->kstack + KSTACKSIZE;
ltr(SEG_TSS << 3); ltr(SEG_TSS << 3);
popcli(); popcli();
} }
@ -178,14 +177,14 @@ growproc(int n)
{ {
char *newmem; char *newmem;
newmem = kalloc(cp->sz + n); newmem = kalloc(proc->sz + n);
if(newmem == 0) if(newmem == 0)
return -1; return -1;
memmove(newmem, cp->mem, cp->sz); memmove(newmem, proc->mem, proc->sz);
memset(newmem + cp->sz, 0, n); memset(newmem + proc->sz, 0, n);
kfree(cp->mem, cp->sz); kfree(proc->mem, proc->sz);
cp->mem = newmem; proc->mem = newmem;
cp->sz += n; proc->sz += n;
usegment(); usegment();
return 0; return 0;
} }
@ -204,24 +203,24 @@ fork(void)
return -1; return -1;
// Copy process state from p. // Copy process state from p.
np->sz = cp->sz; np->sz = proc->sz;
if((np->mem = kalloc(np->sz)) == 0){ if((np->mem = kalloc(np->sz)) == 0){
kfree(np->kstack, KSTACKSIZE); kfree(np->kstack, KSTACKSIZE);
np->kstack = 0; np->kstack = 0;
np->state = UNUSED; np->state = UNUSED;
return -1; return -1;
} }
memmove(np->mem, cp->mem, np->sz); memmove(np->mem, proc->mem, np->sz);
np->parent = cp; np->parent = proc;
*np->tf = *cp->tf; *np->tf = *proc->tf;
// Clear %eax so that fork returns 0 in the child. // Clear %eax so that fork returns 0 in the child.
np->tf->eax = 0; np->tf->eax = 0;
for(i = 0; i < NOFILE; i++) for(i = 0; i < NOFILE; i++)
if(cp->ofile[i]) if(proc->ofile[i])
np->ofile[i] = filedup(cp->ofile[i]); np->ofile[i] = filedup(proc->ofile[i]);
np->cwd = idup(cp->cwd); np->cwd = idup(proc->cwd);
pid = np->pid; pid = np->pid;
np->state = RUNNABLE; np->state = RUNNABLE;
@ -255,14 +254,14 @@ scheduler(void)
// Switch to chosen process. It is the process's job // Switch to chosen process. It is the process's job
// to release ptable.lock and then reacquire it // to release ptable.lock and then reacquire it
// before jumping back to us. // before jumping back to us.
cp = p; proc = p;
usegment(); usegment();
p->state = RUNNING; p->state = RUNNING;
swtch(&c->context, p->context); swtch(&cpu->scheduler, proc->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.
cp = 0; proc = 0;
} }
release(&ptable.lock); release(&ptable.lock);
@ -270,7 +269,7 @@ scheduler(void)
} }
// Enter scheduler. Must hold only ptable.lock // Enter scheduler. Must hold only ptable.lock
// and have changed cp->state. // and have changed proc->state.
void void
sched(void) sched(void)
{ {
@ -278,16 +277,16 @@ sched(void)
if(!holding(&ptable.lock)) if(!holding(&ptable.lock))
panic("sched ptable.lock"); panic("sched ptable.lock");
if(c->ncli != 1) if(cpu->ncli != 1)
panic("sched locks"); panic("sched locks");
if(cp->state == RUNNING) if(proc->state == RUNNING)
panic("sched running"); panic("sched running");
if(readeflags()&FL_IF) if(readeflags()&FL_IF)
panic("sched interruptible"); panic("sched interruptible");
intena = c->intena; intena = cpu->intena;
swtch(&cp->context, c->context); swtch(&proc->context, cpu->scheduler);
c->intena = intena; cpu->intena = intena;
} }
// Give up the CPU for one scheduling round. // Give up the CPU for one scheduling round.
@ -295,7 +294,7 @@ void
yield(void) yield(void)
{ {
acquire(&ptable.lock); //DOC: yieldlock acquire(&ptable.lock); //DOC: yieldlock
cp->state = RUNNABLE; proc->state = RUNNABLE;
sched(); sched();
release(&ptable.lock); release(&ptable.lock);
} }
@ -312,11 +311,11 @@ forkret(void)
} }
// Atomically release lock and sleep on chan. // Atomically release lock and sleep on chan.
// Reacquires lock when reawakened. // Reacquires lock when awakened.
void void
sleep(void *chan, struct spinlock *lk) sleep(void *chan, struct spinlock *lk)
{ {
if(cp == 0) if(proc == 0)
panic("sleep"); panic("sleep");
if(lk == 0) if(lk == 0)
@ -334,12 +333,12 @@ sleep(void *chan, struct spinlock *lk)
} }
// Go to sleep. // Go to sleep.
cp->chan = chan; proc->chan = chan;
cp->state = SLEEPING; proc->state = SLEEPING;
sched(); sched();
// Tidy up. // Tidy up.
cp->chan = 0; proc->chan = 0;
// Reacquire original lock. // Reacquire original lock.
if(lk != &ptable.lock){ //DOC: sleeplock2 if(lk != &ptable.lock){ //DOC: sleeplock2
@ -371,7 +370,7 @@ wakeup(void *chan)
} }
// Kill the process with the given pid. // Kill the process with the given pid.
// Process won't actually exit until it returns // Process won't exit until it returns
// to user space (see trap in trap.c). // to user space (see trap in trap.c).
int int
kill(int pid) kill(int pid)
@ -394,36 +393,36 @@ kill(int pid)
} }
// Exit the current process. Does not return. // Exit the current process. Does not return.
// Exited processes remain in the zombie state // An exited process remains in the zombie state
// until their parent calls wait() to find out they exited. // until its parent calls wait() to find out it exited.
void void
exit(void) exit(void)
{ {
struct proc *p; struct proc *p;
int fd; int fd;
if(cp == initproc) if(proc == initproc)
panic("init exiting"); panic("init exiting");
// Close all open files. // Close all open files.
for(fd = 0; fd < NOFILE; fd++){ for(fd = 0; fd < NOFILE; fd++){
if(cp->ofile[fd]){ if(proc->ofile[fd]){
fileclose(cp->ofile[fd]); fileclose(proc->ofile[fd]);
cp->ofile[fd] = 0; proc->ofile[fd] = 0;
} }
} }
iput(cp->cwd); iput(proc->cwd);
cp->cwd = 0; proc->cwd = 0;
acquire(&ptable.lock); acquire(&ptable.lock);
// Parent might be sleeping in wait(). // Parent might be sleeping in wait().
wakeup1(cp->parent); wakeup1(proc->parent);
// Pass abandoned children to init. // Pass abandoned children to init.
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
if(p->parent == cp){ if(p->parent == proc){
p->parent = initproc; p->parent = initproc;
if(p->state == ZOMBIE) if(p->state == ZOMBIE)
wakeup1(initproc); wakeup1(initproc);
@ -431,7 +430,7 @@ exit(void)
} }
// Jump into the scheduler, never to return. // Jump into the scheduler, never to return.
cp->state = ZOMBIE; proc->state = ZOMBIE;
sched(); sched();
panic("zombie exit"); panic("zombie exit");
} }
@ -449,7 +448,7 @@ wait(void)
// Scan through table looking for zombie children. // Scan through table looking for zombie children.
havekids = 0; havekids = 0;
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
if(p->parent != cp) if(p->parent != proc)
continue; continue;
havekids = 1; havekids = 1;
if(p->state == ZOMBIE){ if(p->state == ZOMBIE){
@ -468,13 +467,13 @@ wait(void)
} }
// No point waiting if we don't have any children. // No point waiting if we don't have any children.
if(!havekids || cp->killed){ if(!havekids || proc->killed){
release(&ptable.lock); release(&ptable.lock);
return -1; return -1;
} }
// Wait for children to exit. (See wakeup1 call in proc_exit.) // Wait for children to exit. (See wakeup1 call in proc_exit.)
sleep(cp, &ptable.lock); //DOC: wait-sleep sleep(proc, &ptable.lock); //DOC: wait-sleep
} }
} }

8
proc.h
View file

@ -51,8 +51,8 @@ struct proc {
// Per-CPU state // Per-CPU state
struct cpu { struct cpu {
uchar apicid; // Local APIC ID uchar id; // Local APIC ID; index into cpus[] below
struct context *context; // Switch here to enter scheduler struct context *scheduler; // 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
volatile uint booted; // Has the CPU started? volatile uint booted; // Has the CPU started?
@ -70,5 +70,5 @@ extern int ncpu;
// pointed at by gs; the name __thread derives from the use // pointed at by gs; the name __thread derives from the use
// of the same mechanism to provide per-thread storage in // of the same mechanism to provide per-thread storage in
// multithreaded user programs. // multithreaded user programs.
extern __thread struct cpu *c; // This cpu. extern __thread struct cpu *cpu; // This cpu.
extern __thread struct proc *cp; // Current process on this cpu. extern __thread struct proc *proc; // Current process on this cpu.

View file

@ -45,6 +45,8 @@ file.c
sysfile.c sysfile.c
exec.c exec.c
# pipes # pipes
pipe.c pipe.c

View file

@ -13,7 +13,7 @@ initlock(struct spinlock *lk, char *name)
{ {
lk->name = name; lk->name = name;
lk->locked = 0; lk->locked = 0;
lk->cpu = 0xffffffff; lk->cpu = 0;
} }
// Acquire the lock. // Acquire the lock.
@ -34,10 +34,7 @@ acquire(struct spinlock *lk)
; ;
// Record info about lock acquisition for debugging. // Record info about lock acquisition for debugging.
// The +10 is only so that we can tell the difference lk->cpu = cpu;
// between forgetting to initialize lock->cpu
// and holding a lock on cpu 0.
lk->cpu = cpu() + 10;
getcallerpcs(&lk, lk->pcs); getcallerpcs(&lk, lk->pcs);
} }
@ -49,7 +46,7 @@ release(struct spinlock *lk)
panic("release"); panic("release");
lk->pcs[0] = 0; lk->pcs[0] = 0;
lk->cpu = 0xffffffff; lk->cpu = 0;
// The xchg serializes, so that reads before release are // The xchg serializes, so that reads before release are
// not reordered after it. The 1996 PentiumPro manual (Volume 3, // not reordered after it. The 1996 PentiumPro manual (Volume 3,
@ -87,7 +84,7 @@ getcallerpcs(void *v, uint pcs[])
int int
holding(struct spinlock *lock) holding(struct spinlock *lock)
{ {
return lock->locked && lock->cpu == cpu() + 10; return lock->locked && lock->cpu == cpu;
} }
@ -102,8 +99,8 @@ pushcli(void)
eflags = readeflags(); eflags = readeflags();
cli(); cli();
if(c->ncli++ == 0) if(cpu->ncli++ == 0)
c->intena = eflags & FL_IF; cpu->intena = eflags & FL_IF;
} }
void void
@ -111,9 +108,9 @@ popcli(void)
{ {
if(readeflags()&FL_IF) if(readeflags()&FL_IF)
panic("popcli - interruptible"); panic("popcli - interruptible");
if(--c->ncli < 0) if(--cpu->ncli < 0)
panic("popcli"); panic("popcli");
if(c->ncli == 0 && c->intena) if(cpu->ncli == 0 && cpu->intena)
sti(); sti();
} }

View file

@ -4,7 +4,7 @@ struct spinlock {
// For debugging: // For debugging:
char *name; // Name of lock. char *name; // Name of lock.
int cpu; // The number of the cpu holding the lock. struct cpu *cpu; // The cpu holding the lock.
uint pcs[10]; // The call stack (an array of program counters) uint pcs[10]; // The call stack (an array of program counters)
// that locked the lock. // that locked the lock.
}; };

View file

@ -44,7 +44,7 @@ fetchstr(struct proc *p, uint addr, char **pp)
int int
argint(int n, int *ip) argint(int n, int *ip)
{ {
return fetchint(cp, cp->tf->esp + 4 + 4*n, ip); return fetchint(proc, proc->tf->esp + 4 + 4*n, ip);
} }
// Fetch the nth word-sized system call argument as a pointer // Fetch the nth word-sized system call argument as a pointer
@ -57,9 +57,9 @@ argptr(int n, char **pp, int size)
if(argint(n, &i) < 0) if(argint(n, &i) < 0)
return -1; return -1;
if((uint)i >= cp->sz || (uint)i+size >= cp->sz) if((uint)i >= proc->sz || (uint)i+size >= proc->sz)
return -1; return -1;
*pp = cp->mem + i; *pp = proc->mem + i;
return 0; return 0;
} }
@ -73,7 +73,7 @@ argstr(int n, char **pp)
int addr; int addr;
if(argint(n, &addr) < 0) if(argint(n, &addr) < 0)
return -1; return -1;
return fetchstr(cp, addr, pp); return fetchstr(proc, addr, pp);
} }
extern int sys_chdir(void); extern int sys_chdir(void);
@ -125,12 +125,12 @@ syscall(void)
{ {
int num; int num;
num = cp->tf->eax; num = proc->tf->eax;
if(num >= 0 && num < NELEM(syscalls) && syscalls[num]) if(num >= 0 && num < NELEM(syscalls) && syscalls[num])
cp->tf->eax = syscalls[num](); proc->tf->eax = syscalls[num]();
else { else {
cprintf("%d %s: unknown sys call %d\n", cprintf("%d %s: unknown sys call %d\n",
cp->pid, cp->name, num); proc->pid, proc->name, num);
cp->tf->eax = -1; proc->tf->eax = -1;
} }
} }

View file

@ -18,7 +18,7 @@ argfd(int n, int *pfd, struct file **pf)
if(argint(n, &fd) < 0) if(argint(n, &fd) < 0)
return -1; return -1;
if(fd < 0 || fd >= NOFILE || (f=cp->ofile[fd]) == 0) if(fd < 0 || fd >= NOFILE || (f=proc->ofile[fd]) == 0)
return -1; return -1;
if(pfd) if(pfd)
*pfd = fd; *pfd = fd;
@ -35,8 +35,8 @@ fdalloc(struct file *f)
int fd; int fd;
for(fd = 0; fd < NOFILE; fd++){ for(fd = 0; fd < NOFILE; fd++){
if(cp->ofile[fd] == 0){ if(proc->ofile[fd] == 0){
cp->ofile[fd] = f; proc->ofile[fd] = f;
return fd; return fd;
} }
} }
@ -89,7 +89,7 @@ sys_close(void)
if(argfd(0, &fd, &f) < 0) if(argfd(0, &fd, &f) < 0)
return -1; return -1;
cp->ofile[fd] = 0; proc->ofile[fd] = 0;
fileclose(f); fileclose(f);
return 0; return 0;
} }
@ -338,8 +338,8 @@ sys_chdir(void)
return -1; return -1;
} }
iunlock(ip); iunlock(ip);
iput(cp->cwd); iput(proc->cwd);
cp->cwd = ip; proc->cwd = ip;
return 0; return 0;
} }
@ -356,13 +356,13 @@ sys_exec(void)
for(i=0;; i++){ for(i=0;; i++){
if(i >= NELEM(argv)) if(i >= NELEM(argv))
return -1; return -1;
if(fetchint(cp, uargv+4*i, (int*)&uarg) < 0) if(fetchint(proc, uargv+4*i, (int*)&uarg) < 0)
return -1; return -1;
if(uarg == 0){ if(uarg == 0){
argv[i] = 0; argv[i] = 0;
break; break;
} }
if(fetchstr(cp, uarg, &argv[i]) < 0) if(fetchstr(proc, uarg, &argv[i]) < 0)
return -1; return -1;
} }
return exec(path, argv); return exec(path, argv);
@ -382,7 +382,7 @@ sys_pipe(void)
fd0 = -1; fd0 = -1;
if((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0){ if((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0){
if(fd0 >= 0) if(fd0 >= 0)
cp->ofile[fd0] = 0; proc->ofile[fd0] = 0;
fileclose(rf); fileclose(rf);
fileclose(wf); fileclose(wf);
return -1; return -1;

View file

@ -37,7 +37,7 @@ sys_kill(void)
int int
sys_getpid(void) sys_getpid(void)
{ {
return cp->pid; return proc->pid;
} }
int int
@ -48,7 +48,7 @@ sys_sbrk(void)
if(argint(0, &n) < 0) if(argint(0, &n) < 0)
return -1; return -1;
addr = cp->sz; addr = proc->sz;
if(growproc(n) < 0) if(growproc(n) < 0)
return -1; return -1;
return addr; return addr;
@ -64,7 +64,7 @@ sys_sleep(void)
acquire(&tickslock); acquire(&tickslock);
ticks0 = ticks; ticks0 = ticks;
while(ticks - ticks0 < n){ while(ticks - ticks0 < n){
if(cp->killed){ if(proc->killed){
release(&tickslock); release(&tickslock);
return -1; return -1;
} }

View file

@ -6,9 +6,9 @@ on the same line as the name, the line number (or, in a few cases, numbers)
where the name is defined. Successive lines in an entry list the line where the name is defined. Successive lines in an entry list the line
numbers where the name is used. For example, this entry: numbers where the name is used. For example, this entry:
swtch 2256 swtch 2208
0311 1928 1962 2255 0318 1928 1967 2207
2256 2208
indicates that swtch is defined on line 2256 and is mentioned on five lines indicates that swtch is defined on line 2208 and is mentioned on five lines
on sheets 03, 19, and 22. on sheets 03, 19, and 22.

24
trap.c
View file

@ -36,18 +36,18 @@ void
trap(struct trapframe *tf) trap(struct trapframe *tf)
{ {
if(tf->trapno == T_SYSCALL){ if(tf->trapno == T_SYSCALL){
if(cp->killed) if(proc->killed)
exit(); exit();
cp->tf = tf; proc->tf = tf;
syscall(); syscall();
if(cp->killed) if(proc->killed)
exit(); exit();
return; return;
} }
switch(tf->trapno){ switch(tf->trapno){
case T_IRQ0 + IRQ_TIMER: case T_IRQ0 + IRQ_TIMER:
if(cpu() == 0){ if(cpu->id == 0){
acquire(&tickslock); acquire(&tickslock);
ticks++; ticks++;
wakeup(&ticks); wakeup(&ticks);
@ -70,35 +70,35 @@ trap(struct trapframe *tf)
case T_IRQ0 + 7: case T_IRQ0 + 7:
case T_IRQ0 + IRQ_SPURIOUS: case T_IRQ0 + IRQ_SPURIOUS:
cprintf("cpu%d: spurious interrupt at %x:%x\n", cprintf("cpu%d: spurious interrupt at %x:%x\n",
cpu(), tf->cs, tf->eip); cpu->id, tf->cs, tf->eip);
lapiceoi(); lapiceoi();
break; break;
default: default:
if(cp == 0 || (tf->cs&3) == 0){ if(proc == 0 || (tf->cs&3) == 0){
// In kernel, it must be our mistake. // In kernel, it must be our mistake.
cprintf("unexpected trap %d from cpu %d eip %x\n", cprintf("unexpected trap %d from cpu %d eip %x\n",
tf->trapno, cpu(), tf->eip); tf->trapno, cpu->id, tf->eip);
panic("trap"); panic("trap");
} }
// In user space, assume process misbehaved. // In user space, assume process misbehaved.
cprintf("pid %d %s: trap %d err %d on cpu %d eip %x -- kill proc\n", cprintf("pid %d %s: trap %d err %d on cpu %d eip %x -- kill proc\n",
cp->pid, cp->name, tf->trapno, tf->err, cpu(), tf->eip); proc->pid, proc->name, tf->trapno, tf->err, cpu->id, tf->eip);
cp->killed = 1; proc->killed = 1;
} }
// Force process exit if it has been killed and is in user space. // Force process exit if it has been killed and is in user space.
// (If it is still executing in the kernel, let it keep running // (If it is still executing in the kernel, let it keep running
// until it gets to the regular system call return.) // until it gets to the regular system call return.)
if(cp && cp->killed && (tf->cs&3) == DPL_USER) if(proc && proc->killed && (tf->cs&3) == DPL_USER)
exit(); exit();
// Force process to give up CPU on clock tick. // Force process to give up CPU on clock tick.
// If interrupts were on while locks held, would need to check nlock. // If interrupts were on while locks held, would need to check nlock.
if(cp && cp->state == RUNNING && tf->trapno == T_IRQ0+IRQ_TIMER) if(proc && proc->state == RUNNING && tf->trapno == T_IRQ0+IRQ_TIMER)
yield(); yield();
// Check if the process has been killed since we yielded // Check if the process has been killed since we yielded
if(cp && cp->killed && (tf->cs&3) == DPL_USER) if(proc && proc->killed && (tf->cs&3) == DPL_USER)
exit(); exit();
} }

BIN
xv6.pdf

Binary file not shown.

4505
xv6.ps

File diff suppressed because it is too large Load diff