summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bio.c2
-rw-r--r--console.c2
-rw-r--r--defs.h2
-rw-r--r--fd.c2
-rw-r--r--fd.h3
-rw-r--r--fs.c9
-rw-r--r--ide.c2
-rw-r--r--kalloc.c2
-rw-r--r--main.c2
-rw-r--r--proc.c6
-rw-r--r--proc.h2
-rw-r--r--spinlock.c10
-rw-r--r--spinlock.h1
-rw-r--r--syscall.c39
-rw-r--r--syscall.h1
-rw-r--r--userfs.c16
-rw-r--r--usys.S1
17 files changed, 89 insertions, 13 deletions
diff --git a/bio.c b/bio.c
index 9be11df..c1a4bd6 100644
--- a/bio.c
+++ b/bio.c
@@ -8,7 +8,7 @@
#include "buf.h"
struct buf buf[NBUF];
-struct spinlock buf_table_lock;
+struct spinlock buf_table_lock = { "buf_table" };
struct buf *
getblk()
diff --git a/console.c b/console.c
index 9756c84..9a7d725 100644
--- a/console.c
+++ b/console.c
@@ -3,7 +3,7 @@
#include "defs.h"
#include "spinlock.h"
-struct spinlock console_lock;
+struct spinlock console_lock = { "console" };
int panicked = 0;
int use_console_lock = 0;
diff --git a/defs.h b/defs.h
index 84616c9..c6c333b 100644
--- a/defs.h
+++ b/defs.h
@@ -99,7 +99,7 @@ void brelse(struct buf *);
struct inode * iget(uint dev, uint inum);
void ilock(struct inode *ip);
void iunlock(struct inode *ip);
-void iincref(struct inode *ip);
+void idecref(struct inode *ip);
void iput(struct inode *ip);
struct inode * namei(char *path);
int readi(struct inode *ip, void *xdst, uint off, uint n);
diff --git a/fd.c b/fd.c
index 6ce4aec..9ce6bae 100644
--- a/fd.c
+++ b/fd.c
@@ -86,6 +86,8 @@ fd_close(struct fd *fd)
if(--fd->ref == 0){
if(fd->type == FD_PIPE){
pipe_close(fd->pipe, fd->writeable);
+ } else if(fd->type == FD_FILE){
+ idecref(fd->ip);
} else {
panic("fd_close");
}
diff --git a/fd.h b/fd.h
index aa03af9..442ee34 100644
--- a/fd.h
+++ b/fd.h
@@ -1,9 +1,10 @@
struct fd {
- enum { FD_CLOSED, FD_NONE, FD_PIPE } type;
+ enum { FD_CLOSED, FD_NONE, FD_PIPE, FD_FILE } type;
int ref; // reference count
char readable;
char writeable;
struct pipe *pipe;
+ struct inode *ip;
};
extern struct fd fds[NFD];
diff --git a/fs.c b/fs.c
index 3b06bc7..0e987c2 100644
--- a/fs.c
+++ b/fs.c
@@ -12,7 +12,7 @@
// these are inodes currently in use
// an entry is free if count == 0
struct inode inode[NINODE];
-struct spinlock inode_table_lock;
+struct spinlock inode_table_lock = { "inode_table" };
uint rootdev = 1;
@@ -111,11 +111,14 @@ iput(struct inode *ip)
}
void
-iincref(struct inode *ip)
+idecref(struct inode *ip)
{
acquire(&inode_table_lock);
- ip->count += 1;
+ if(ip->count < 1)
+ panic("idecref");
+
+ ip->count -= 1;
release(&inode_table_lock);
}
diff --git a/ide.c b/ide.c
index 88a1d4d..27a76fb 100644
--- a/ide.c
+++ b/ide.c
@@ -25,7 +25,7 @@ struct ide_request {
};
struct ide_request request[NREQUEST];
int head, tail;
-struct spinlock ide_lock;
+struct spinlock ide_lock = { "ide" };
int disk_channel;
diff --git a/kalloc.c b/kalloc.c
index 0b22c91..c13a639 100644
--- a/kalloc.c
+++ b/kalloc.c
@@ -15,7 +15,7 @@
#include "proc.h"
#include "spinlock.h"
-struct spinlock kalloc_lock;
+struct spinlock kalloc_lock = { "kalloc" };
struct run {
struct run *next;
diff --git a/main.c b/main.c
index 1b8bdbe..3db7eab 100644
--- a/main.c
+++ b/main.c
@@ -95,6 +95,8 @@ mpmain(void)
{
cprintf("an application processor\n");
idtinit(); // CPU's idt
+ if(cpu() == 0)
+ panic("mpmain on cpu 0");
lapic_init(cpu());
lapic_timerinit();
lapic_enableintr();
diff --git a/proc.c b/proc.c
index 4e44a8e..b67810e 100644
--- a/proc.c
+++ b/proc.c
@@ -7,7 +7,7 @@
#include "defs.h"
#include "spinlock.h"
-struct spinlock proc_table_lock;
+struct spinlock proc_table_lock = { "proc_table" };
struct proc proc[NPROC];
struct proc *curproc[NCPU];
@@ -137,8 +137,10 @@ scheduler(void)
cprintf("start scheduler on cpu %d jmpbuf %p\n", cpu(), &cpus[cpu()].jmpbuf);
cpus[cpu()].lastproc = &proc[0];
- if(cpus[cpu()].nlock != 0)
+ if(cpus[cpu()].nlock != 0){
+ cprintf("la %x lr %x\n", cpus[cpu()].lastacquire, cpus[cpu()].lastrelease );
panic("holding locks at first entry to scheduler");
+ }
for(;;){
// Loop over process table looking for process to run.
diff --git a/proc.h b/proc.h
index 1b86eb2..a273141 100644
--- a/proc.h
+++ b/proc.h
@@ -70,6 +70,8 @@ struct cpu {
char mpstack[MPSTACK]; // per-cpu start-up stack, only used to get into main()
struct proc *lastproc; // last proc scheduled on this cpu (never NULL)
int nlock; // # of locks currently held
+ struct spinlock *lastacquire; // xxx debug
+ struct spinlock *lastrelease; // xxx debug
};
extern struct cpu cpus[NCPU];
diff --git a/spinlock.c b/spinlock.c
index 171afaf..bde6e46 100644
--- a/spinlock.c
+++ b/spinlock.c
@@ -8,7 +8,7 @@
// Can't call cprintf from inside these routines,
// because cprintf uses them itself.
-#define cprintf dont_use_cprintf
+//#define cprintf dont_use_cprintf
extern int use_console_lock;
@@ -21,8 +21,12 @@ getcallerpc(void *v)
void
acquire(struct spinlock * lock)
{
- if(holding(lock))
+ if(holding(lock)){
+ extern use_console_lock;
+ use_console_lock = 0;
+ cprintf("lock %s pc %x\n", lock->name ? lock->name : "", lock->pc);
panic("acquire");
+ }
if(cpus[cpu()].nlock++ == 0)
cli();
@@ -31,6 +35,7 @@ acquire(struct spinlock * lock)
cpuid(0, 0, 0, 0, 0); // memory barrier
lock->pc = getcallerpc(&lock);
lock->cpu = cpu();
+ cpus[cpu()].lastacquire = lock;
}
void
@@ -39,6 +44,7 @@ release(struct spinlock * lock)
if(!holding(lock))
panic("release");
+ cpus[cpu()].lastrelease = lock;
cpuid(0, 0, 0, 0, 0); // memory barrier
lock->locked = 0;
if(--cpus[cpu()].nlock == 0)
diff --git a/spinlock.h b/spinlock.h
index 0572124..ee48a7e 100644
--- a/spinlock.h
+++ b/spinlock.h
@@ -1,4 +1,5 @@
struct spinlock {
+ char *name;
uint locked;
uint pc;
int cpu;
diff --git a/syscall.c b/syscall.c
index ab9dd17..43be534 100644
--- a/syscall.c
+++ b/syscall.c
@@ -11,6 +11,7 @@
#include "fs.h"
#include "fsvar.h"
#include "elf.h"
+#include "fd.h"
/*
* User code makes a system call with INT T_SYSCALL.
@@ -244,6 +245,41 @@ sys_cons_puts(void)
}
int
+sys_open(void)
+{
+ struct proc *cp = curproc[cpu()];
+ struct inode *ip;
+ uint arg0, arg1;
+ int ufd;
+ struct fd *fd;
+
+ if(fetcharg(0, &arg0) < 0 || fetcharg(1, &arg1) < 0)
+ return -1;
+ if(checkstring(arg0) < 0)
+ return -1;
+ if((ip = namei(cp->mem + arg0)) == 0)
+ return -1;
+ if((fd = fd_alloc()) == 0){
+ iput(ip);
+ return -1;
+ }
+ if((ufd = fd_ualloc()) < 0){
+ iput(ip);
+ fd_close(fd);
+ return -1;
+ }
+
+ iunlock(ip);
+ fd->type = FD_FILE;
+ fd->readable = 1;
+ fd->writeable = 0;
+ fd->ip = ip;
+ cp->fds[ufd] = fd;
+
+ return ufd;
+}
+
+int
sys_exec(void)
{
struct proc *cp = curproc[cpu()];
@@ -467,6 +503,9 @@ syscall(void)
case SYS_exec:
ret = sys_exec();
break;
+ case SYS_open:
+ ret = sys_open();
+ break;
default:
cprintf("unknown sys call %d\n", num);
// XXX fault
diff --git a/syscall.h b/syscall.h
index 799d8ed..e894200 100644
--- a/syscall.h
+++ b/syscall.h
@@ -11,3 +11,4 @@
#define SYS_panic 11
#define SYS_cons_puts 12
#define SYS_exec 13
+#define SYS_open 14
diff --git a/userfs.c b/userfs.c
index d3a4923..c263868 100644
--- a/userfs.c
+++ b/userfs.c
@@ -8,8 +8,24 @@ char *args[] = { "echo", "hello", "goodbye", 0 };
int
main(void)
{
+ int fd;
+
puts("userfs running\n");
block();
+ fd = open("echo", 0);
+ if(fd >= 0){
+ puts("open echo ok\n");
+ close(fd);
+ } else {
+ puts("open echo failed!\n");
+ }
+ fd = open("doesnotexist", 0);
+ if(fd >= 0){
+ puts("open doesnotexist succeeded!\n");
+ close(fd);
+ } else {
+ puts("open doesnotexist failed\n");
+ }
exec("echo", args);
return 0;
}
diff --git a/usys.S b/usys.S
index 09c753e..2c3c855 100644
--- a/usys.S
+++ b/usys.S
@@ -21,3 +21,4 @@ STUB(kill)
STUB(panic)
STUB(cons_puts)
STUB(exec)
+STUB(open)