Skip to content

Commit

Permalink
Part 6, Reading and writing
Browse files Browse the repository at this point in the history
  • Loading branch information
singpolyma committed Aug 17, 2012
1 parent 36fadfc commit f874dd2
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 0 deletions.
2 changes: 2 additions & 0 deletions asm.h
@@ -1,3 +1,5 @@
unsigned int *activate(unsigned int *stack);
int fork(void);
int getpid(void);
int write(int fd, const void *buf, size_t count);
int read(int fd, void *buf, size_t count);
70 changes: 70 additions & 0 deletions kernel.c
Expand Up @@ -74,6 +74,70 @@ unsigned int *init_task(unsigned int *stack, void (*start)(void)) {
return stack;
}

void _read(unsigned int *task, unsigned int **tasks, size_t task_count, struct pipe_ringbuffer *pipes);
void _write(unsigned int *task, unsigned int **tasks, size_t task_count, struct pipe_ringbuffer *pipes);

void _read(unsigned int *task, unsigned int **tasks, size_t task_count, struct pipe_ringbuffer *pipes) {
task[-1] = TASK_READY;
/* If the fd is invalid, or trying to read too much */
if(task[2+0] > PIPE_LIMIT || task[2+2] > PIPE_BUF) {
task[2+0] = -1;
} else {
struct pipe_ringbuffer *pipe = &pipes[task[2+0]];
if((size_t)PIPE_LEN(*pipe) < task[2+2]) {
/* Trying to read more than there is: block */
task[-1] = TASK_WAIT_READ;
} else {
size_t i;
char *buf = (char*)task[2+1];
/* Copy data into buf */
for(i = 0; i < task[2+2]; i++) {
PIPE_POP(*pipe,buf[i]);
}

/* Unblock any waiting writes
XXX: nondeterministic unblock order
*/
for(i = 0; i < task_count; i++) {
if(tasks[i][-1] == TASK_WAIT_WRITE) {
_write(tasks[i], tasks, task_count, pipes);
}
}
}
}
}

void _write(unsigned int *task, unsigned int **tasks, size_t task_count, struct pipe_ringbuffer *pipes) {
/* If the fd is invalid or the write would be non-atomic */
if(task[2+0] > PIPE_LIMIT || task[2+2] > PIPE_BUF) {
task[2+0] = -1;
} else {
struct pipe_ringbuffer *pipe = &pipes[task[2+0]];

if((size_t)PIPE_BUF - PIPE_LEN(*pipe) <
task[2+2]) {
/* Trying to write more than we have space for: block */
task[-1] = TASK_WAIT_WRITE;
} else {
size_t i;
const char *buf = (const char*)task[2+1];
/* Copy data into pipe */
for(i = 0; i < task[2+2]; i++) {
PIPE_PUSH(*pipe,buf[i]);
}

/* Unblock any waiting reads
XXX: nondeterministic unblock order
*/
for(i = 0; i < task_count; i++) {
if(tasks[i][-1] == TASK_WAIT_READ) {
_read(tasks[i], tasks, task_count, pipes);
}
}
}
}
}

int main(void) {
unsigned int stacks[TASK_LIMIT][STACK_SIZE];
unsigned int *tasks[TASK_LIMIT];
Expand Down Expand Up @@ -124,6 +188,12 @@ int main(void) {
case 0x2: /* getpid */
tasks[current_task][2+0] = current_task;
break;
case 0x3: /* write */
_write(tasks[current_task], tasks, task_count, pipes);
break;
case 0x4: /* read */
_read(tasks[current_task], tasks, task_count, pipes);
break;
case -4: /* Timer 0 or 1 went off */
if(*(TIMER0 + TIMER_MIS)) { /* Timer0 went off */
*(TIMER0 + TIMER_INTCLR) = 1; /* Clear interrupt */
Expand Down
12 changes: 12 additions & 0 deletions syscalls.s
Expand Up @@ -10,3 +10,15 @@ getpid:
mov r7, #0x2
svc 0
bx lr
.global write
write:
push {r7}
mov r7, #0x3
svc 0
bx lr
.global read
read:
push {r7}
mov r7, #0x4
svc 0
bx lr

0 comments on commit f874dd2

Please sign in to comment.