aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2020-08-22 19:44:49 +0200
committerMarvin Borner2020-08-22 19:44:49 +0200
commit8bb7b5cceaaf96a5dd6321d35aae28748896d87b (patch)
tree9a4103fb1da636fdf0c5ec8f04425c0c388f527d
parent424dc57424ee17de77d689443f95d2e1bed72f4a (diff)
Added *very* basic polling ipc
-rw-r--r--apps/Makefile2
-rw-r--r--apps/init.c3
-rw-r--r--apps/test.c12
-rw-r--r--apps/wm.c18
-rw-r--r--kernel/features/proc.c36
-rw-r--r--kernel/features/syscall.c15
-rw-r--r--kernel/inc/proc.h11
-rw-r--r--libc/inc/sys.h54
-rw-r--r--libc/random.c3
-rw-r--r--libgui/inc/gui.h6
10 files changed, 137 insertions, 23 deletions
diff --git a/apps/Makefile b/apps/Makefile
index 6a6e52c..4c26468 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -1,6 +1,6 @@
# MIT License, Copyright (c) 2020 Marvin Borner
-COBJS = init.o wm.o
+COBJS = init.o wm.o test.o
CC = ../cross/opt/bin/i686-elf-gcc
LD = ../cross/opt/bin/i686-elf-ld
OC = ../cross/opt/bin/i686-elf-objcopy
diff --git a/apps/init.c b/apps/init.c
index ba3e15a..f00110e 100644
--- a/apps/init.c
+++ b/apps/init.c
@@ -10,5 +10,6 @@ int main(int argc, char **argv)
printf("[%s loaded]\n", argv[0]);
int wm = exec("/wm", "wm", argv[1], NULL);
- return wm;
+ int test = exec("/test", "test", NULL);
+ return wm + test;
}
diff --git a/apps/test.c b/apps/test.c
new file mode 100644
index 0000000..8004b34
--- /dev/null
+++ b/apps/test.c
@@ -0,0 +1,12 @@
+#include <def.h>
+#include <gui.h>
+#include <print.h>
+
+int main()
+{
+ print("[test loaded]\n");
+ gui_new_window();
+ while (1) {
+ };
+ return 0;
+}
diff --git a/apps/wm.c b/apps/wm.c
index f3ac901..5896e92 100644
--- a/apps/wm.c
+++ b/apps/wm.c
@@ -34,9 +34,21 @@ int main(int argc, char **argv)
gui_init("/font/spleen-16x32.psfu");
gui_write(vbe, 50, 50, text, "hallo");
- event_map(EVENT_KEYBOARD, onkey);
-
- while (1) {
+ //event_map(EVENT_KEYBOARD, onkey); // TODO: Fix events
+
+ struct message *msg;
+ while (1) { // TODO: Remove continuous polling?
+ if (!(msg = msg_receive()))
+ continue;
+
+ switch (msg->type) {
+ case MSG_NEW_WINDOW:
+ printf("New window for pid %d\n", msg->src);
+ break;
+ default:
+ printf("Unknown WM request!");
+ }
};
+
return 0;
}
diff --git a/kernel/features/proc.c b/kernel/features/proc.c
index b968032..4d4a9f3 100644
--- a/kernel/features/proc.c
+++ b/kernel/features/proc.c
@@ -99,6 +99,30 @@ struct proc *proc_current()
return NULL;
}
+void proc_send(struct proc *src, struct proc *dest, enum message_type type, void *data)
+{
+ assert(src && dest);
+ struct proc_message *msg = malloc(sizeof(*msg));
+ msg->src = src;
+ msg->dest = dest;
+ msg->msg = malloc(sizeof(struct message));
+ msg->msg->src = src->pid;
+ msg->msg->type = type;
+ msg->msg->data = data;
+ list_add(dest->messages, msg);
+}
+
+struct proc_message *proc_receive(struct proc *proc)
+{
+ if (proc->messages && proc->messages->head) {
+ struct proc_message *msg = proc->messages->head->data;
+ list_remove(proc->messages, proc->messages->head);
+ return msg;
+ } else {
+ return NULL;
+ }
+}
+
void proc_resolve(struct proc *proc)
{
proc->state = PROC_RESOLVED;
@@ -107,6 +131,17 @@ void proc_resolve(struct proc *proc)
hlt();
}
+struct proc *proc_from_pid(u32 pid)
+{
+ struct node *iterator = proc_list->head;
+ do {
+ if (((struct proc *)iterator->data)->pid == pid) {
+ return iterator->data;
+ }
+ } while ((iterator = iterator->next) != NULL);
+ return NULL;
+}
+
void proc_exit(struct proc *proc, int status)
{
assert(proc);
@@ -130,6 +165,7 @@ struct proc *proc_make()
struct proc *proc = malloc(sizeof(*proc));
proc->pid = pid++;
proc->events = list_new();
+ proc->messages = list_new();
proc->state = PROC_DEFAULT;
if (current)
diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c
index c8da824..9bd5e9b 100644
--- a/kernel/features/syscall.c
+++ b/kernel/features/syscall.c
@@ -16,7 +16,9 @@ void syscall_handler(struct regs *r)
{
enum sys num = r->eax;
r->eax = 0;
- printf("[SYSCALL] %d: ", num);
+
+ if (num != SYS_RECEIVE)
+ printf("[SYSCALL] %d: ", num);
switch (num) {
case SYS_LOOP: {
@@ -87,6 +89,17 @@ void syscall_handler(struct regs *r)
proc_resolve(proc_current());
break;
}
+ case SYS_SEND: {
+ printf("send\n");
+ proc_send(proc_current(), proc_from_pid(r->ebx), r->ecx, (void *)r->edx);
+ break;
+ }
+ case SYS_RECEIVE: {
+ /* printf("receive\n"); */
+ struct proc_message *msg = proc_receive(proc_current());
+ r->eax = (u32)(msg ? msg->msg : NULL);
+ break;
+ }
default: {
printf("unknown\n");
loop();
diff --git a/kernel/inc/proc.h b/kernel/inc/proc.h
index 48bd7d7..e9d1612 100644
--- a/kernel/inc/proc.h
+++ b/kernel/inc/proc.h
@@ -7,6 +7,7 @@
#include <event.h>
#include <interrupts.h>
#include <list.h>
+#include <sys.h>
#define PROC_QUANTUM 42 // Milliseconds
@@ -25,6 +26,7 @@ struct proc {
struct regs regs_backup;
enum proc_state state;
struct list *events;
+ struct list *messages;
};
struct proc_event {
@@ -32,10 +34,19 @@ struct proc_event {
void *data;
};
+struct proc_message {
+ struct proc *src;
+ struct proc *dest;
+ struct message *msg;
+};
+
void proc_init();
void proc_print();
struct proc *proc_current();
+void proc_send(struct proc *src, struct proc *dest, enum message_type type, void *data);
+struct proc_message *proc_receive(struct proc *proc);
void proc_resolve(struct proc *proc);
+struct proc *proc_from_pid(u32 pid);
void proc_exit(struct proc *proc, int status);
struct proc *proc_make();
diff --git a/libc/inc/sys.h b/libc/inc/sys.h
index bb5dec2..dc6aaf1 100644
--- a/libc/inc/sys.h
+++ b/libc/inc/sys.h
@@ -5,19 +5,28 @@
#define SYS_H
enum sys {
- SYS_LOOP,
- SYS_MALLOC,
- SYS_FREE,
- SYS_READ,
- SYS_WRITE,
- SYS_EXEC,
- SYS_EXIT,
- SYS_TIME,
- SYS_MAP,
- SYS_UNMAP,
- SYS_RESOLVE
+ SYS_LOOP, // To infinity and beyond (debug)!
+ SYS_MALLOC, // Allocate memory
+ SYS_FREE, // Free memory
+ SYS_READ, // Read file
+ SYS_WRITE, // Write to file
+ SYS_EXEC, // Execute path
+ SYS_EXIT, // Exit current process
+ SYS_TIME, // Get kernel time
+ SYS_MAP, // Map event to function
+ SYS_UNMAP, // Unmap event
+ SYS_RESOLVE, // Resolve event (needs to be executed at end of function)
+ SYS_SEND, // Send message to process
+ SYS_RECEIVE // Receive message (non-blocking/sync)
};
enum event { EVENT_KEYBOARD, EVENT_MOUSE };
+enum message_type { MSG_NEW_WINDOW };
+
+struct message {
+ int src;
+ enum message_type type;
+ void *data;
+};
#if defined(userspace)
@@ -34,19 +43,30 @@ int sysv(enum sys num, ...);
*/
#define loop() sys0(SYS_LOOP)
-#define read(path) (void *)sys1(SYS_READ, (int)path)
-#define write(path, buf) sys2(SYS_WRITE, (int)path, buf)
-#define exec(path, ...) sysv(SYS_EXEC, (int)path, ##__VA_ARGS__)
+#define read(path) (void *)sys1(SYS_READ, (int)(path))
+#define write(path, buf) sys2(SYS_WRITE, (int)(path), (buf))
+#define exec(path, ...) (int)sysv(SYS_EXEC, (int)(path), ##__VA_ARGS__)
#define exit(status) \
{ \
sys1(SYS_EXIT, (int)status); \
while (1) { \
} \
}
-#define time() sys0(SYS_TIME)
-#define event_map(id, func) sys2(SYS_MAP, (int)id, (int)func)
-#define event_unmap(id, func) sys2(SYS_UNMAP, (int)id, (int)func)
+#define time() (int)sys0(SYS_TIME)
+
+#define event_map(id, func) sys2(SYS_MAP, (int)(id), (int)(func))
+#define event_unmap(id, func) sys2(SYS_UNMAP, (int)(id), (int)(func))
#define event_resolve() sys0(SYS_RESOLVE) // TODO: Find method making event_resolve obsolete
+#define msg_send(pid, type, msg) sys3(SYS_SEND, (int)(pid), (int)(type), (int)(msg))
+#define msg_receive() (struct message *)sys0(SYS_RECEIVE)
+static inline struct message *msg_receive_loop()
+{
+ struct message *msg;
+ while (!(msg = msg_receive()))
+ ;
+ return msg;
+}
+
#endif
#endif
diff --git a/libc/random.c b/libc/random.c
index 7ad8a67..086fa11 100644
--- a/libc/random.c
+++ b/libc/random.c
@@ -19,6 +19,9 @@ u32 rand()
char *randstr(u32 size)
{
+ if (!size)
+ return NULL;
+
char *buf = malloc(size + 1);
const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
diff --git a/libgui/inc/gui.h b/libgui/inc/gui.h
index c646fab..acef037 100644
--- a/libgui/inc/gui.h
+++ b/libgui/inc/gui.h
@@ -5,6 +5,7 @@
#define GUI_H
#include <def.h>
+#include <sys.h>
#include <vesa.h>
// Generalized font struct
@@ -18,4 +19,9 @@ struct font {
void gui_write(struct vbe *vbe, int x, int y, const u32 c[3], char *text);
void gui_init(char *font_path);
+/**
+ * Wrappers
+ */
+#define gui_new_window() msg_send(1, MSG_NEW_WINDOW, NULL);
+
#endif