Skip to content

Commit

Permalink
file descriptors
Browse files Browse the repository at this point in the history
pipes
  • Loading branch information
rtm committed Jun 27, 2006
1 parent b61c254 commit c41f1de
Show file tree
Hide file tree
Showing 16 changed files with 424 additions and 39 deletions.
18 changes: 13 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
OBJS = main.o console.o string.o kalloc.o proc.o trapasm.o trap.o vectors.o \
syscall.o ide.o picirq.o mp.o spinlock.o
syscall.o ide.o picirq.o mp.o spinlock.o fd.o pipe.o

CC = i386-jos-elf-gcc
LD = i386-jos-elf-ld
Expand All @@ -20,22 +20,30 @@ bootblock : bootasm.S bootmain.c
$(OBJCOPY) -S -O binary bootblock.o bootblock
./sign.pl bootblock

kernel : $(OBJS) bootother.S user1
kernel : $(OBJS) bootother.S user1 usertests
$(CC) -nostdinc -I. -c bootother.S
$(LD) -N -e start -Ttext 0x7000 -o bootother.out bootother.o
$(OBJCOPY) -S -O binary bootother.out bootother
$(OBJDUMP) -S bootother.o > bootother.asm
$(LD) -Ttext 0x100000 -e main -o kernel $(OBJS) -b binary bootother user1
$(LD) -Ttext 0x100000 -e main -o kernel $(OBJS) -b binary bootother user1 usertests
$(OBJDUMP) -S kernel > kernel.asm

vectors.S : vectors.pl
perl vectors.pl > vectors.S

user1 : user1.c
user1 : user1.c ulib.o
$(CC) -nostdinc -I. -c user1.c
$(LD) -N -e main -Ttext 0 -o user1 user1.o
$(LD) -N -e main -Ttext 0 -o user1 user1.o ulib.o
$(OBJDUMP) -S user1 > user1.asm

usertests : usertests.c ulib.o
$(CC) -nostdinc -I. -c usertests.c
$(LD) -N -e main -Ttext 0 -o usertests usertests.o ulib.o
$(OBJDUMP) -S usertests > usertests.asm

ulib.o : ulib.c
$(CC) -nostdinc -I. -c ulib.c

-include *.d

clean :
Expand Down
8 changes: 8 additions & 0 deletions Notes
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,11 @@ it's IRQ 0, but it comes at a weird and changing vector (e.g. 119) if
you don't initialize the PIC. why doesn't jos see this? if i
initialize the PIC with IRQ_OFFSET 32, the interrupt arrives at vector
32.

test out-of-fd cases for creating pipe.
test pipe circular buffer
test pipe writer or reader closes while other active or waiting
test exit vs fd reference counts
test write of more than PIPESIZE
test reader goes first vs writer goes first
test streaming of a lot of data
16 changes: 16 additions & 0 deletions defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ void pic_init(void);
void mp_init(void);
int cpu(void);
int mp_isbcpu(void);
void lapic_init(int c);

// spinlock.c
extern uint32_t kernel_lock;
Expand All @@ -46,3 +47,18 @@ void release_grant_spinlock(uint32_t* lock, int cpu);

// main.c
void load_icode(struct proc *p, uint8_t *binary, unsigned size);

// pipe.c
struct pipe;
struct fd;
int pipe_alloc(struct fd **fd1, struct fd **fd2);
void pipe_close(struct pipe *p, int writeable);
int pipe_write(struct pipe *p, char *addr, int n);
int pipe_read(struct pipe *p, char *addr, int n);

// fd.c
int fd_ualloc();
struct fd * fd_alloc();
void fd_close(struct fd *);
int fd_read(struct fd *fd, char *addr, int n);
int fd_write(struct fd *fd, char *addr, int n);
80 changes: 80 additions & 0 deletions fd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include "types.h"
#include "param.h"
#include "x86.h"
#include "mmu.h"
#include "proc.h"
#include "defs.h"
#include "fd.h"

struct fd fds[NFD];

/*
* allocate a file descriptor number for curproc.
*/
int
fd_ualloc()
{
int fd;
struct proc *p = curproc[cpu()];
for(fd = 0; fd < NOFILE; fd++)
if(p->fds[fd] == 0)
return fd;
return -1;
}

struct fd *
fd_alloc()
{
int i;

for(i = 0; i < NFD; i++){
if(fds[i].type == FD_CLOSED){
fds[i].type = FD_NONE;
fds[i].count = 1;
return fds + i;
}
}
return 0;
}

void
fd_close(struct fd *fd)
{
if(fd->type == FD_CLOSED || fd->count <= 0)
panic("fd_close");
fd->count -= 1;
if(fd->count == 0){
if(fd->type == FD_PIPE)
pipe_close(fd->pipe, fd->writeable);
fd->type = FD_CLOSED;
}
}

/*
* addr is a kernel address, pointing into some process's p->mem.
*/
int
fd_write(struct fd *fd, char *addr, int n)
{
if(fd->writeable == 0)
return -1;
if(fd->type == FD_PIPE){
return pipe_write(fd->pipe, addr, n);
} else {
panic("fd_write");
return -1;
}
}

int
fd_read(struct fd *fd, char *addr, int n)
{
if(fd->readable == 0)
return -1;
if(fd->type == FD_PIPE){
return pipe_read(fd->pipe, addr, n);
} else {
panic("fd_read");
return -1;
}
}
9 changes: 9 additions & 0 deletions fd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
struct fd {
enum { FD_CLOSED, FD_NONE, FD_PIPE } type;
int count; // reference count
char readable;
char writeable;
struct pipe *pipe;
};

extern struct fd fds[NFD];
8 changes: 4 additions & 4 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@

extern char edata[], end[];
extern int acpu;
extern char _binary_user1_start[];
extern char _binary_user1_size[];
extern char _binary_user1_start[], _binary_user1_size[];
extern char _binary_usertests_start[], _binary_usertests_size[];

char buf[512];

Expand All @@ -25,7 +25,7 @@ main()
cprintf("an application processor\n");
release_spinlock(&kernel_lock);
acquire_spinlock(&kernel_lock);
idtinit();
idtinit(); // CPU's idt
lapic_init(cpu());
curproc[cpu()] = &proc[0]; // XXX
swtch();
Expand Down Expand Up @@ -70,7 +70,7 @@ main()

#if 1
p = newproc();
load_icode(p, _binary_user1_start, (unsigned) _binary_user1_size);
load_icode(p, _binary_usertests_start, (unsigned) _binary_usertests_size);
#endif

#if 0
Expand Down
2 changes: 2 additions & 0 deletions param.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
#define PAGE 4096
#define KSTACKSIZE PAGE
#define NCPU 8
#define NOFILE 16 // file descriptors per process
#define NFD 100 // file descriptors per system
100 changes: 100 additions & 0 deletions pipe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#include "types.h"
#include "param.h"
#include "x86.h"
#include "mmu.h"
#include "proc.h"
#include "defs.h"
#include "fd.h"

#define PIPESIZE 512

struct pipe {
int readopen; // read fd is still open
int writeopen; // write fd is still open
int writep; // next index to write
int readp; // next index to read
char data[PIPESIZE];
};

int
pipe_alloc(struct fd **fd1, struct fd **fd2)
{
*fd1 = *fd2 = 0;
struct pipe *p = 0;

if((*fd1 = fd_alloc()) == 0)
goto oops;
if((*fd2 = fd_alloc()) == 0)
goto oops;
if((p = (struct pipe *) kalloc(PAGE)) == 0)
goto oops;
(*fd1)->type = FD_PIPE;
(*fd1)->readable = 1;
(*fd1)->writeable = 0;
(*fd1)->pipe = p;
(*fd2)->type = FD_PIPE;
(*fd2)->readable = 0;
(*fd2)->writeable = 1;
(*fd2)->pipe = p;
return 0;
oops:
if(p)
kfree((char *) p, PAGE);
if(*fd1){
(*fd1)->type = FD_NONE;
fd_close(*fd1);
}
if(*fd2){
(*fd2)->type = FD_NONE;
fd_close(*fd2);
}
return -1;
}

void
pipe_close(struct pipe *p, int writeable)
{
if(writeable)
p->writeopen = 0;
else
p->readopen = 0;
if(p->readopen == 0 && p->writeopen == 0)
kfree((char *) p, PAGE);
}

int
pipe_write(struct pipe *p, char *addr, int n)
{
int i;

for(i = 0; i < n; i++){
while(((p->writep + 1) % PIPESIZE) == p->readp){
if(p->readopen == 0)
return -1;
sleep(&p->writep);
}
p->data[p->writep] = addr[i];
p->writep = (p->writep + 1) % PIPESIZE;
}
return i;
}

int
pipe_read(struct pipe *p, char *addr, int n)
{
int i;

while(p->readp == p->writep){
if(p->writeopen == 0)
return 0;
sleep(&p->readp);
}

for(i = 0; i < n; i++){
if(p->readp == p->writep)
break;
addr[i] = p->data[p->readp];
p->readp = (p->readp + 1) % PIPESIZE;
}
return i;
}
9 changes: 9 additions & 0 deletions proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "mmu.h"
#include "x86.h"
#include "param.h"
#include "fd.h"
#include "proc.h"
#include "defs.h"

Expand Down Expand Up @@ -49,6 +50,7 @@ newproc()
struct proc *np;
struct proc *op = curproc[cpu()];
unsigned *sp;
int fd;

for(np = &proc[1]; np < &proc[NPROC]; np++)
if(np->state == UNUSED)
Expand Down Expand Up @@ -80,6 +82,13 @@ newproc()
np->esp = (unsigned) sp;
np->ebp = (unsigned) sp;

// copy file descriptors
for(fd = 0; fd < NOFILE; fd++){
np->fds[fd] = op->fds[fd];
if(np->fds[fd])
np->fds[fd]->count += 1;
}

np->state = RUNNABLE;

cprintf("newproc %x\n", np);
Expand Down
1 change: 1 addition & 0 deletions proc.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct proc{
int pid;
int ppid;
void *chan; // sleep
struct fd *fds[NOFILE];

struct Taskstate ts; // only to give cpu address of kernel stack
struct Segdesc gdt[NSEGS];
Expand Down
Loading

0 comments on commit c41f1de

Please sign in to comment.