summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/gc/obj.h6
-rw-r--r--src/include/gc/server.h14
-rw-r--r--src/include/gm/call.h18
-rw-r--r--src/include/gm/call/manager.h14
-rw-r--r--src/include/gm/method.h2
-rw-r--r--src/include/gm/method/manager.h20
-rw-r--r--src/include/stdlib.h5
-rw-r--r--src/include/string.h7
-rw-r--r--src/kernel/Makefile2
-rw-r--r--src/kernel/core/kmain.c5
-rw-r--r--src/kernel/core/loader_.asm2
-rw-r--r--src/kernel/ipc/object.c1
-rw-r--r--src/kernel/ipc/object.h1
-rw-r--r--src/kernel/ipc/request.c37
-rw-r--r--src/kernel/ipc/request.h2
-rw-r--r--src/kernel/ipc/shm.c6
-rw-r--r--src/kernel/mem/paging.c2
-rw-r--r--src/kernel/mem/seg.c1
-rw-r--r--src/kernel/task/syscall.c3
-rw-r--r--src/kernel/task/task.c69
-rw-r--r--src/library/Makefile3
-rw-r--r--src/library/gc/server.c25
-rw-r--r--src/library/gc/shm.c4
-rw-r--r--src/library/gm/call.c34
-rw-r--r--src/library/gm/call/manager.c44
-rw-r--r--src/library/std/stdio.c51
-rw-r--r--src/library/std/string.c40
-rw-r--r--src/modules/manager/main.c97
-rw-r--r--src/modules/test/main.c60
29 files changed, 474 insertions, 101 deletions
diff --git a/src/include/gc/obj.h b/src/include/gc/obj.h
index 10651f5..fcb60cd 100644
--- a/src/include/gc/obj.h
+++ b/src/include/gc/obj.h
@@ -5,10 +5,6 @@
#define ME_UNHANDLED -32767
#define ME_INTERRUPTED -32766
-struct object_cli {
- int id;
-};
-
-typedef struct object_cli Object;
+typedef int Object;
#endif
diff --git a/src/include/gc/server.h b/src/include/gc/server.h
index 36597c7..3612a1d 100644
--- a/src/include/gc/server.h
+++ b/src/include/gc/server.h
@@ -16,11 +16,13 @@ struct method_data {
union {
int i;
void* p;
- } val;
+ };
int type;
int keepShm; //for messages : keep shared memory segment after return or unmap ? (default : 0 = unmap)
+ size_t shmsize;
} parameters[3];
uint32_t func;
+ int pid;
int blocking; //1 : blocking request, 0 : message
struct object_srv *obj;
};
@@ -37,11 +39,19 @@ struct method_ret {
//helper function for creating return values
struct method_ret mr_long(int val);
struct method_ret mr_llong(int64_t val);
-struct method_ret mr_obj(Object* obj);
+struct method_ret mr_obj(Object obj);
struct method_ret mr_srv(struct object_srv* obj);
struct method_ret mr_void();
struct method_ret mr_err(int error);
+// for checking if a string passed in shared memory is valid
+#define CHKSSTR(md, n) { size_t _i, _ok = 0; if (md->parameters[n].p == 0) return mr_err(-1); \
+ for (_i = 0; _i < md->parameters[n].shmsize; _i++) { \
+ if (*((char*)md->parameters[n].p + _i) == 0) { \
+ _ok = 1; break; \
+ } } \
+ if (!_ok && md->parameters[n].shmsize != 0) return mr_err(-1); }
+
typedef struct method_ret (*method_handler)(struct method_data*);
struct method_srv {
diff --git a/src/include/gm/call.h b/src/include/gm/call.h
new file mode 100644
index 0000000..5c3849d
--- /dev/null
+++ b/src/include/gm/call.h
@@ -0,0 +1,18 @@
+#ifndef DEF_CALL_H
+#define DEF_CALL_H
+
+/*
+ * This file and all files in include/call/ define prototypes to helper functions for calling methods on objects.
+ */
+
+#include <gc/obj.h>
+
+#define _CHP Object o, int block
+#define _CHC if (block) request(o, &sr); else send_msg(o, &sr);
+
+int c_handleCheck(_CHP, int method);
+int c_handleCheckA(_CHP, int* methods, int number);
+
+int c_nothing(_CHP);
+
+#endif
diff --git a/src/include/gm/call/manager.h b/src/include/gm/call/manager.h
new file mode 100644
index 0000000..49aafe7
--- /dev/null
+++ b/src/include/gm/call/manager.h
@@ -0,0 +1,14 @@
+#ifndef DEF_CALL_MANAGER_H
+#define DEF_CALL_MANAGER_H
+
+#include <gm/call.h>
+#include <gc/obj.h>
+
+Object c_open(_CHP, char *c);
+Object open(char *c); //calls c_open with object 1
+
+void c_registerSvc(char *name); //automatically calls with objecct id 0
+
+void c_logSvc(char *log, int level);
+
+#endif
diff --git a/src/include/gm/method.h b/src/include/gm/method.h
index 6206f07..13d3f16 100644
--- a/src/include/gm/method.h
+++ b/src/include/gm/method.h
@@ -22,4 +22,6 @@
#define M_NOTHING_VVVV (2)
/* This method does nothing, it just checks message transmission to an object. */
+#include "method/manager.h"
+
#endif
diff --git a/src/include/gm/method/manager.h b/src/include/gm/method/manager.h
new file mode 100644
index 0000000..2066093
--- /dev/null
+++ b/src/include/gm/method/manager.h
@@ -0,0 +1,20 @@
+#ifdef DEF_METHOD_H
+
+#define M_OPEN_OMVV (10 | MP(1, 3, 0, 0))
+/* This function opens a distant ressource. Example : open("file:Root/Public/test.txt"); */
+
+#define M_REGISTERSVC_VMOV (11 | MP(0, 3, 1, 0))
+/* This function registers a service.
+ * parameter 1 : service name;
+ * parameter 2 : service root object. */
+
+#define M_LOGSVC_VMIV (12 | MP(0, 3, 2, 0))
+/* This parameters logs an entry for service with corresponding PID. Parameter 2 is : */
+#define LL_CRITICAL 0
+#define LL_ERROR 1
+#define LL_WARNING 2
+#define LL_NOTICE 3
+#define LL_STATUS 4
+#define LL_DEBUG 5
+
+#endif
diff --git a/src/include/stdlib.h b/src/include/stdlib.h
index b232649..3a2b42c 100644
--- a/src/include/stdlib.h
+++ b/src/include/stdlib.h
@@ -1,7 +1,12 @@
#ifndef _DEF_STDLIB_H
#define _DEF_STDLIB_H
+#define NULL 0
+
//includes malloc/free
#include <gc/mem.h>
+void printk_int(int number);
+void printk_hex(unsigned number);
+
#endif
diff --git a/src/include/string.h b/src/include/string.h
index 15ec3f3..24ac216 100644
--- a/src/include/string.h
+++ b/src/include/string.h
@@ -2,10 +2,17 @@
#define _DEF_STRING_H
#include <gc/syscall.h>
+#include <stdlib.h>
void *memcpy(void *dest, const void *src, int count);
uint8_t *memset(uint8_t *dest, uint8_t val, int count);
uint16_t *memsetw(uint16_t *dest, uint16_t val, int count);
+
int strlen(const char *str);
+char *strcpy(char *dest, const char *src);
+char *strdup(const char *src);
+char *strchr(const char *str, char c);
+char *strcat(char *dest, const char *src);
+int strcmp(const char *s1, const char *s2);
#endif
diff --git a/src/kernel/Makefile b/src/kernel/Makefile
index 6d0b7f3..d7a6a57 100644
--- a/src/kernel/Makefile
+++ b/src/kernel/Makefile
@@ -1,7 +1,7 @@
.PHONY: clean, mrproper
CC = gcc
-CFLAGS = -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -fno-stack-protector -Wall -Wextra -I . -I ./lib
+CFLAGS = -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -fno-stack-protector -Wall -Wextra -I . -I ./lib -g
LD = ld
LDFLAGS = -T link.ld
diff --git a/src/kernel/core/kmain.c b/src/kernel/core/kmain.c
index 9fb1397..1577ac7 100644
--- a/src/kernel/core/kmain.c
+++ b/src/kernel/core/kmain.c
@@ -50,10 +50,11 @@ void kmain(struct multiboot_info_t* mbd, int32_t magic) {
if (elf_check((uint8_t*)mods[i].mod_start)) {
monitor_write(" : Invalid ELF file\n");
} else {
- if (elf_exec((uint8_t*)mods[i].mod_start, PL_DRIVER) == 0) {
+ struct process *pr = elf_exec((uint8_t*)mods[i].mod_start, PL_DRIVER);
+ if (pr == 0) {
monitor_write(" : Error loading\n");
} else {
- monitor_write(" : OK\n");
+ monitor_write(" : OK pid:"); monitor_writeDec(pr->pid); monitor_write("\n");
}
}
}
diff --git a/src/kernel/core/loader_.asm b/src/kernel/core/loader_.asm
index d3b92cf..5ee998a 100644
--- a/src/kernel/core/loader_.asm
+++ b/src/kernel/core/loader_.asm
@@ -31,7 +31,7 @@ loader: ;here, we load our false GDT, used for having the kernel in higher half
section .text
higherhalf: ; now we're running in higher half
- mov esp, tasking_tmpStack+0x4000 ; set up the stack
+ mov esp, tasking_tmpStack+0x8000 ; set up the stack
push eax ; pass Multiboot magic number
add ebx, 0xE0000000 ; update the MB info structure so that it is in the new seg
push ebx ; pass Multiboot info structure
diff --git a/src/kernel/ipc/object.c b/src/kernel/ipc/object.c
index e381c89..cfb9652 100644
--- a/src/kernel/ipc/object.c
+++ b/src/kernel/ipc/object.c
@@ -8,6 +8,7 @@ struct object* obj_new(struct process* owner) {
ret->descriptors = 0;
ret->busyMutex = MUTEX_UNLOCKED;
ret->request = 0;
+ ret->wakeupOnRq = 0;
return ret;
}
diff --git a/src/kernel/ipc/object.h b/src/kernel/ipc/object.h
index 9dd3a1e..4577615 100644
--- a/src/kernel/ipc/object.h
+++ b/src/kernel/ipc/object.h
@@ -8,6 +8,7 @@ struct object {
int descriptors;
uint32_t busyMutex; //if busy, either a blocking request is being processed, or a sent message is waiting for being recieved
struct request *request;
+ struct thread *wakeupOnRq;
};
struct obj_descriptor {
diff --git a/src/kernel/ipc/request.c b/src/kernel/ipc/request.c
index 9ca724e..7fe8f2b 100644
--- a/src/kernel/ipc/request.c
+++ b/src/kernel/ipc/request.c
@@ -15,15 +15,19 @@ int request_get(int id, uint32_t ptr, int wait) {
if (obj->request != 0 && obj->request->acknowledged != RS_PENDING) return -3;
//if not (busymutex unlocked and request==0) && wait, then wait, else return -1
if (wait == 0 && obj->request == 0) return -1;
- while (obj->busyMutex != MUTEX_LOCKED && (obj->request == 0 || obj->request->acknowledged != RS_PENDING)) thread_sleep(1);
+ while (obj->busyMutex != MUTEX_LOCKED && (obj->request == 0 || obj->request->acknowledged != RS_PENDING)) {
+ //set thread to be waked up on request
+ obj->wakeupOnRq = current_thread;
+ //go to sleep
+ thread_goInactive();
+ }
obj->request->acknowledged = RS_PROCESSED;
//when request pending (wait finished), write it to ptr
struct user_request *p = (struct user_request*)ptr;
p->func = obj->request->func;
for (i = 0; i < 3; i++) {
p->params[i] = obj->request->params[i];
- if (obj->request->shm_sndr[i] != 0) p->shmsize[i] = obj->request->shm_sndr[i]->len;
- else p->shmsize[i] = 0;
+ p->shmsize[i] = obj->request->shmsize[i];
}
p->isBlocking = (obj->request->requester != 0);
p->pid = obj->request->pid;
@@ -69,15 +73,19 @@ void request_answer(int id, uint32_t answer, uint32_t answer2, int errcode) {
obj->request->acknowledged = RS_FINISHED;
switch (obj->request->func >> 30) {
case PT_OBJDESC:
- if ((int)answer <= 0) {
+ if ((int)answer < 0) {
obj->request->answer.n = answer;
} else {
if (obj->owner == obj->request->requester->process) {
obj->request->answer.n = answer;
} else {
- int n = objdesc_get(obj->request->requester->process, objdesc_read(obj->owner, answer));
- if (n == -1) {
- n = objdesc_add(obj->request->requester->process, objdesc_read(obj->owner, answer));
+ struct object *o = objdesc_read(obj->owner, answer);
+ int n = -1;
+ if (o != 0) {
+ n = objdesc_get(obj->request->requester->process, o);
+ if (n == -1) {
+ n = objdesc_add(obj->request->requester->process, o);
+ }
}
obj->request->answer.n = n;
}
@@ -110,11 +118,12 @@ int request_mapShm(int id, uint32_t pos, int number) {
int n = (obj->request->func >> (28 - (2 * number))) & 3;
if (n != PT_SHM) return -4;
//check if sender process is different from receiver process, if not return -7
- if (obj->owner == obj->request->requester->process) return -7;
+ if (obj->request->requester != 0 && obj->owner == obj->request->requester->process) return -7;
//check if sender sent a shm seg in parameter [number], if not return -5
if (obj->request->shm_sndr[number] == 0) return -5;
//map shm to position
obj->request->shm_rcv[number] = seg_map(obj->request->shm_sndr[number]->seg, obj->owner->pagedir, pos);
+ obj->request->shm_sndr[number]->seg->mappings--;
//if request is nonblocking and no more shm is to be mapped, delete request and free object busymutex
if (obj->request->requester != 0) return 0;
for (i = 0; i < 3; i++) {
@@ -161,7 +170,7 @@ static struct request *mkrequest(int id, struct thread *requester,
uint32_t v = (i == 0 ? a : (i == 1 ? b : c));
switch (n) {
case PT_OBJDESC:
- if ((int)v <= 0) {
+ if ((int)v < 0) {
rq->params[i] = v;
} else {
if (obj->owner == current_thread->process) {
@@ -180,16 +189,25 @@ static struct request *mkrequest(int id, struct thread *requester,
rq->params[i] = v;
break;
case PT_SHM:
+ rq->shmsize[i] = 0;
if (obj->owner == current_thread->process) {
rq->params[i] = v;
+ struct segment_map *t = shmseg_getByOff(current_thread->process, v);
+ if (t != 0) rq->shmsize[i] = t->len;
} else {
rq->shm_sndr[i] = shmseg_getByOff(current_thread->process, v);
+ rq->shm_sndr[i]->seg->mappings++;
+ if (rq->shm_sndr[i] != 0) rq->shmsize[i] = rq->shm_sndr[i]->len;
}
break;
}
}
// reference request from object
obj->request = rq;
+ if (obj->wakeupOnRq != 0) {
+ thread_wakeUp(obj->wakeupOnRq);
+ obj->wakeupOnRq = 0;
+ }
// return request
return rq;
}
@@ -230,5 +248,6 @@ int send_msg(int obj, uint32_t rq_ptr) {
//if returned value is 0, return -1 else return 0
if (e != 0) return e;
if (rq == 0) return -1;
+ urq->errcode = 0;
return 0;
}
diff --git a/src/kernel/ipc/request.h b/src/kernel/ipc/request.h
index 18eaf84..760a159 100644
--- a/src/kernel/ipc/request.h
+++ b/src/kernel/ipc/request.h
@@ -17,7 +17,7 @@
struct request {
struct object *obj;
struct thread *requester; //0 if nonblocking message
- uint32_t func, params[3], obj_close[3]; //obj_close : object descriptors to close when requests yields an answer
+ uint32_t func, params[3], obj_close[3], shmsize[3]; //obj_close : object descriptors to close when requests yields an answer
struct segment_map *shm_sndr[3], *shm_rcv[3];
int acknowledged; // (only for blocking requests) 0 : request is pending, 1 : request is being processes, 2 : finished, 3 : interrupted
union {
diff --git a/src/kernel/ipc/shm.c b/src/kernel/ipc/shm.c
index 1cdacfb..e760a0f 100644
--- a/src/kernel/ipc/shm.c
+++ b/src/kernel/ipc/shm.c
@@ -2,6 +2,7 @@
#include <mem/mem.h>
#include <mem/seg.h>
#include <task/task.h>
+#include <core/sys.h>
struct segment* shmseg_make(size_t len, struct process* owner) {
struct shmseg *ss = kmalloc(sizeof(struct shmseg));
@@ -29,8 +30,9 @@ struct segment_map *shmseg_map(struct segment *seg, struct page_directory *paged
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));
+ for (i = 0; i < sm->len; i += 0x1000) {
+ struct page *page = pagedir_getPage(sm->pagedir, sm->start + i, 0);
+ if (page != 0) page_unmap(page);
}
}
diff --git a/src/kernel/mem/paging.c b/src/kernel/mem/paging.c
index 9972b2a..4992d5e 100644
--- a/src/kernel/mem/paging.c
+++ b/src/kernel/mem/paging.c
@@ -121,7 +121,7 @@ uint32_t paging_fault(struct registers *regs) {
if (regs->err_code & 0x4) monitor_write("user ");
if (regs->err_code & 0x8) monitor_write("rsvd ");
if (regs->err_code & 0x10) monitor_write("instructionfetch ");
- monitor_write("@"); monitor_writeHex(addr); monitor_write("\n");
+ monitor_write("cr2:"); monitor_writeHex(addr); monitor_write("\n");
return 1;
}
return 0;
diff --git a/src/kernel/mem/seg.c b/src/kernel/mem/seg.c
index ffaa84c..e3eca67 100644
--- a/src/kernel/mem/seg.c
+++ b/src/kernel/mem/seg.c
@@ -1,5 +1,6 @@
#include "seg.h"
#include "mem.h"
+#include <core/sys.h>
struct segment_map *seg_map(struct segment* seg, struct page_directory *pagedir, size_t offset) {
struct segment_map *sm = seg->map(seg, pagedir, offset);
diff --git a/src/kernel/task/syscall.c b/src/kernel/task/syscall.c
index 9a1ce81..a5142eb 100644
--- a/src/kernel/task/syscall.c
+++ b/src/kernel/task/syscall.c
@@ -12,6 +12,7 @@
#define CALL1V(name, scname) static void scname(struct registers* r) { name(r->ebx); }
#define CALL2V(name, scname) static void scname(struct registers* r) { name(r->ebx, r->ecx); }
#define CALL3V(name, scname) static void scname(struct registers* r) { name(r->ebx, r->ecx, r->edx); }
+#define CALL4V(name, scname) static void scname(struct registers* r) { name(r->ebx, r->ecx, r->edx, r->esi); }
CALL0V(thread_exit, thread_exit_sc);
CALL0V(tasking_switch, schedule_sc);
@@ -27,7 +28,7 @@ CALL1(object_owned, object_owned_sc);
CALL1V(object_close, object_close_sc);
CALL3(request_get, request_get_sc);
CALL1(request_has, request_has_sc);
-CALL3V(request_answer, request_answer_sc);
+CALL4V(request_answer, request_answer_sc);
CALL3(request_mapShm, request_mapShm_sc);
CALL2(request, request_sc);
CALL2(send_msg, send_msg_sc);
diff --git a/src/kernel/task/task.c b/src/kernel/task/task.c
index f10ec6f..8afc609 100644
--- a/src/kernel/task/task.c
+++ b/src/kernel/task/task.c
@@ -28,7 +28,7 @@ static uint32_t nextpid = 1;
struct process *processes = 0, *kernel_process;
struct thread *threads = 0, *current_thread = 0, *idle_thread;
-uint32_t tasking_tmpStack[0x4000];
+uint32_t tasking_tmpStack[KSTACKSIZE];
void tasking_init() {
cli();
@@ -54,7 +54,9 @@ static struct thread *thread_next() {
if (thread_runnable(ret)) {
return ret;
}
- if (ret == current_thread) return idle_thread;
+ if (ret == current_thread) {
+ return idle_thread;
+ }
}
}
@@ -110,8 +112,17 @@ uint32_t tasking_handleException(struct registers *regs) {
"Coprocessor Segment Overrun","Bad TSS","Segment Not Present","Stack Fault","General Protection Fault",
"Page Fault","Unknown Interrupt","Coprocessor Fault","Alignment Check","Machine Check"};
monitor_write(exception_messages[regs->int_no]);
- monitor_write(" at "); monitor_writeHex(regs->eip);
- PANIC("kk");
+ monitor_write(" eip:"); monitor_writeHex(regs->eip);
+ if (regs->eip >= 0xE0000000) {
+ monitor_write("\n Stack trace :");
+ uint32_t *stack = (uint32_t*)regs->ebp, i;
+ for (i = 0; i < 5 && stack > 0xE0000000 && stack < (regs->useresp + 0x8000); i++) {
+ monitor_write("\nframe@"); monitor_writeHex(stack);
+ monitor_write(" next:"); monitor_writeHex(stack[0]); monitor_write(" ret:"); monitor_writeHex(stack[1]);
+ stack = (uint32_t*)stack[0];
+ }
+ PANIC("Kernel error'd.");
+ }
if (regs->int_no == 14) {
monitor_write("\n>>> Process exiting.\n");
thread_exit_stackJmp(EX_PR_EXCEPTION);
@@ -140,7 +151,7 @@ void thread_wakeUp(struct thread* t) {
}
int proc_priv() {
- if (current_thread == 0) return PL_UNKNOWN;
+ if (current_thread == 0 || current_thread->process == 0) return PL_UNKNOWN;
return current_thread->process->privilege;
}
@@ -151,20 +162,21 @@ void thread_exit2(uint32_t reason) { //See EX_TH_* defines in task.h
* if reason is none of the two cases above, it is the whole process exiting (with error code = reason)
*/
struct thread *th = current_thread;
+ if (th == 0 || th->process == 0) goto retrn;
struct process *pr = th->process;
if ((reason == EX_TH_NORMAL || reason == EX_TH_EXCEPTION) && pr->threads > 1) {
thread_delete(th);
} else {
process_delete(pr);
}
- sti();
+ retrn:
tasking_switch();
}
void thread_exit_stackJmp(uint32_t reason) {
- uint32_t *stack;
cli();
- stack = tasking_tmpStack + 0x4000;
+ uint32_t *stack;
+ stack = tasking_tmpStack + (KSTACKSIZE / 4);
stack--; *stack = reason;
stack--; *stack = 0;
asm volatile(" \
@@ -296,36 +308,49 @@ struct process *process_new(struct process* parent, uint32_t uid, uint32_t privi
}
static void thread_delete(struct thread *th) {
- kfree(th->kernelStack_addr);
- if (th->userStack_seg != 0) seg_unmap(th->userStack_seg);
- th->process->threads--;
if (threads == th) {
threads = th->next;
} else {
struct thread *it = threads;
- while (it->next != th && it->next != 0) it = it->next;
- if (it->next == th) it->next = th->next;
+ while (it) {
+ if (it->next == th) {
+ it->next = th->next;
+ break;
+ }
+ it = it->next;
+ }
}
+ if (current_thread == th) current_thread = 0;
+ th->process->threads--;
+ kfree(th->kernelStack_addr);
+ if (th->userStack_seg != 0) seg_unmap(th->userStack_seg);
kfree(th);
}
static void process_delete(struct process *pr) {
- struct thread *it;
- while (threads != 0 && threads->process == pr) thread_delete(threads);
- it = threads;
- while (it != 0 && it->next != 0) {
- while (it->next != 0 && it->next->process == pr) thread_delete(it->next);
- it = it->next;
+ struct thread *it = threads;
+ while (it != 0) {
+ if (it->process == pr) {
+ thread_delete(it);
+ it = threads;
+ } else {
+ it = it->next;
+ }
}
obj_closeall(pr);
- pagedir_delete(pr->pagedir);
if (processes == pr) {
processes = pr->next;
} else {
struct process *it = processes;
- while (it != 0 && it->next != pr) it = it->next;
- if (it != 0 && it->next == pr) it->next = pr->next;
+ while (it) {
+ if (it->next == pr) {
+ it->next = pr->next;
+ break;
+ }
+ it = it->next;
+ }
}
+ pagedir_delete(pr->pagedir);
kfree(pr);
}
diff --git a/src/library/Makefile b/src/library/Makefile
index 1451c26..3d55354 100644
--- a/src/library/Makefile
+++ b/src/library/Makefile
@@ -8,8 +8,9 @@ LDFLAGS = -r
Library = grapes.o
Objects = gc/syscall.o gc/server.o \
+ gm/call.o gm/call/manager.o \
gc/mem.o gc/shm.o \
- std/mutex.o std/string.o \
+ std/mutex.o std/string.o std/stdio.o \
start.o
all: $(Library)
diff --git a/src/library/gc/server.c b/src/library/gc/server.c
index 9fd1616..96c3180 100644
--- a/src/library/gc/server.c
+++ b/src/library/gc/server.c
@@ -47,25 +47,27 @@ void srv_handle(Server *o, int act) {
md.func = rq.func;
md.blocking = rq.isBlocking;
md.obj = o;
+ md.pid = rq.pid;
//get parameters
for (i = 0; i < 3; i++) {
md.parameters[i].type = (rq.func >> (28 - (2 * i))) & 3;
switch (md.parameters[i].type) {
case PT_LONG:
case PT_OBJDESC:
- md.parameters[i].val.i = rq.params[i];
+ md.parameters[i].i = rq.params[i];
break;
case PT_SHM: //all the fuss about keepShm only applies to messages.
md.parameters[i].keepShm = 1; //if local memory or if nothing, do not unmap it
+ md.parameters[i].shmsize = rq.shmsize[i];
if (rq.params[i] == 0) { //TODO : map shm (shm manager) !!!
void* p = shm_alloc(rq.shmsize[i]);
- md.parameters[i].val.p = p;
+ md.parameters[i].p = p;
if (p != 0) {
request_mapShm(o->id, (size_t)p, i);
md.parameters[i].keepShm = 0; //we had to map it, so mark it to be unmapped
}
} else {
- md.parameters[i].val.p = (void*)rq.params[i];
+ md.parameters[i].p = (void*)rq.params[i];
}
break;
}
@@ -77,10 +79,15 @@ void srv_handle(Server *o, int act) {
if (ret.type == PT_OBJDESC || ret.type == PT_LONG) a = ret.i;
if (ret.type == PT_LONGLONG) a = (uint32_t)ret.l, b = (uint32_t)((uint64_t)ret.l >> 32);
request_answer(o->id, a, b, ret.status);
+ for (i = 0; i < 3; i++) {
+ if (md.parameters[i].type == PT_SHM && md.parameters[i].p != 0) {
+ shm_free(md.parameters[i].p);
+ }
+ }
} else {
for (i = 0; i < 3; i++) {
if (md.parameters[i].type == PT_SHM && md.parameters[i].keepShm == 0) {
- shm_freeDel(md.parameters[i].val.p);
+ shm_freeDel(md.parameters[i].p);
}
}
}
@@ -156,7 +163,7 @@ method_handler getHandler(Server *o, uint32_t m) {
}
struct method_ret checkIfHandles(struct method_data *d) {
- if (getHandler(d->obj, d->parameters[0].val.i) == 0) {
+ if (getHandler(d->obj, d->parameters[0].i) == 0) {
return mr_long(0);
}
return mr_long(1);
@@ -165,9 +172,9 @@ struct method_ret checkIfHandles(struct method_data *d) {
struct method_ret checkIfHandlesMany(struct method_data *d) {
if (d->parameters[0].type != PT_SHM) return mr_err(-1);
if (d->parameters[1].type != PT_LONG) return mr_err(-1);
- uint32_t *data = d->parameters[0].val.p, i;
+ uint32_t *data = d->parameters[0].p, i;
if (data == 0) return mr_long(0);
- for (i = 0; i < d->parameters[1].val.i; i++) {
+ for (i = 0; i < d->parameters[1].i; i++) {
if (getHandler(d->obj, data[i]) == 0) return mr_long(0);
}
return mr_long(1);
@@ -185,8 +192,8 @@ struct method_ret mr_llong(int64_t val) {
return r;
}
-struct method_ret mr_obj(Object* obj) {
- struct method_ret r; r.status = 0; r.type = PT_OBJDESC; r.i = obj->id;
+struct method_ret mr_obj(Object obj) {
+ struct method_ret r; r.status = 0; r.type = PT_OBJDESC; r.i = obj;
return r;
}
diff --git a/src/library/gc/shm.c b/src/library/gc/shm.c
index 8077352..7f8609a 100644
--- a/src/library/gc/shm.c
+++ b/src/library/gc/shm.c
@@ -28,7 +28,7 @@ void* shm_alloc(size_t size) {
//go through all blocks, get the one with the closest size
struct shm_block *i = blocks, *block = 0;
while (i) {
- if (i->size >= size && i->is_hole == 1 && i->size < block->size) block = i;
+ if (i->size >= size && i->is_hole == 1 && (block == 0 || i->size < block->size)) block = i;
i = i->next;
}
if (block == 0) {
@@ -57,7 +57,7 @@ static void unify (struct shm_block *b) {
if (b->next == 0 || b->is_hole == 0 || b->next->is_hole == 0) return;
struct shm_block *n = b->next;
b->size += n->size;
- n->next->prev = b;
+ if (n->next != 0) n->next->prev = b;
b->next = n->next;
free(n);
}
diff --git a/src/library/gm/call.c b/src/library/gm/call.c
new file mode 100644
index 0000000..553fbaf
--- /dev/null
+++ b/src/library/gm/call.c
@@ -0,0 +1,34 @@
+#include <syscall.h>
+#include <gm/call.h>
+#include <gm/method.h>
+#include <gc/shm.h>
+#include <string.h>
+
+int c_handleCheck(_CHP, int method) {
+ struct user_sendrequest sr;
+ sr.func = M_HANDLECHECK_BIVV;
+ sr.a = method;
+ _CHC;
+ if (sr.errcode) return 0;
+ return sr.answeri;
+}
+
+int c_handleCheckA(_CHP, int* methods, int number) {
+ struct user_sendrequest sr;
+ sr.func = M_HANDLECHECK_BMIV;
+ void* ptr = shm_allocNew(sizeof(int) * number);
+ memcpy(ptr, methods, sizeof(int) * number);
+ sr.a = (uint32_t)methods;
+ sr.b = number;
+ _CHC;
+ shm_freeDel(ptr);
+ if (sr.errcode) return 0;
+ return sr.answeri;
+}
+
+int c_nothing(_CHP) {
+ struct user_sendrequest sr;
+ sr.func = M_NOTHING_VVVV;
+ _CHC;
+ return sr.errcode;
+}
diff --git a/src/library/gm/call/manager.c b/src/library/gm/call/manager.c
new file mode 100644
index 0000000..4b296f7
--- /dev/null
+++ b/src/library/gm/call/manager.c
@@ -0,0 +1,44 @@
+#include <syscall.h>
+#include <gm/call/manager.h>
+#include <gm/method.h>
+#include <gc/shm.h>
+#include <string.h>
+
+Object c_open(_CHP, char *c) {
+ struct user_sendrequest sr;
+ sr.func = M_OPEN_OMVV;
+ void* ptr = shm_allocNew(strlen(c) + 1);
+ strcpy(ptr, c);
+ sr.a = (uint32_t)ptr;
+ _CHC;
+ shm_freeDel(ptr);
+ if (sr.errcode) return -1;
+ return sr.answeri;
+}
+
+Object open(char *c) {
+ return c_open(1, 1, c);
+}
+
+void c_registerSvc(char *name) {
+ struct user_sendrequest sr;
+ sr.func = M_REGISTERSVC_VMOV;
+ void* ptr = shm_allocNew(strlen(name) + 1);
+ strcpy(ptr, name);
+ sr.a = (uint32_t)ptr;
+ sr.b = 0;
+ send_msg(1, &sr);
+ shm_freeDel(ptr);
+}
+
+void c_logSvc(char *log, int level) {
+ struct user_sendrequest sr;
+ sr.func = M_LOGSVC_VMIV;
+ void* ptr = shm_allocNew(strlen(log) + 1);
+ if (ptr == 0) return;
+ strcpy(ptr, log);
+ sr.a = (uint32_t)ptr;
+ sr.b = level;
+ request(1, &sr);
+ shm_freeDel(ptr);
+}
diff --git a/src/library/std/stdio.c b/src/library/std/stdio.c
new file mode 100644
index 0000000..3b24da1
--- /dev/null
+++ b/src/library/std/stdio.c
@@ -0,0 +1,51 @@
+#include <stdlib.h>
+
+void printk_int(int number) {
+ if (number == 0) {
+ printk("0");
+ return;
+ }
+ int negative = 0;
+ if (number < 0) {
+ negative = 1;
+ number = 0 - number;
+ }
+ int order = 0, temp = number, i;
+ char numbers[] = "0123456789";
+ while (temp > 0) {
+ order++;
+ temp /= 10;
+ }
+
+ char *s, *r;
+ s = malloc(order + (negative ? 2 : 1));
+ if (negative) {
+ s[0] = '-';
+ r = s + 1;
+ } else {
+ r = s;
+ }
+
+ for (i = order; i > 0; i--) {
+ r[i - 1] = numbers[number % 10];
+ number /= 10;
+ }
+ r[order] = 0;
+ printk(s);
+ free(s);
+}
+
+void printk_hex(unsigned v) {
+ char s[11] = {'0', 'x', 0};
+
+ int i;
+
+ char hexdigits[] = "0123456789ABCDEF";
+
+ for (i = 0; i < 8; i++) {
+ s[i + 2] = (hexdigits[v >> 28]);
+ v = v << 4;
+ }
+ s[11] = 0;
+ printk(s);
+}
diff --git a/src/library/std/string.c b/src/library/std/string.c
index 869256a..4c374ad 100644
--- a/src/library/std/string.c
+++ b/src/library/std/string.c
@@ -6,6 +6,46 @@ int strlen(const char *str) {
return i;
}
+char *strchr(const char *str, char c) {
+ while (*str) {
+ if (*str == c) return (char*)str;
+ str++;
+ }
+ return NULL;
+}
+
+char *strcpy(char *dest, const char *src) {
+ memcpy(dest, src, strlen(src) + 1);
+ return (char*)src;
+}
+
+char *strdup(const char *src) {
+ char* ret = malloc(strlen(src) + 1);
+ if (ret == NULL) return ret;
+ strcpy(ret, src);
+ return ret;
+}
+
+char *strcat(char *dest, const char *src) {
+ char *dest2 = dest;
+ dest2 += strlen(dest) - 1;
+ while (*src) {
+ *dest2 = *src;
+ src++;
+ dest2++;
+ }
+ *dest2 = 0;
+ return dest;
+}
+
+int strcmp(const char *s1, const char *s2) {
+ while ((*s1) && (*s1 == *s2)) {
+ s1++;
+ s2++;
+ }
+ return (* (unsigned char*)s1 - *(unsigned char*)s2);
+}
+
void *memcpy(void *vd, const void *vs, int count) {
uint8_t *dest = (uint8_t*)vd, *src = (uint8_t*)vs;
uint32_t f = count % 4, n = count / 4, i;
diff --git a/src/modules/manager/main.c b/src/modules/manager/main.c
index 9e23097..d211831 100644
--- a/src/modules/manager/main.c
+++ b/src/modules/manager/main.c
@@ -2,20 +2,107 @@
#include <gc/mem.h>
#include <gc/server.h>
#include <gm/method.h>
+#include <gm/call/manager.h>
+#include <string.h>
+char *loglevels[] = {"Critical", "Error", "Warning", "Notice", "Status", "Debug"};
+int loglevel = LL_DEBUG;
+
+struct service {
+ char* name;
+ int pid;
+ Object obj;
+ struct service *next;
+};
+
+struct service *services = 0;
+
+//************************ FUNCTIONS THAT DO STUFF ********************
+void logsvc(int pid, char* log, int level) {
+ if (level > loglevel || level < 0) return;
+ struct service *svc = services;
+ while (svc) {
+ if (svc->pid == pid) break;
+ svc = svc->next;
+ }
+ if (svc == 0) {
+ printk("[log:??] ");
+ } else {
+ printk("[log:"); printk(svc->name); printk("] ");
+ }
+ printk(loglevels[level]); printk(": ");
+ printk(log); printk("\n");
+}
+
+void registersvc(int pid, char* name, Object descriptor) {
+ struct service *svc = malloc(sizeof(struct service));
+ svc->name = strdup(name);
+ svc->pid = pid;
+ svc->obj = descriptor;
+ svc->next = services;
+ services = svc;
+ char msg[100] = "Service registered: ";
+ strcat(msg, svc->name);
+ logsvc(1, msg, LL_NOTICE);
+}
+
+//****************************** HANDLING METHODS ON MAIN OBJECT *****************
struct method_ret handle_nothing(struct method_data *d) {
- if (d->blocking) printk("[manager] Received a {nothing} request.\n");
- else printk("[manager] Received a {nothing} message.\n");
+ if (d->blocking) logsvc(1, "Received a {nothing} request.", LL_DEBUG);
+ else logsvc(1, "Received a {nothing} message.", LL_DEBUG);
+ return mr_void();
+}
+
+struct method_ret handle_open(struct method_data *d) {
+ CHKSSTR(d, 0);
+ char *svc = d->parameters[0].p;
+ printk("open: "); printk(svc); printk("\n");
+ char *sep, *res;
+ sep = strchr(svc, ':');
+ if (sep != 0) *sep = '0';
+ struct service *s = services;
+ while (s) {
+ if (strcmp(s->name, svc) == 0) break;
+ s = s->next;
+ }
+ if (s == 0) return mr_err(-2);
+ if (sep == 0) {
+ return mr_obj(s->obj);
+ } else {
+ *sep = ':';
+ res = sep + 1;
+ // open service svc, ressource res
+ Object r = c_open(s->obj, 1, res);
+ if (r == -1) return mr_err(-3);
+ return mr_obj(r);
+ }
+}
+
+struct method_ret handle_registersvc(struct method_data *d) {
+ CHKSSTR(d, 0);
+ if (d->parameters[1].i == 0) return mr_err(-1);
+ registersvc(d->pid, d->parameters[0].p, d->parameters[1].i);
+ return mr_void();
+}
+
+struct method_ret handle_logsvc(struct method_data *d) {
+ CHKSSTR(d, 0);
+ logsvc(d->pid, d->parameters[0].p, d->parameters[1].i);
return mr_void();
}
int main() {
- printk("[manager] Manager module configuring...\n");
- Server *mgr = srv_get(0);
+ logsvc(1, "Manager module configuring...", LL_NOTICE);
+ registersvc(1, "manager", 0);
+ Server *mgr = srv_get(0);
srv_addHandler(mgr, M_NOTHING_VVVV, handle_nothing);
- printk("[manager] Manager module configured : starting request handling.\n");
+ srv_addHandler(mgr, M_OPEN_OMVV, handle_open);
+ srv_addHandler(mgr, M_REGISTERSVC_VMOV, handle_registersvc);
+ srv_addHandler(mgr, M_LOGSVC_VMIV, handle_logsvc);
+
+ logsvc(1, "Manager module configured : starting request handling.", LL_STATUS);
srv_handle(mgr, HA_LOOP);
printk("[manager] Manager EPIC FAIL.\n");
diff --git a/src/modules/test/main.c b/src/modules/test/main.c
index 148490b..88242e5 100644
--- a/src/modules/test/main.c
+++ b/src/modules/test/main.c
@@ -2,60 +2,46 @@
#include <gc/mem.h>
#include <gc/server.h>
#include <gm/method.h>
+#include <gm/call.h>
+#include <gm/call/manager.h>
+#include <stdlib.h>
#define FACTOR 4
-int obj = -1;
-
struct method_ret nulhandle(struct method_data *d) {
- if (d->blocking) printk("[test:2?] Handling a request.\n");
- else printk("[test:2?] Handling a message.\n");
+ if (d->blocking) c_logSvc("Handling a nothing request.", LL_STATUS);
+ else c_logSvc("Handling a nothing message.", LL_STATUS);
return mr_void();
}
+struct method_ret openhandle(struct method_data *d) {
+ CHKSSTR(d, 0);
+ printk("test.open: "); printk(d->parameters[0].p); printk("\n");
+ return mr_err(-1);
+}
+
void thread2(void* d) {
- printk("[test:2] Creating new object...\n");
- Server *s = srv_create();
+ Server *s = srv_get(0);
srv_addHandler(s, M_NOTHING_VVVV, nulhandle);
- obj = s->id;
+ srv_addHandler(s, M_OPEN_OMVV, openhandle);
while (1) {
- printk("[test:2] Waiting for a request...\n");
+ c_logSvc("{2} Waiting for a request on main object...", LL_STATUS);
srv_handle(s, HA_WAIT);
}
}
int main() {
- int i;
-
- printk("[test:1] Hi world !\n");
- printk("[test:1] Creating new thread...\n");
+ c_logSvc("Hi world from unregistered test module !", LL_NOTICE);
+ c_registerSvc("test");
+ c_logSvc("Creating new thread...", LL_STATUS);
thread_new(thread2, 0);
- while (obj == -1);
- printk("[test:1] Object was created. Sending request...\n");
- struct user_sendrequest sr;
- sr.func = M_NOTHING_VVVV;
- request(obj, &sr);
- printk("[test:1] Got answer. Now sending request to manager...\n");
- request(1, &sr);
- printk("[test:1] And now a message to manager...\n");
- send_msg(1, &sr);
+ c_logSvc("{1} Sending a test message to manager", LL_STATUS);
+ c_nothing(1, 0);
- printk("[test:1] testing malloc and free...");
- int* v = malloc(10 * sizeof(int));
- if (v == 0) printk("zero");
- int* vv = malloc(10 * sizeof(int));
- for (i = 0; i < 10; i++) { v[i] = i * 1243; }
- for (i = 0; i < 10; i++) { vv[i] = i * 2; }
- for (i = 0; i < 10; i++) {
- if (v[i] != i * 1243) printk("FAIL");
- }
- for (i = 0; i < 10; i++) {
- if (vv[i] != i * 2) printk("fail");
- }
- free(v); free(vv);
- printk("nothing bad happened :)\n");
+ Object t = open("test");
+ printk("Open 'test' : "); printk_int(t); printk("\n");
- printk("[test:1] HAHA !!! Death of [test] in 1 seconds!\n");
- thread_sleep(1000);
+ c_logSvc("{1} Thread now sleeping...", LL_WARNING);
+ while (1) thread_sleep(1000);
return 0;
}