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:
parent
0aef891495
commit
48755214c9
23 changed files with 2437 additions and 2379 deletions
2
Makefile
2
Makefile
|
@ -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''
|
||||||
|
|
|
@ -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
2
defs.h
|
@ -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
14
exec.c
|
@ -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
4
fs.c
|
@ -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
2
ide.c
|
@ -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);
|
||||||
|
|
||||||
|
|
2
lapic.c
2
lapic.c
|
@ -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
20
main.c
|
@ -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)
|
||||||
|
|
16
mmu.h
16
mmu.h
|
@ -42,15 +42,15 @@ 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
11
mp.c
|
@ -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
4
pipe.c
|
@ -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
115
proc.c
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
proc.h
10
proc.h
|
@ -31,7 +31,7 @@ struct proc {
|
||||||
char *mem; // Start of process memory (kernel address)
|
char *mem; // Start of process memory (kernel address)
|
||||||
uint sz; // Size of process memory (bytes)
|
uint sz; // Size of process memory (bytes)
|
||||||
char *kstack; // Bottom of kernel stack for this process
|
char *kstack; // Bottom of kernel stack for this process
|
||||||
enum procstate state; // Process state
|
enum procstate state; // Process state
|
||||||
volatile int pid; // Process ID
|
volatile int pid; // Process ID
|
||||||
struct proc *parent; // Parent process
|
struct proc *parent; // Parent process
|
||||||
struct trapframe *tf; // Trap frame for current syscall
|
struct trapframe *tf; // Trap frame for current syscall
|
||||||
|
@ -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.
|
||||||
|
|
|
@ -45,6 +45,8 @@ file.c
|
||||||
sysfile.c
|
sysfile.c
|
||||||
exec.c
|
exec.c
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# pipes
|
# pipes
|
||||||
pipe.c
|
pipe.c
|
||||||
|
|
||||||
|
|
19
spinlock.c
19
spinlock.c
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
spinlock.h
10
spinlock.h
|
@ -1,11 +1,11 @@
|
||||||
// Mutual exclusion lock.
|
// Mutual exclusion lock.
|
||||||
struct spinlock {
|
struct spinlock {
|
||||||
uint locked; // Is the lock held?
|
uint locked; // Is the lock held?
|
||||||
|
|
||||||
// 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.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
16
syscall.c
16
syscall.c
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
18
sysfile.c
18
sysfile.c
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
8
toc.ftr
8
toc.ftr
|
@ -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
24
trap.c
|
@ -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
BIN
xv6.pdf
Binary file not shown.
Loading…
Reference in a new issue