summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/include/comus/syscalls.h3
-rw-r--r--kernel/syscall.c22
-rw-r--r--user/forkman.c53
-rw-r--r--user/include/unistd.h19
-rw-r--r--user/lib/syscall.S1
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