clean up stale error checks and panics

delete unused functions
a few comments
This commit is contained in:
rtm 2006-08-29 14:45:45 +00:00
parent b52151e032
commit 2b19190c13
11 changed files with 46 additions and 347 deletions

44
Notes
View file

@ -95,49 +95,15 @@ inode->count counts in-memory pointers to the struct
blocks and inodes have ad-hoc sleep-locks blocks and inodes have ad-hoc sleep-locks
provide a single mechanism? provide a single mechanism?
test 14-character file names
and file arguments longer than 14
kalloc() can return 0; do callers handle this right? kalloc() can return 0; do callers handle this right?
OH! recursive interrupts will use up any amount of cpu[].stack!
underflow and wrecks *previous* cpu's struct
disk scheduling
mkdir
sh arguments
sh redirection
indirect blocks
is there a create/create race for same file name?
resulting in two entries w/ same name in directory?
why does shell often ignore first line of input?
test: one process unlinks a file while another links to it test: one process unlinks a file while another links to it
test: one process opens a file while another deletes it test: one process opens a file while another deletes it
test: mkdir. deadlock d/.. vs ../d, two processes. test: deadlock d/.. vs ../d, two processes.
test: dup() shared fd->off test: dup() shared fd->off
test: sbrk test: sbrk
test: does echo foo > x truncate x? test: does echo foo > x truncate x?
make proc[0] runnable
cpu early tss and gdt
how do we get cpu0 scheduler() to use mpstack, not proc[0].kstack?
when iget() first sleeps, where does it longjmp to?
maybe set up proc[0] to be runnable, with entry proc0main(), then
have main() call scheduler()?
perhaps so proc[0] uses right kstack?
and scheduler() uses mpstack?
ltr sets the busy bit in the TSS, faults if already set
so gdt and TSS per cpu?
we don't want to be using some random process's gdt when it changes it.
maybe get rid of per-proc gdt and ts
one per cpu
refresh it when needed
setupsegs(proc *)
why do we get 0 characters from keyboard?
are the locks in the right place in keyboardintr?
sh: support pipes? leave it for the class? sh: support pipes? leave it for the class?
sh: dynamic memory allocation? sh: dynamic memory allocation?
sh: should sh support ; () & --- need malloc sh: should sh support ; () & --- need malloc
@ -146,3 +112,11 @@ sh: stop stdin on ctrl-d (for cat > y)
really should have bdwrite() for file content really should have bdwrite() for file content
and make some inode updates async and make some inode updates async
so soft updates make sense so soft updates make sense
disk scheduling
echo foo > bar should truncate bar
so O_CREATE should not truncate
but O_TRUNC should
make it work on one cpu
make it work on amsterdam

View file

@ -9,10 +9,6 @@ struct spinlock console_lock;
int panicked = 0; int panicked = 0;
int use_console_lock = 0; int use_console_lock = 0;
// per-cpu copy of output to help panic/lock debugging
char obuf[NCPU][1024];
uint obufi[NCPU];
/* /*
* copy console output to parallel port, which you can tell * copy console output to parallel port, which you can tell
* .bochsrc to copy to the stdout: * .bochsrc to copy to the stdout:
@ -37,10 +33,6 @@ cons_putc(int c)
ushort *crt = (ushort *) 0xB8000; // base of CGA memory ushort *crt = (ushort *) 0xB8000; // base of CGA memory
int ind; int ind;
obuf[rcr4()][obufi[rcr4()]++] = c;
if(obufi[rcr4()] >= 1024)
obufi[rcr4()] = 0;
if(panicked){ if(panicked){
cli(); cli();
for(;;) for(;;)

2
defs.h
View file

@ -16,7 +16,7 @@ struct jmpbuf;
void setupsegs(struct proc *); void setupsegs(struct proc *);
struct proc * copyproc(struct proc*); struct proc * copyproc(struct proc*);
struct spinlock; struct spinlock;
char *growproc(int); int growproc(int);
void sleep(void *, struct spinlock *); void sleep(void *, struct spinlock *);
void wakeup(void *); void wakeup(void *);
void scheduler(void); void scheduler(void);

4
main.c
View file

@ -25,8 +25,6 @@ main0(void)
int i; int i;
struct proc *p; struct proc *p;
lcr4(0); // xxx copy of cpu #
// clear BSS // clear BSS
memset(edata, 0, end - edata); memset(edata, 0, end - edata);
@ -97,8 +95,6 @@ main0(void)
void void
mpmain(void) mpmain(void)
{ {
lcr4(1); // xxx copy of cpu #
cprintf("cpu%d: starting\n", cpu()); cprintf("cpu%d: starting\n", cpu());
idtinit(); // CPU's idt idtinit(); // CPU's idt
if(cpu() == 0) if(cpu() == 0)

20
param.h
View file

@ -1,10 +1,10 @@
#define NPROC 64 #define NPROC 64 // maximum number of processes
#define PAGE 4096 #define PAGE 4096 // granularity of user-space memory allocation
#define KSTACKSIZE PAGE #define KSTACKSIZE PAGE // size of per-process kernel stack
#define NCPU 8 #define NCPU 8 // maximum number of CPUs
#define NOFILE 16 // file descriptors per process #define NOFILE 16 // file descriptors per process
#define NFD 100 // file descriptors per system #define NFD 100 // file descriptors per system
#define NREQUEST 100 // outstanding disk requests #define NREQUEST 100 // outstanding disk requests
#define NBUF 10 #define NBUF 10 // size of disk block cache
#define NINODE 100 #define NINODE 100 // maximum number of active i-nodes
#define NDEV 10 #define NDEV 10 // maximum major device number

8
proc.c
View file

@ -138,22 +138,22 @@ copyproc(struct proc* p)
return np; return np;
} }
char * int
growproc(int n) growproc(int n)
{ {
struct proc *cp = curproc[cpu()]; struct proc *cp = curproc[cpu()];
char *newmem, *oldmem; char *newmem, *oldmem;
newmem = kalloc(cp->sz + n); newmem = kalloc(cp->sz + n);
if(newmem == 0) return (char *) -1; if(newmem == 0)
return -1;
memmove(newmem, cp->mem, cp->sz); memmove(newmem, cp->mem, cp->sz);
memset(newmem + cp->sz, 0, n); memset(newmem + cp->sz, 0, n);
oldmem = cp->mem; oldmem = cp->mem;
cp->mem = newmem; cp->mem = newmem;
kfree(oldmem, cp->sz); kfree(oldmem, cp->sz);
cprintf("growproc: added %d bytes to %d bytes\n", n, cp->sz);
cp->sz += n; cp->sz += n;
return cp->sz - n; return 0;
} }
// Per-CPU process scheduler. // Per-CPU process scheduler.

View file

@ -6,18 +6,11 @@
#include "proc.h" #include "proc.h"
#include "spinlock.h" #include "spinlock.h"
// Can't call cprintf from inside these routines,
// because cprintf uses them itself.
//#define cprintf dont_use_cprintf
#define LOCKMAGIC 0x6673ffea
extern int use_console_lock; extern int use_console_lock;
void void
initlock(struct spinlock *lock, char *name) initlock(struct spinlock *lock, char *name)
{ {
lock->magic = LOCKMAGIC;
lock->name = name; lock->name = name;
lock->locked = 0; lock->locked = 0;
lock->cpu = 0xffffffff; lock->cpu = 0xffffffff;
@ -38,8 +31,6 @@ getcallerpcs(void *v, uint pcs[])
void void
acquire(struct spinlock * lock) acquire(struct spinlock * lock)
{ {
if(lock->magic != LOCKMAGIC)
panic("weird lock magic");
if(holding(lock)) if(holding(lock))
panic("acquire"); panic("acquire");
@ -47,34 +38,32 @@ acquire(struct spinlock * lock)
cli(); cli();
cpus[cpu()].nlock++; cpus[cpu()].nlock++;
while(cmpxchg(0, 1, &lock->locked) == 1) while(cmpxchg(0, 1, &lock->locked) == 1)
; ;
cpuid(0, 0, 0, 0, 0); // memory barrier cpuid(0, 0, 0, 0, 0); // memory barrier
getcallerpcs(&lock, lock->pcs); getcallerpcs(&lock, lock->pcs);
lock->cpu = cpu() + 10; lock->cpu = cpu() + 10;
cpus[cpu()].lastacquire = lock; cpus[cpu()].lastacquire = lock;
} }
void void
release(struct spinlock * lock) release(struct spinlock * lock)
{ {
if(lock->magic != LOCKMAGIC)
panic("weird lock magic");
if(!holding(lock)) if(!holding(lock))
panic("release"); panic("release");
cpus[cpu()].lastrelease = lock; cpus[cpu()].lastrelease = lock;
lock->pcs[0] = 0; lock->pcs[0] = 0;
lock->cpu = 0xffffffff; lock->cpu = 0xffffffff;
cpuid(0, 0, 0, 0, 0); // memory barrier cpuid(0, 0, 0, 0, 0); // memory barrier
lock->locked = 0; lock->locked = 0;
if(--cpus[cpu()].nlock == 0) if(--cpus[cpu()].nlock == 0)
sti(); sti();
} }
int int
holding(struct spinlock *lock) holding(struct spinlock *lock)
{ {
return lock->locked && lock->cpu == cpu() + 10; return lock->locked && lock->cpu == cpu() + 10;
} }

View file

@ -1,5 +1,4 @@
struct spinlock { struct spinlock {
uint magic;
char *name; char *name;
uint locked; uint locked;
int cpu; int cpu;

View file

@ -473,15 +473,15 @@ sys_getpid(void)
int int
sys_sbrk(void) sys_sbrk(void)
{ {
char *r;
int n; int n;
struct proc *cp = curproc[cpu()]; struct proc *cp = curproc[cpu()];
if(fetcharg(0, &n) < 0) if(fetcharg(0, &n) < 0)
return -1; return -1;
r = growproc(n); if(growproc(n) != 0)
return -1;
setupsegs(cp); setupsegs(cp);
return (int) r; return 0;
} }
int int

45
trap.c
View file

@ -35,58 +35,18 @@ trap(struct trapframe *tf)
{ {
int v = tf->trapno; int v = tf->trapno;
if(cpus[cpu()].nlock){
cprintf("trap v %d eip %x cpu %d nlock %d\n",
v, tf->eip, cpu(), cpus[cpu()].nlock);
panic("interrupt while holding a lock");
}
if(curproc[cpu()] == 0){
if(&tf < cpus[cpu()].mpstack || &tf > cpus[cpu()].mpstack + MPSTACK){
cprintf("&tf %x mpstack %x\n", &tf, cpus[cpu()].mpstack);
panic("trap cpu stack");
}
} else if(curproc[cpu()]){
if(&tf < curproc[cpu()]->kstack){
panic("trap kstack");
}
}
if(v == T_SYSCALL){ if(v == T_SYSCALL){
struct proc *cp = curproc[cpu()]; struct proc *cp = curproc[cpu()];
int num = cp->tf->eax; int num = cp->tf->eax;
if((read_eflags() & FL_IF) == 0)
panic("syscall but interrupts now disabled");
if(cp == 0)
panic("syscall with no proc");
if(cp->killed) if(cp->killed)
proc_exit(); proc_exit();
cp->tf = tf; cp->tf = tf;
syscall(); syscall();
if(cp != curproc[cpu()])
panic("trap ret wrong curproc");
if(cp->state != RUNNING)
panic("trap ret but not RUNNING");
if(tf != cp->tf)
panic("trap ret wrong tf");
if(cpus[cpu()].nlock){
cprintf("num=%d\n", num);
panic("syscall returning locks held");
}
if((read_eflags() & FL_IF) == 0)
panic("syscall returning but FL_IF clear");
if(read_esp() < (uint)cp->kstack ||
read_esp() >= (uint)cp->kstack + KSTACKSIZE)
panic("trap ret esp wrong");
if(cp->killed) if(cp->killed)
proc_exit(); proc_exit();
// XXX probably ought to lgdt on trap return
return; return;
} }
//if(read_eflags() & FL_IF)
//panic("interrupt but interrupts enabled");
if(v == (IRQ_OFFSET + IRQ_TIMER)){ if(v == (IRQ_OFFSET + IRQ_TIMER)){
struct proc *cp = curproc[cpu()]; struct proc *cp = curproc[cpu()];
lapic_timerintr(); lapic_timerintr();
@ -108,8 +68,6 @@ trap(struct trapframe *tf)
if(v == (IRQ_OFFSET + IRQ_IDE)){ if(v == (IRQ_OFFSET + IRQ_IDE)){
ide_intr(); ide_intr();
if(cpus[cpu()].nlock)
panic("ide_intr returned while holding a lock");
cli(); // prevent a waiting interrupt from overflowing stack cli(); // prevent a waiting interrupt from overflowing stack
lapic_eoi(); lapic_eoi();
return; return;
@ -117,9 +75,6 @@ trap(struct trapframe *tf)
if(v == (IRQ_OFFSET + IRQ_KBD)){ if(v == (IRQ_OFFSET + IRQ_KBD)){
kbd_intr(); kbd_intr();
if(cpus[cpu()].nlock){
panic("kbd_intr returned while holding a lock");
}
cli(); // prevent a waiting interrupt from overflowing stack cli(); // prevent a waiting interrupt from overflowing stack
lapic_eoi(); lapic_eoi();
return; return;

212
x86.h
View file

@ -1,45 +1,3 @@
static __inline void breakpoint(void) __attribute__((always_inline));
static __inline uchar inb(int port) __attribute__((always_inline));
static __inline void insb(int port, void *addr, int cnt) __attribute__((always_inline));
static __inline ushort inw(int port) __attribute__((always_inline));
static __inline void insw(int port, void *addr, int cnt) __attribute__((always_inline));
static __inline uint inl(int port) __attribute__((always_inline));
static __inline void insl(int port, void *addr, int cnt) __attribute__((always_inline));
static __inline void outb(int port, uchar data) __attribute__((always_inline));
static __inline void outsb(int port, const void *addr, int cnt) __attribute__((always_inline));
static __inline void outw(int port, ushort data) __attribute__((always_inline));
static __inline void outsw(int port, const void *addr, int cnt) __attribute__((always_inline));
static __inline void outsl(int port, const void *addr, int cnt) __attribute__((always_inline));
static __inline void outl(int port, uint data) __attribute__((always_inline));
static __inline void invlpg(void *addr) __attribute__((always_inline));
struct segdesc;
static __inline void lgdt(struct segdesc *p, int) __attribute__((always_inline));
struct gatedesc;
static __inline void lidt(struct gatedesc *p, int) __attribute__((always_inline));
static __inline void lldt(ushort sel) __attribute__((always_inline));
static __inline void ltr(ushort sel) __attribute__((always_inline));
static __inline void lcr0(uint val) __attribute__((always_inline));
static __inline uint rcr0(void) __attribute__((always_inline));
static __inline uint rcr2(void) __attribute__((always_inline));
static __inline void lcr3(uint val) __attribute__((always_inline));
static __inline uint rcr3(void) __attribute__((always_inline));
static __inline void lcr4(uint val) __attribute__((always_inline));
static __inline uint rcr4(void) __attribute__((always_inline));
static __inline void tlbflush(void) __attribute__((always_inline));
static __inline uint read_eflags(void) __attribute__((always_inline));
static __inline void write_eflags(uint eflags) __attribute__((always_inline));
static __inline uint read_ebp(void) __attribute__((always_inline));
static __inline uint read_esp(void) __attribute__((always_inline));
static __inline void cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp);
static __inline void cli(void) __attribute__((always_inline));
static __inline void sti(void) __attribute__((always_inline));
static __inline void
breakpoint(void)
{
__asm __volatile("int3");
}
static __inline uchar static __inline uchar
inb(int port) inb(int port)
{ {
@ -48,40 +6,6 @@ inb(int port)
return data; return data;
} }
static __inline void
insb(int port, void *addr, int cnt)
{
__asm __volatile("cld\n\trepne\n\tinsb" :
"=D" (addr), "=c" (cnt) :
"d" (port), "0" (addr), "1" (cnt) :
"memory", "cc");
}
static __inline ushort
inw(int port)
{
ushort data;
__asm __volatile("inw %w1,%0" : "=a" (data) : "d" (port));
return data;
}
static __inline void
insw(int port, void *addr, int cnt)
{
__asm __volatile("cld\n\trepne\n\tinsw" :
"=D" (addr), "=c" (cnt) :
"d" (port), "0" (addr), "1" (cnt) :
"memory", "cc");
}
static __inline uint
inl(int port)
{
uint data;
__asm __volatile("inl %w1,%0" : "=a" (data) : "d" (port));
return data;
}
static __inline void static __inline void
insl(int port, void *addr, int cnt) insl(int port, void *addr, int cnt)
{ {
@ -97,30 +21,12 @@ outb(int port, uchar data)
__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port)); __asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
} }
static __inline void
outsb(int port, const void *addr, int cnt)
{
__asm __volatile("cld\n\trepne\n\toutsb" :
"=S" (addr), "=c" (cnt) :
"d" (port), "0" (addr), "1" (cnt) :
"cc");
}
static __inline void static __inline void
outw(int port, ushort data) outw(int port, ushort data)
{ {
__asm __volatile("outw %0,%w1" : : "a" (data), "d" (port)); __asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
} }
static __inline void
outsw(int port, const void *addr, int cnt)
{
__asm __volatile("cld\n\trepne\n\toutsw" :
"=S" (addr), "=c" (cnt) :
"d" (port), "0" (addr), "1" (cnt) :
"cc");
}
static __inline void static __inline void
outsl(int port, const void *addr, int cnt) outsl(int port, const void *addr, int cnt)
{ {
@ -130,17 +36,7 @@ outsl(int port, const void *addr, int cnt)
"cc"); "cc");
} }
static __inline void struct segdesc;
outl(int port, uint data)
{
__asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
}
static __inline void
invlpg(void *addr)
{
__asm __volatile("invlpg (%0)" : : "r" (addr) : "memory");
}
static __inline void static __inline void
lgdt(struct segdesc *p, int size) lgdt(struct segdesc *p, int size)
@ -154,6 +50,8 @@ lgdt(struct segdesc *p, int size)
asm volatile("lgdt (%0)" : : "g" (pd)); asm volatile("lgdt (%0)" : : "g" (pd));
} }
struct gatedesc;
static __inline void static __inline void
lidt(struct gatedesc *p, int size) lidt(struct gatedesc *p, int size)
{ {
@ -166,76 +64,12 @@ lidt(struct gatedesc *p, int size)
asm volatile("lidt (%0)" : : "g" (pd)); asm volatile("lidt (%0)" : : "g" (pd));
} }
static __inline void
lldt(ushort sel)
{
__asm __volatile("lldt %0" : : "r" (sel));
}
static __inline void static __inline void
ltr(ushort sel) ltr(ushort sel)
{ {
__asm __volatile("ltr %0" : : "r" (sel)); __asm __volatile("ltr %0" : : "r" (sel));
} }
static __inline void
lcr0(uint val)
{
__asm __volatile("movl %0,%%cr0" : : "r" (val));
}
static __inline uint
rcr0(void)
{
uint val;
__asm __volatile("movl %%cr0,%0" : "=r" (val));
return val;
}
static __inline uint
rcr2(void)
{
uint val;
__asm __volatile("movl %%cr2,%0" : "=r" (val));
return val;
}
static __inline void
lcr3(uint val)
{
__asm __volatile("movl %0,%%cr3" : : "r" (val));
}
static __inline uint
rcr3(void)
{
uint val;
__asm __volatile("movl %%cr3,%0" : "=r" (val));
return val;
}
static __inline void
lcr4(uint val)
{
__asm __volatile("movl %0,%%cr4" : : "r" (val));
}
static __inline uint
rcr4(void)
{
uint cr4;
__asm __volatile("movl %%cr4,%0" : "=r" (cr4));
return cr4;
}
static __inline void
tlbflush(void)
{
uint cr3;
__asm __volatile("movl %%cr3,%0" : "=r" (cr3));
__asm __volatile("movl %0,%%cr3" : : "r" (cr3));
}
static __inline uint static __inline uint
read_eflags(void) read_eflags(void)
{ {
@ -250,46 +84,6 @@ write_eflags(uint eflags)
__asm __volatile("pushl %0; popfl" : : "r" (eflags)); __asm __volatile("pushl %0; popfl" : : "r" (eflags));
} }
static __inline uint
read_ebp(void)
{
uint ebp;
__asm __volatile("movl %%ebp,%0" : "=r" (ebp));
return ebp;
}
static __inline uint
read_esp(void)
{
uint esp;
__asm __volatile("movl %%esp,%0" : "=r" (esp));
return esp;
}
static __inline uint
read_esi(void)
{
uint esi;
__asm __volatile("movl %%esi,%0" : "=r" (esi));
return esi;
}
static __inline uint
read_edi(void)
{
uint edi;
__asm __volatile("movl %%edi,%0" : "=r" (edi));
return edi;
}
static __inline uint
read_ebx(void)
{
uint ebx;
__asm __volatile("movl %%ebx,%0" : "=r" (ebx));
return ebx;
}
static __inline void static __inline void
cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp) cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp)
{ {