summaryrefslogtreecommitdiff
path: root/src/kernel/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/ipc')
-rw-r--r--src/kernel/ipc/object.h26
-rw-r--r--src/kernel/ipc/request.h29
-rw-r--r--src/kernel/ipc/shm.c56
-rw-r--r--src/kernel/ipc/shm.h24
4 files changed, 135 insertions, 0 deletions
diff --git a/src/kernel/ipc/object.h b/src/kernel/ipc/object.h
new file mode 100644
index 0000000..ef90a66
--- /dev/null
+++ b/src/kernel/ipc/object.h
@@ -0,0 +1,26 @@
+#ifndef DEF_OBJECT_H
+#define DEF_OBJECT_H
+
+#include <task/task.h>
+
+#define OS_INACTIVE 0 //No one doing anything on this
+#define OS_LISTENING 1 //A thread is waiting for a request on this object
+#define OS_REQUESTPENDING 2 //A request is waiting for a thread to handle it
+#define OS_BUSY 3 //A thread is currently handling a request
+
+struct object {
+ struct process *owner;
+ int descriptors;
+ uint32_t busyMutex;
+ struct request *request;
+};
+
+struct obj_descriptor {
+ struct object *obj;
+ int id;
+ int owned;
+ struct obj_descriptor *next;
+};
+
+#endif
+
diff --git a/src/kernel/ipc/request.h b/src/kernel/ipc/request.h
new file mode 100644
index 0000000..bf90c68
--- /dev/null
+++ b/src/kernel/ipc/request.h
@@ -0,0 +1,29 @@
+#ifndef DEF_REQUEST_H
+#define DEF_REQUEST_H
+
+#include "object.h"
+
+#define A_STILLRUNNING 0
+#define A_NUMBER 1
+#define A_OBJDESCRIPTOR 2
+#define A_VOID 3
+
+struct request {
+ struct object *obj;
+ struct thread *requester;
+ uint32_t func, param1, param2, param3;
+ struct seg_map *shm_cli, *shm_srv;
+ int answerType;
+ union {
+ int num;
+ struct object* obj;
+ } answer;
+};
+
+struct user_request {
+ uint32_t func, param1, param2, param3;
+ int hasShm;
+};
+
+#endif
+
diff --git a/src/kernel/ipc/shm.c b/src/kernel/ipc/shm.c
new file mode 100644
index 0000000..0a0d3ee
--- /dev/null
+++ b/src/kernel/ipc/shm.c
@@ -0,0 +1,56 @@
+#include "shm.h"
+#include <mem/mem.h>
+#include <mem/seg.h>
+
+struct segment* shmseg_make(size_t len, struct process* owner) {
+ struct shmseg *ss = kmalloc(sizeof(struct shmseg));
+ struct segment *se = kmalloc(sizeof(struct segment));
+ unsigned i;
+ se->seg_data = ss;
+ se->mappings = 0;
+ se->map = shmseg_map;
+ se->unmap = shmseg_unmap;
+ se->delete = shmseg_delete;
+ se->handle_fault = shmseg_handleFault;
+ ss->len = len;
+ ss->owner = owner;
+ ss->frames = kmalloc((len / 0x1000) * sizeof(uint32_t));
+ for (i = 0; i < (len / 0x1000); i++) ss->frames[i] = 0;
+ return se;
+}
+
+struct segment_map *shmseg_map(struct segment *seg, struct page_directory *pagedir, size_t offset) {
+ struct segment_map *sm = kmalloc(sizeof(struct segment_map));
+ sm->start = offset;
+ sm->len = ((struct shmseg*)(seg->seg_data))->len;
+ return sm;
+}
+
+void shmseg_unmap(struct segment_map *sm) {
+ size_t i;
+ for (i = sm->start; i < sm->start + sm->len; i += 0x1000) {
+ page_unmap(pagedir_getPage(sm->pagedir, i, 0));
+ }
+}
+
+int shmseg_handleFault(struct segment_map *sm, size_t addr, int write) {
+ struct shmseg *ss = sm->seg->seg_data;
+ addr &= 0xFFFFF000;
+ struct page *p = pagedir_getPage(sm->pagedir, addr, 1);
+ if (p->frame != 0) return 1;
+ int frame_idx = (addr - sm->start) / 0x1000;
+ if (ss->frames[frame_idx] == 0) {
+ ss->frames[frame_idx] = frame_alloc();
+ }
+ page_map(p, ss->frames[frame_idx], 1, 1);
+ return 0;
+}
+
+void shmseg_delete(struct segment *seg) {
+ struct shmseg *ss = seg->seg_data;
+ unsigned i;
+ for (i = 0; i < (ss->len / 0x1000); i++) {
+ if (ss->frames[i] != 0) frame_free(ss->frames[i]);
+ }
+ kfree(ss->frames);
+}
diff --git a/src/kernel/ipc/shm.h b/src/kernel/ipc/shm.h
new file mode 100644
index 0000000..b409955
--- /dev/null
+++ b/src/kernel/ipc/shm.h
@@ -0,0 +1,24 @@
+#ifndef DEF_SHM_H
+#define DEF_SHM_H
+
+#include <task/task.h>
+
+struct shmseg {
+ size_t len;
+ uint32_t *frames;
+ struct process* owner;
+};
+
+//Shared memory segment stuff
+struct segment* shmseg_make(size_t len, struct process* owner);
+struct segment_map* shmseg_map(struct segment* seg, struct page_directory *pagedir, size_t offset);
+void shmseg_unmap(struct segment_map*);
+void shmseg_delete(struct segment *seg);
+int shmseg_handleFault(struct segment_map *map, size_t addr, int write);
+
+//Shared memory syscalls
+void shm_create(size_t offset, size_t len);
+void shm_delete(size_t offset);
+
+#endif
+