diff options
-rw-r--r-- | kernel/include/comus/syscalls.h | 3 | ||||
-rw-r--r-- | kernel/syscall.c | 22 | ||||
-rw-r--r-- | user/forkman.c | 53 | ||||
-rw-r--r-- | user/include/unistd.h | 19 | ||||
-rw-r--r-- | user/lib/syscall.S | 1 |
5 files changed, 84 insertions, 14 deletions
diff --git a/kernel/include/comus/syscalls.h b/kernel/include/comus/syscalls.h index f27b879..ffc9d1b 100644 --- a/kernel/include/comus/syscalls.h +++ b/kernel/include/comus/syscalls.h @@ -32,9 +32,10 @@ #define SYS_ticks 19 #define SYS_allocshared 20 #define SYS_popsharedmem 21 +#define SYS_keypoll 22 // UPDATE THIS DEFINITION IF MORE SYSCALLS ARE ADDED! -#define N_SYSCALLS 22 +#define N_SYSCALLS 23 // interrupt vector entry for system calls #define VEC_SYSCALL 0x80 diff --git a/kernel/syscall.c b/kernel/syscall.c index 2b98ec1..d98f886 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -1,6 +1,7 @@ #include <comus/user.h> #include <comus/cpu.h> #include <comus/syscalls.h> +#include <comus/input.h> #include <comus/drivers/acpi.h> #include <comus/drivers/gpu.h> #include <comus/drivers/pit.h> @@ -397,6 +398,26 @@ static int sys_allocshared(void) return 0; } +// NOTE: observes AND consumes the key event +static int sys_keypoll(void) +{ + ARG1(struct keycode *, keyev); + RET(int, waspressed); + + void *ouraddr = kmapuseraddr(pcb->memctx, keyev, sizeof(struct keycode)); + + if (keycode_pop(ouraddr)) { + kunmapaddr(ouraddr); + *waspressed = false; + return 0; + } + + kunmapaddr(ouraddr); + + *waspressed = true; + return 0; +} + static int (*syscall_tbl[N_SYSCALLS])(void) = { [SYS_exit] = sys_exit, [SYS_waitpid] = sys_waitpid, @@ -420,6 +441,7 @@ static int (*syscall_tbl[N_SYSCALLS])(void) = { [SYS_ticks] = sys_ticks, [SYS_allocshared] = sys_allocshared, [SYS_popsharedmem] = sys_popsharedmem, + [SYS_keypoll] = sys_keypoll, }; void syscall_handler(void) diff --git a/user/forkman.c b/user/forkman.c index fb5ae5f..69bff7e 100644 --- a/user/forkman.c +++ b/user/forkman.c @@ -6,10 +6,12 @@ * */ +#include <stdlib.h> +#include <string.h> #include <unistd.h> #include <stdio.h> -#include <string.h> #include <unistd.h> +#include "../kernel/include/comus/keycodes.h" #define GAME_WIDTH 480 #define GAME_HEIGHT 360 @@ -29,11 +31,15 @@ typedef struct { volatile size_t frame; volatile size_t dummy_counter; volatile int lock; + volatile uint8_t client_barrier; + volatile uint8_t server_barrier; + volatile uint8_t key_status[255]; volatile uint8_t mem[PAGE_SIZE * (SHARED_PAGES - 1)]; } sharedmem; static int display_server_entry(sharedmem *); static int client_entry(sharedmem *); +static void barrier_wait(sharedmem *, int isclient); int main(void) { @@ -43,8 +49,6 @@ int main(void) return 1; } - printf("ABOUT TO FORK\n"); - int child = fork(); if (child < 0) { fprintf(stderr, "fork failed!\n"); @@ -52,7 +56,6 @@ int main(void) } if (child) { - printf("FORK GOOD, CHILD IS %d\n", child); sharedmem *shared = allocshared(SHARED_PAGES, child); if (!shared) { fprintf(stderr, "memory share failure\n"); @@ -61,8 +64,6 @@ int main(void) return display_server_entry(shared); } else { - printf("FORK GOOD, WE ARE CHILD\n"); - sharedmem *shared; while (!(shared = popsharedmem())) @@ -90,12 +91,22 @@ static int display_server_entry(sharedmem *shared) size_t last_frame = 1; + barrier_wait(shared, 0); + while (1) { - if (shared->frame == last_frame) { + if (shared->frame == last_frame) continue; - } - printf("server writing frame %zu\n", last_frame); + struct keycode keycode; + + if (keypoll(&keycode)) { + if (keycode.flags & KC_FLAG_KEY_DOWN) { + shared->key_status[(uint8_t)keycode.key] = 1; + } + if (keycode.flags & KC_FLAG_KEY_UP) { + shared->key_status[(uint8_t)keycode.key] = 0; + } + } last_frame += 1; shared->frame = last_frame; @@ -107,15 +118,35 @@ static int display_server_entry(sharedmem *shared) static int client_entry(sharedmem *shared) { size_t last_frame = shared->frame; + barrier_wait(shared, 1); do { if (last_frame == shared->frame) continue; - printf("client writing frame %zu\n", last_frame); - last_frame += 1; shared->frame = last_frame; } while (1); return 0; } + +static void barrier_wait(sharedmem *shared, int isclient) +{ + if (isclient) { + if (shared->server_barrier) { + shared->server_barrier = 0; + } else { + shared->client_barrier = 1; + while (shared->client_barrier) + ; + } + } else { + if (shared->client_barrier) { + shared->client_barrier = 0; + } else { + shared->server_barrier = 1; + while (shared->server_barrier) + ; + } + } +} diff --git a/user/include/unistd.h b/user/include/unistd.h index 27b6d31..e817c84 100644 --- a/user/include/unistd.h +++ b/user/include/unistd.h @@ -14,6 +14,12 @@ /* System Call Definitions */ +// NOTE: needs to match kernel input.h +struct keycode { + char key; + char flags; +}; + typedef unsigned short pid_t; enum { @@ -195,7 +201,7 @@ extern void *sbrk(intptr_t increment); * @return pointer to the virtual address which will be accessible by both, * after popsharedmem() is called. */ -extern void* allocshared(size_t num_pages, int other_pid); +extern void *allocshared(size_t num_pages, int other_pid); /** * Checks if another process has tried to share memory with us, and return it. @@ -207,7 +213,16 @@ extern void* allocshared(size_t num_pages, int other_pid); * process has tried to share with us, or NULL if we the shared virtual address * space is already occupied in the caller's pagetable. */ -extern void* popsharedmem(void); +extern void *popsharedmem(void); + +/** + * Get the most recent key event, if there is one. + * + * @param poll the keycode to write out to + * @return 0 if there was no key event, in which case `poll` was not changed, or + * 1 if there was an event and the caller should read from `poll`. + */ +extern int keypoll(struct keycode *poll); /** * Poweroff the system. diff --git a/user/lib/syscall.S b/user/lib/syscall.S index 9e050bc..93b7daa 100644 --- a/user/lib/syscall.S +++ b/user/lib/syscall.S @@ -29,3 +29,4 @@ SYSCALL drm SYS_drm SYSCALL ticks SYS_ticks SYSCALL allocshared SYS_allocshared SYSCALL popsharedmem SYS_popsharedmem +SYSCALL keypoll SYS_keypoll |