Permalink
Browse files

Part 6, Reading and writing

  • Loading branch information...
1 parent 36fadfc commit f874dd26281601430bb08e3bf6853cade40f4ac1 @singpolyma committed Aug 16, 2012
Showing with 84 additions and 0 deletions.
  1. +2 −0 asm.h
  2. +70 −0 kernel.c
  3. +12 −0 syscalls.s
View
@@ -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);
View
@@ -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];
@@ -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 */
View
@@ -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.