From ee348973b0cb0f6481e4fd6e7494c63167c9759c Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Wed, 7 Apr 2010 11:37:21 +0200 Subject: More work on manager --- src/include/gc/obj.h | 6 +-- src/include/gc/server.h | 14 +++++- src/include/gm/call.h | 18 ++++++++ src/include/gm/call/manager.h | 14 ++++++ src/include/gm/method.h | 2 + src/include/gm/method/manager.h | 20 +++++++++ src/include/stdlib.h | 5 +++ src/include/string.h | 7 +++ src/kernel/Makefile | 2 +- src/kernel/core/kmain.c | 5 ++- src/kernel/core/loader_.asm | 2 +- src/kernel/ipc/object.c | 1 + src/kernel/ipc/object.h | 1 + src/kernel/ipc/request.c | 37 ++++++++++++---- src/kernel/ipc/request.h | 2 +- src/kernel/ipc/shm.c | 6 ++- src/kernel/mem/paging.c | 2 +- src/kernel/mem/seg.c | 1 + src/kernel/task/syscall.c | 3 +- src/kernel/task/task.c | 69 +++++++++++++++++++---------- src/library/Makefile | 3 +- src/library/gc/server.c | 25 +++++++---- src/library/gc/shm.c | 4 +- src/library/gm/call.c | 34 +++++++++++++++ src/library/gm/call/manager.c | 44 +++++++++++++++++++ src/library/std/stdio.c | 51 ++++++++++++++++++++++ src/library/std/string.c | 40 +++++++++++++++++ src/modules/manager/main.c | 97 ++++++++++++++++++++++++++++++++++++++--- src/modules/test/main.c | 60 ++++++++++--------------- 29 files changed, 474 insertions(+), 101 deletions(-) create mode 100644 src/include/gm/call.h create mode 100644 src/include/gm/call/manager.h create mode 100644 src/include/gm/method/manager.h create mode 100644 src/library/gm/call.c create mode 100644 src/library/gm/call/manager.c create mode 100644 src/library/std/stdio.c (limited to 'src') 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 + +#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 +#include + +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 +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 +#include 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 #include #include +#include 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 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 +#include +#include +#include +#include + +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 +#include +#include +#include +#include + +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 + +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 #include #include +#include +#include +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 #include #include +#include +#include +#include #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; } -- cgit v1.2.3