summaryrefslogtreecommitdiff
path: root/fd.c
diff options
context:
space:
mode:
authorrtm <rtm>2006-07-12 01:48:35 +0000
committerrtm <rtm>2006-07-12 01:48:35 +0000
commit4e8f237be819424f922399f8d121d9867b675541 (patch)
tree53459cfde9630b3ae0d2d46d0ce3d4c1ac423944 /fd.c
parentb41b38d0da0854f3fa92967b70180ea1156154d4 (diff)
downloadxv6-labs-4e8f237be819424f922399f8d121d9867b675541.tar.gz
xv6-labs-4e8f237be819424f922399f8d121d9867b675541.tar.bz2
xv6-labs-4e8f237be819424f922399f8d121d9867b675541.zip
no more big kernel lock
succeeds at usertests.c pipe test
Diffstat (limited to 'fd.c')
-rw-r--r--fd.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/fd.c b/fd.c
index 8b59605..0f7028f 100644
--- a/fd.c
+++ b/fd.c
@@ -5,6 +5,9 @@
#include "proc.h"
#include "defs.h"
#include "fd.h"
+#include "spinlock.h"
+
+struct spinlock fd_table_lock;
struct fd fds[NFD];
@@ -22,18 +25,24 @@ fd_ualloc()
return -1;
}
+/*
+ * allocate a file descriptor structure
+ */
struct fd *
fd_alloc()
{
int i;
+ acquire(&fd_table_lock);
for(i = 0; i < NFD; i++){
if(fds[i].type == FD_CLOSED){
fds[i].type = FD_NONE;
fds[i].count = 1;
+ release(&fd_table_lock);
return fds + i;
}
}
+ release(&fd_table_lock);
return 0;
}
@@ -69,8 +78,11 @@ fd_read(struct fd *fd, char *addr, int n)
void
fd_close(struct fd *fd)
{
+ acquire(&fd_table_lock);
+
if(fd->count < 1 || fd->type == FD_CLOSED)
panic("fd_close");
+
fd->count -= 1;
if(fd->count == 0){
@@ -79,6 +91,19 @@ fd_close(struct fd *fd)
} else {
panic("fd_close");
}
+ fd->count = 0;
fd->type = FD_CLOSED;
}
+
+ release(&fd_table_lock);
+}
+
+void
+fd_reference(struct fd *fd)
+{
+ acquire(&fd_table_lock);
+ if(fd->count < 1 || fd->type == FD_CLOSED)
+ panic("fd_reference");
+ fd->count += 1;
+ release(&fd_table_lock);
}