From dbfa8cae66811247e5110e2e17f1c6ae5d1b2bcd Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Wed, 24 Mar 2010 15:40:16 +0100 Subject: IPC not tested but suposedly working. --- doc/objects-requests.txt | 20 ++++- doc/syscalls.txt | 15 ++++ src/include/gc/syscall.h | 29 +++++++ src/kernel/Makefile | 2 +- src/kernel/core/kmain.c | 7 +- src/kernel/ipc/object.c | 10 ++- src/kernel/ipc/request.c | 201 ++++++++++++++++++++++++++++++++++++++++------ src/kernel/ipc/request.h | 35 +++++--- src/kernel/mem/gdt.c | 2 +- src/kernel/mem/mem.c | 2 +- src/kernel/mem/paging.c | 6 +- src/kernel/task/idt.c | 2 +- src/kernel/task/syscall.c | 21 +++++ src/kernel/task/task.c | 7 +- src/kernel/task/task.h | 2 +- src/kernel/task/timer.c | 2 +- src/library/gc/syscall.c | 36 +++++++++ src/modules/test/main.c | 32 ++++++-- 18 files changed, 369 insertions(+), 62 deletions(-) diff --git a/doc/objects-requests.txt b/doc/objects-requests.txt index 9169552..e53c343 100644 --- a/doc/objects-requests.txt +++ b/doc/objects-requests.txt @@ -1,11 +1,25 @@ +The requests can be of two types : +- Blocking, IE the sender waits for an answer +- Nonblocking, the request is a simple message. + Requests are identified by a 32bit function number, composed as follows : (8 bit) parameter and return type ; (24bit) function number the first 8 bits are : - 2bit answer type ; 2bit parameter a ; 2bit parameter b ; 2bit parameter c + 2bit answer type ; 2bit parameter a type ; 2bit parameter b type ; 2bit parameter c type each two bit couple can be one of the following : - 00 : void - 01 : object descriptor number (will be copied with a new number to reciever) -- 10 : integer -- 11 : long long (replies), or shared memory offset (requests and messages) +- 10 : long +- 11 : long long (replies), or shared memory offset in sender's space (requests and messages) + +When shared memory segments are sent as request parameters from a process to the same process, the pointer +to the memory is kept and sent to the handler function. If handler is in another process, receiver will +have to call request_mapShm specifying a pointer. Shared memory is automatically unmapped when requests +yields an answer, and is kept when the request is nonblocking (message). + +When objects are sent as request parameters, the receiver process will get an immediately usable object +descriptor. The descriptor is closed in blocking requests after the request yields an answer (except if the +request is handled in the same process than the sender, OR if the receiver already had a descriptor to +this object). The descriptor is kept when sent by a nonblocking request (message). diff --git a/doc/syscalls.txt b/doc/syscalls.txt index 663618d..2972b97 100644 --- a/doc/syscalls.txt +++ b/doc/syscalls.txt @@ -16,5 +16,20 @@ id=eax Name Parameters Description 8 shm_create ebx: offset Create a shared memory segment at offset (ret = errcode) ecx: length 9 shm_delete ebx: offset Delete a shared memory segment at offset (ret = errcode) + 10 object_create none Creates an object for current process (returns a descriptor to it) + 11 object_owned ebx: object descriptor True (1) if object with this descriptor is ours, false(0) elsewhere + 12 object_close ebx: object descriptor Closes descriptor to an object (deleting it if necessary) + 13 request_get ebx: object descriptor Gets a request pending on object (only if we own it) + ecx: pointer to write request + edx: wait for a request ? + 14 request_has ebx: object descriptor Is there a request waiting on this object ? + 15 request_answer ebx: object descriptor + ecx, edx: answer Answer a request on object + 16 request_mapShm ebx: object descriptor Map shared memory sent with request to receiver's address space + ecx: offset + edx: parameter number (0, 1 or 2) + 17 request ebx: object descriptor Send a blocking request to object + ecx: pointer to user_sendrequest struct with information + 18 send_msg same as above Send a nonblocking request to object, same as above If a processes wishes to exit with an error code, it HAS to use process_exit. thread_exit will do nothing. diff --git a/src/include/gc/syscall.h b/src/include/gc/syscall.h index 4001420..5287d85 100644 --- a/src/include/gc/syscall.h +++ b/src/include/gc/syscall.h @@ -1,8 +1,28 @@ #ifndef DEF_SYSCALL_H #define DEF_SYSCALL_H +typedef unsigned long long uint64_t; +typedef unsigned int uint32_t; +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; +typedef long long int64_t; +typedef int int32_t; +typedef short int16_t; +typedef char int8_t; + typedef unsigned size_t; +struct user_request { + uint32_t func, params[3]; + int isBlocking; // 1 : blocking request, 0 : nonblocking request (message) +}; + +struct user_sendrequest { + uint32_t func, a, b, c; + uint32_t answeri; + int64_t answerll; +}; + void thread_exit(); void schedule(); void thread_sleep(int time); @@ -13,5 +33,14 @@ void irq_wait(int number); int proc_priv(); int shm_create(size_t offset, size_t length); int shm_delete(size_t offset); +int object_create(); +int object_owned(int descriptor); +void object_close(int descriptor); +int request_get(int descriptor, struct user_request *rq, int wait); +int request_has(int descriptor); +void request_answer(int descriptor, int answer1, int answer2); +int request_mapShm(int descriptor, size_t offset, int number); +int request(int descriptor, struct user_sendrequest *rq); +int send_msg(int descriptor, struct user_sendrequest *rq); #endif diff --git a/src/kernel/Makefile b/src/kernel/Makefile index 5de25f8..6d0b7f3 100644 --- a/src/kernel/Makefile +++ b/src/kernel/Makefile @@ -14,7 +14,7 @@ OBJECTS = core/loader_.o core/kmain.o core/sys.o \ task/idt.o task/idt_.o task/task.o task/task_.o task/syscall.o \ lib/stdlib.o lib/bitset.o lib/mutex.o \ mem/mem.o mem/paging.o mem/gdt.o mem/heap.o mem/seg.o \ - ipc/shm.o ipc/object.o \ + ipc/shm.o ipc/object.o ipc/request.o \ linker/elf.o OUT = kernel.elf diff --git a/src/kernel/core/kmain.c b/src/kernel/core/kmain.c index 0a94fde..9fb1397 100644 --- a/src/kernel/core/kmain.c +++ b/src/kernel/core/kmain.c @@ -31,7 +31,7 @@ void kmain(struct multiboot_info_t* mbd, int32_t magic) { PANIC("wrong multiboot magic number."); } - monitor_write("Grapes kernel booting ...\n"); + monitor_write("Grapes 0.0.3 'I am no sweet potato' starting up :\n"); idt_init(); @@ -43,8 +43,9 @@ void kmain(struct multiboot_info_t* mbd, int32_t magic) { timer_init(20); tasking_init(); - monitor_write("Loading modules...\n"); + monitor_write("\nLoading modules :\n"); for (i = 0; i < mbd->mods_count; i++) { + monitor_write(" * "); monitor_write((char*)mods[i].string); if (elf_check((uint8_t*)mods[i].mod_start)) { monitor_write(" : Invalid ELF file\n"); @@ -57,7 +58,7 @@ void kmain(struct multiboot_info_t* mbd, int32_t magic) { } } - monitor_write("Passing control to loaded modules...\n"); + monitor_write("Modules now RULE THE WORLD !\n"); sti(); tasking_switch(); } diff --git a/src/kernel/ipc/object.c b/src/kernel/ipc/object.c index 70c31b2..ea59d28 100644 --- a/src/kernel/ipc/object.c +++ b/src/kernel/ipc/object.c @@ -27,17 +27,19 @@ void obj_closeP(struct process* p, int id) { if (obj == 0) return; objdesc_rm(p, id); if (obj->owner == p) { - if (obj->descriptors > 0) { + if (obj->descriptors > 0) { //TODO !!! obj->owner = 0; // set object to be invalid - //if a request was being handled, give it a null response + //if a request was being handled, set it to interrupted (acknowledged = 3) and wake up receiver thread or if nonblocking delete it + //unlock objects busymutex } else { obj_delete(obj); } } else { if (obj->descriptors == 0 && obj->owner == 0) { obj_delete(obj); + } else if (obj->descriptors == 1 && obj->owner != 0) { + //future : send message becuz object closed for everyone } - //future : send message becuz object was closed } } @@ -48,6 +50,8 @@ void obj_closeall(struct process* p) { // DESCRIPTORS int objdesc_add(struct process* proc, struct object* obj) { + int tmp = objdesc_get(proc, obj); + if (tmp != -1) { return -1; } //signal that a descriptor already exists struct obj_descriptor *ret = kmalloc(sizeof(struct obj_descriptor)); ret->obj = obj; ret->id = proc->next_objdesc; diff --git a/src/kernel/ipc/request.c b/src/kernel/ipc/request.c index 51a0bbc..25c778a 100644 --- a/src/kernel/ipc/request.c +++ b/src/kernel/ipc/request.c @@ -1,55 +1,208 @@ #include "request.h" +#include "shm.h" +#include "object.h" +#include +#include +#include -int request_get(int obj, uint32_t ptr, int wait) { - //check if we own the object, if not return -2 - //check if a request is pending. if request is being processed, return -3 - //if not (busymutex unlocked or request==0) && wait, then wait, else return -1 - //if request pending, write it to ptr - // if request is nonblocking and no shm is to be mapped, delete it and unlock objects busymutex - //return 0 +int request_get(int id, uint32_t ptr, int wait) { + int i; + //check if we own the object, if not return -2 (-10 if descriptor does not exist) + struct object *obj = objdesc_read(current_thread->process, id); + if (obj == 0) return -10; + if (obj->owner != current_thread->process) return -2; + //check if a request is pending. if request is being processed (acknowledged), return -3 + 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) return -1; + while (obj->busyMutex != MUTEX_LOCKED && (obj->request == 0 || obj->request->acknowledged != RS_PENDING)) thread_sleep(1); + 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]; + p->isBlocking = (obj->request->requester != 0); + //if request is nonblocking and no shm is to be mapped, delete request and unlock objects busymutex, else set it to acknowledged + if (p->isBlocking) return 0; + for (i = 0; i < 3; i++) { + if (obj->request->shm_sndr[i] != 0) return 0; + } + kfree(obj->request); + obj->request = 0; + mutex_unlock(&obj->busyMutex); + return 0; } -int request_has(int obj) { - //check if we own the object, if not return -2 +int request_has(int id) { + //check if we own the object, if not return -2 (-10 if descriptor does not exist) + struct object *obj = objdesc_read(current_thread->process, id); + if (obj == 0) return -10; + if (obj->owner != current_thread->process) return -2; //check if a request is pending. - // if being processed, return 2 - // if waiting for ack, return 1 // if none (busymutex unlocked or request==0), return 0 + if (obj->request == 0 || obj->busyMutex == MUTEX_UNLOCKED) return 0; + // if waiting for ack (not acknowledged), return 1 + if (obj->request->acknowledged == RS_PENDING) return 1; + // if being processed (acknowledged), return 2 + return 2; } -void request_answer(int obj, uint32_t answer) { - //check if we own the object, if not return +void request_answer(int id, uint32_t answer, uint32_t answer2) { + int i; + //check if we own the object, if not return (also return if descriptor does not exist) + struct object *obj = objdesc_read(current_thread->process, id); + if (obj == 0) return; + if (obj->owner != current_thread->process) return; //if no blocking request is being processed (including non-acknowledged waiting requests), return - //set blocking request to finished, and set its answer + if (obj->request == 0 || obj->request->acknowledged == RS_PENDING || obj->request->requester == 0) return; + //unmap shared memory segments from shm_rcv, close descriptors to objects from obj_close + for (i = 0; i < 3; i++) { + if (obj->request->shm_rcv[i] != 0) seg_unmap(obj->request->shm_rcv[i]); + if (obj->request->obj_close[i] != 0) obj_closeP(obj->owner, obj->request->obj_close[i]); + } + //set blocking request to finished (acknowledged = 2), and set its answer + obj->request->acknowledged = RS_FINISHED; + switch (obj->request->func >> 30) { + case PT_OBJDESC: + 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)); + } + obj->request->answer.n = n; + } + break; + case PT_LONG: + obj->request->answer.n = answer; + break; + case PT_LONGLONG: + obj->request->answer.ll = (uint64_t)((uint64_t)answer << 32) | answer2; + } + //wake up receiver thread (thread_wakeUp) + thread_wakeUp(obj->request->requester); //dereference request from object, unlock objects busymutex + obj->request = 0; + mutex_unlock(&obj->busyMutex); } -int request_mapShm(int obj, uint32_t pos, int number) { - //check if we own the object, if not return -2 +int request_mapShm(int id, uint32_t pos, int number) { + int i; + if (number > 2 || number < 0) return -9; + //check if we own the object, if not return -2 (-10 if descriptor does not exist) + struct object *obj = objdesc_read(current_thread->process, id); + if (obj == 0) return -10; + if (obj->owner != current_thread->process) return -2; //if no request is being processes (including non-acknowledged waiting requests), return -3 - //check if the requests has shm in parameter [number], if not return -4 + if (obj->request == 0 || obj->request->acknowledged == RS_PENDING || obj->request->requester == 0) return -3; + //check if the requests should have shm in parameter [number], if not return -4 + 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; + //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); //if request is nonblocking and no more shm is to be mapped, delete request and free object busymutex - //return 0 + if (obj->request->requester != 0) return 0; + for (i = 0; i < 3; i++) { + if (obj->request->shm_sndr[i] != 0 && obj->request->shm_rcv[i] == 0) return 0; + } + kfree(obj->request); + obj->request = 0; + mutex_unlock(&obj->busyMutex); + return 0; } -static struct request *mkrequest(int obj, struct thread *requester, +static struct request *mkrequest(int id, struct thread *requester, uint32_t func, uint32_t a, uint32_t b, uint32_t c) { + int i; // get object from descriptor id, if none return 0 + struct object *obj = objdesc_read(current_thread->process, id); + if (obj == 0) return 0; // waitlock object's busy mutex + mutex_lock(&obj->busyMutex); // if object cannot answer (owner == 0) return 0 - // create request, fill it up, reference it from object + if (obj->owner == 0) { + mutex_unlock(&obj->busyMutex); + return 0; + } + // create request, fill it up : + struct request *rq = kmalloc(sizeof(struct request)); + rq->obj = obj; + rq->requester = requester; + rq->func = func; + for (i = 0; i < 3; i++) { rq->params[i] = 0; rq->obj_close[i] = 0; rq->shm_sndr[i] = 0; rq->shm_rcv[i] = 0; } + rq->acknowledged = RS_PENDING; + // integers: use as is + // objects: open a new descriptor in receiver process (if same process, keep number), put that number as an int + // if receiver already had descriptor to this object, use it and set obj_close to 0, else set obj_close to new number + // shm: if same process, put ptr as int, else put 0 as int and get segment_map to shm_sndr + // objects and shm: 0 means sender didn't want to share anything, that should stay 0. + for (i = 0; i < 3; i++) { + int n = (rq->func >> (28 - (2 * i))) & 3; + uint32_t v = (i == 0 ? a : (i == 1 ? b : c)); + switch (n) { + case PT_OBJDESC: + if (obj->owner == current_thread->process) { + rq->params[i] = v; + } else { + int d = objdesc_get(obj->owner, objdesc_read(current_thread->process, v)); + if (d == -1) { + d = objdesc_add(obj->owner, objdesc_read(current_thread->process, v)); + rq->obj_close[i] = d; + } + rq->params[i] = d; + } + break; + case PT_LONG: + rq->params[i] = v; + break; + case PT_SHM: + if (obj->owner == current_thread->process) { + rq->params[i] = v; + } else { + rq->shm_sndr[i] = shmseg_getByOff(current_thread->process, v); + } + break; + } + } + // reference request from object + obj->request = rq; // return request + return rq; } -int request(int obj, uint32_t func, uint32_t a, uint32_t b, uint32_t c, uint32_t answerptr) { +int request(int obj, uint32_t rq_ptr) { + struct user_sendrequest *urq = (void*)rq_ptr; //call mkrequest with parameters (requester thread = current thread) - //if returned value is 0, return -1 + struct request *rq = mkrequest(obj, current_thread, urq->func, urq->a, urq->b, urq->c); + //if returned value is 0 (could not create request), return -1 + if (rq == 0) return -1; //sleep until request is handled - //write answer to *answerptr, delete request, return 0 + thread_goInactive(); + //if request has been interrupted because process closed communication (acknowledged == 3), return -2 + if (rq->acknowledged == 3) return -2; + //write answer to urq, delete request, return 0 + switch (urq->func >> 30) { + case PT_OBJDESC: + case PT_LONG: + urq->answeri = rq->answer.n; + break; + case PT_LONGLONG: + urq->answerll = rq->answer.ll; + } + kfree(rq); + return 0; } -int send_msg(int obj, uint32_t func, uint32_t a, uint32_t b, uint32_t c) { +int send_msg(int obj, uint32_t rq_ptr) { + struct user_sendrequest *urq = (void*)rq_ptr; //call mkrequest with parameters (requester thread = 0) + struct request *rq = mkrequest(obj, 0, urq->func, urq->a, urq->b, urq->c); //if returned value is 0, return -1 else return 0 + if (rq == 0) return -1; + return 0; } diff --git a/src/kernel/ipc/request.h b/src/kernel/ipc/request.h index 4a35dc3..0b60a5c 100644 --- a/src/kernel/ipc/request.h +++ b/src/kernel/ipc/request.h @@ -3,16 +3,23 @@ #include "object.h" -#define A_STILLRUNNING 0 -#define A_NUMBER 1 -#define A_OBJDESCRIPTOR 2 -#define A_VOID 3 +#define RS_PENDING 0 +#define RS_PROCESSED 1 +#define RS_FINISHED 2 +#define RS_INTERRUPTED 3 + +#define PT_VOID 0 +#define PT_OBJDESC 1 +#define PT_LONG 2 +#define PT_LONGLONG 3 //for return values +#define PT_SHM 3 //for parameters struct request { struct object *obj; struct thread *requester; //0 if nonblocking message - uint32_t func, params[3]; - struct seg_map *shm_srv[3], *shm_cli[3]; + uint32_t func, params[3], obj_close[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 { int64_t ll; uint32_t n; @@ -20,18 +27,24 @@ struct request { }; struct user_request { - uint32_t func, param1, param2, param3; - int hasShm; + uint32_t func, params[3]; + int isBlocking; // 1 : blocking request, 0 : nonblocking request (message) +}; + +struct user_sendrequest { + uint32_t func, a, b, c; + uint32_t answeri; + int64_t answerll; }; //syscalls int request_get(int obj, uint32_t ptr, int wait); int request_has(int obj); -void request_answer(int obj, uint32_t answer); +void request_answer(int obj, uint32_t answer, uint32_t answer2); //answer2 used for long long. int request_mapShm(int obj, uint32_t pos, int number); -int request(int obj, uint32_t func, uint32_t a, uint32_t b, uint32_t c, uint32_t answerptr); -int send_msg(int obj, uint32_t func, uint32_t a, uint32_t b, uint32_t c); +int request(int obj, uint32_t rq_ptr); +int send_msg(int obj, uint32_t rq_ptr); #endif diff --git a/src/kernel/mem/gdt.c b/src/kernel/mem/gdt.c index 18a5fa7..e9a1be5 100644 --- a/src/kernel/mem/gdt.c +++ b/src/kernel/mem/gdt.c @@ -54,5 +54,5 @@ void gdt_init() { gdt_flush((uint32_t)&gdt_ptr); tss_flush(); - monitor_write("GDT ok\n"); + monitor_write("[GDT] "); } diff --git a/src/kernel/mem/mem.c b/src/kernel/mem/mem.c index 2f7e1c8..06242a5 100644 --- a/src/kernel/mem/mem.c +++ b/src/kernel/mem/mem.c @@ -75,7 +75,7 @@ static struct heap kheap; void kheap_init() { heap_create(&kheap, (mem_placementAddr & 0xFFFFF000) + 0x1000, KHEAP_IDXSIZE, KHEAP_INITSIZE, KHEAP_MAXSIZE); kheap_working = 1; - monitor_write("Kernel heap ok\n"); + monitor_write("[KHeap] "); } void* kmalloc(size_t size) { diff --git a/src/kernel/mem/paging.c b/src/kernel/mem/paging.c index d478e05..8996162 100644 --- a/src/kernel/mem/paging.c +++ b/src/kernel/mem/paging.c @@ -45,10 +45,10 @@ void paging_init(size_t totalRam) { kernel_pagedir->tables[i] = kernel_pagedir->tables[i + 896]; } - monitor_write("Page dir is at: "); + monitor_write("{PD: "); monitor_writeHex(kernel_pagedir->physicalAddr); pagedir_switch(kernel_pagedir); - monitor_write("\nPaging started\n"); + monitor_write("} [Paging] "); } void paging_cleanup() { @@ -57,7 +57,7 @@ void paging_cleanup() { kernel_pagedir->tablesPhysical[i] = 0; kernel_pagedir->tables[i] = 0; } - monitor_write("Pages cleaned up\n"); + monitor_write("[PD Cleanup] "); } void pagedir_switch(struct page_directory *pd) { diff --git a/src/kernel/task/idt.c b/src/kernel/task/idt.c index 0f3c2f2..80f13db 100644 --- a/src/kernel/task/idt.c +++ b/src/kernel/task/idt.c @@ -186,7 +186,7 @@ void idt_init() { idt_flush((int32_t)&idt_ptr); - monitor_write("IDT ok\n"); + monitor_write("[IDT] "); } void idt_handleIrq(int number, int_callback func) { diff --git a/src/kernel/task/syscall.c b/src/kernel/task/syscall.c index 51c46f1..dd909e0 100644 --- a/src/kernel/task/syscall.c +++ b/src/kernel/task/syscall.c @@ -6,9 +6,12 @@ r->eax = name(r->ebx); } #define CALL2(name, scname) static void scname(struct registers* r) { \ r->eax = name(r->ebx, r->ecx); } +#define CALL3(name, scname) static void scname(struct registers* r) { \ + r->eax = name(r->ebx, r->ecx, r->edx); } #define CALL0V(name, scname) static void scname(struct registers* r) { name(); } #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); } CALL0V(thread_exit, thread_exit_sc); CALL0V(tasking_switch, schedule_sc); @@ -19,6 +22,15 @@ CALL1V(idt_waitIrq, irq_wait_sc); CALL0(proc_priv, proc_priv_sc); CALL2(shm_create, shm_create_sc); CALL1(shm_delete, shm_delete_sc); +CALL0(object_create, object_create_sc); +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); +CALL3(request_mapShm, request_mapShm_sc); +CALL2(request, request_sc); +CALL2(send_msg, send_msg_sc); static void thread_new_sc(struct registers* r) { thread_new(current_thread->process, (thread_entry)r->ebx, (void*)r->ecx); @@ -35,4 +47,13 @@ int_callback syscalls[] = { proc_priv_sc, shm_create_sc, shm_delete_sc, + object_create_sc, //10 + object_owned_sc, + object_close_sc, + request_get_sc, + request_has_sc, + request_answer_sc, //15 + request_mapShm_sc, + request_sc, + send_msg_sc, 0 }; diff --git a/src/kernel/task/task.c b/src/kernel/task/task.c index 6959676..dec7565 100644 --- a/src/kernel/task/task.c +++ b/src/kernel/task/task.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "timer.h" #define KSTACKSIZE 0x8000 @@ -39,7 +40,7 @@ void tasking_init() { idle_thread = thread_new(kernel_process, task_idle, 0); threads = 0; //Do not include idle thread in threads sti(); - monitor_write("Tasking set up\n"); + monitor_write("[Tasking] "); } static struct thread *thread_next() { @@ -130,6 +131,10 @@ void thread_goInactive() { tasking_switch(); } +void thread_wakeUp(struct thread* t) { + if (t->state == TS_WAKEWAIT) t->state = TS_RUNNING; +} + int proc_priv() { if (current_thread == 0) return PL_UNKNOWN; return current_thread->process->privilege; diff --git a/src/kernel/task/task.h b/src/kernel/task/task.h index b2a5434..1c22785 100644 --- a/src/kernel/task/task.h +++ b/src/kernel/task/task.h @@ -3,7 +3,6 @@ #include #include -#include #include "idt.h" #define TS_RUNNING 0 @@ -57,6 +56,7 @@ uint32_t tasking_handleException(struct registers *regs); void thread_sleep(uint32_t msecs); void thread_goInactive(); //Blocks the current thread. another one must be there to wake it up at some point. +void thread_wakeUp(struct thread *t); int proc_priv(); //Returns current privilege level void thread_exit(); void process_exit(uint32_t retval); diff --git a/src/kernel/task/timer.c b/src/kernel/task/timer.c index 8c1a2b8..e924657 100644 --- a/src/kernel/task/timer.c +++ b/src/kernel/task/timer.c @@ -32,5 +32,5 @@ void timer_init(uint32_t freq) { outb(0x40, l); outb(0x40, h); - monitor_write("Timer started\n"); + monitor_write("[PIT] "); } diff --git a/src/library/gc/syscall.c b/src/library/gc/syscall.c index e1ef3cd..8fd1554 100644 --- a/src/library/gc/syscall.c +++ b/src/library/gc/syscall.c @@ -45,3 +45,39 @@ int shm_create(size_t offset, size_t length) { int shm_delete(size_t offset) { return call(9, offset, 0, 0, 0, 0); } + +int object_create() { + return call(10, 0, 0, 0, 0, 0); +} + +int object_owned(int descriptor) { + return call(11, descriptor, 0, 0, 0, 0); +} + +void object_close(int descriptor) { + call(12, descriptor, 0, 0, 0, 0); +} + +int request_get(int descriptor, struct user_request *rq, int wait) { + return call(13, descriptor, (size_t)rq, wait, 0, 0); +} + +int request_has(int descriptor) { + return call(14, descriptor, 0, 0, 0, 0); +} + +void request_answer(int descriptor, int answer1, int answer2) { + call(15, descriptor, answer1, answer2, 0, 0); +} + +int request_mapShm(int descriptor, size_t offset, int number) { + return call(16, descriptor, offset, number, 0, 0); +} + +int request(int descriptor, struct user_sendrequest *rq) { + return call(17, descriptor, (size_t)rq, 0, 0, 0); +} + +int send_msg(int descriptor, struct user_sendrequest *rq) { + return call(18, descriptor, (size_t)rq, 0, 0, 0); +} diff --git a/src/modules/test/main.c b/src/modules/test/main.c index 9e03ee8..d2a4692 100644 --- a/src/modules/test/main.c +++ b/src/modules/test/main.c @@ -2,20 +2,36 @@ #define FACTOR 4 +int obj = -1; + void thread2(void* d) { + printk("[module:test:2] Creating new object...\n"); + obj = object_create(); + struct user_request rq; while (1) { - printk("$"); - thread_sleep(35*FACTOR); + printk("[module:test:2] Waiting for a request...\n"); + request_get(obj, &rq, 1); + if (rq.isBlocking) { + printk("[module:test:2] Got request. Answering...\n"); + request_answer(obj, 42, 0); + } else { + printk("[module:test:2] Got message. Ignoring it.\n"); + } } } int main() { - printk("[module:test] Hi world !\n"); - printk("[module:test] Creating new thread...\n"); + printk("[module:test:1] Hi world !\n"); + printk("[module:test:1] Creating new thread...\n"); thread_new(thread2, 0); - while (1) { - printk("."); - thread_sleep(50*FACTOR); - } + while (obj == -1); + printk("[module:test:1] Object was created. Sending request...\n"); + struct user_sendrequest sr; + sr.func = 0x80000001; + request(obj, &sr); + printk("[module:test:1] Got answer. Sending message...\n"); + send_msg(obj, &sr); + printk("[module:test:1] HAHA !!! Death in 10 seconds!\n"); + thread_sleep(10000); return 0; } -- cgit v1.2.3