diff options
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/Makefile | 2 | ||||
-rw-r--r-- | src/kernel/ipc/object.c | 118 | ||||
-rw-r--r-- | src/kernel/ipc/object.h | 40 | ||||
-rw-r--r-- | src/kernel/ipc/request.c | 253 | ||||
-rw-r--r-- | src/kernel/ipc/request.h | 54 | ||||
-rw-r--r-- | src/kernel/task/syscall.c | 24 | ||||
-rw-r--r-- | src/kernel/task/task.c | 11 | ||||
-rw-r--r-- | src/kernel/task/task.h | 3 |
8 files changed, 4 insertions, 501 deletions
diff --git a/src/kernel/Makefile b/src/kernel/Makefile index 757349f..5d46325 100644 --- a/src/kernel/Makefile +++ b/src/kernel/Makefile @@ -4,7 +4,7 @@ Obj = core/loader_.o core/kmain.o core/sys.o core/test.o \ task/idt.o task/idt_.o task/task.o task/task_.o task/syscall.o task/sched.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/request.o \ + ipc/shm.o \ linker/elf.o include ../common.make diff --git a/src/kernel/ipc/object.c b/src/kernel/ipc/object.c deleted file mode 100644 index cfb9652..0000000 --- a/src/kernel/ipc/object.c +++ /dev/null @@ -1,118 +0,0 @@ -#include "object.h" -#include <lib/mutex.h> -#include <mem/mem.h> - -struct object* obj_new(struct process* owner) { - struct object* ret = kmalloc(sizeof(struct object)); - ret->owner = owner; - ret->descriptors = 0; - ret->busyMutex = MUTEX_UNLOCKED; - ret->request = 0; - ret->wakeupOnRq = 0; - return ret; -} - -void obj_delete(struct object* obj) { - if (obj->descriptors > 0) return; - if (obj->busyMutex != MUTEX_UNLOCKED) return; - if (obj->request != 0) return; - kfree(obj); -} - -int obj_createP(struct process* p) { - return objdesc_add(p, obj_new(p)); -} - -void obj_closeP(struct process* p, int id) { - struct object* obj = objdesc_read(p, id); - if (obj == 0) return; - objdesc_rm(p, id); - if (obj->owner == p) { - if (obj->descriptors > 0) { //TODO !!! - obj->owner = 0; // set object to be invalid - //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 - } - } -} - -void obj_closeall(struct process* p) { - while (p->objects != 0) obj_closeP(p, p->objects->id); -} - -// 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; - ret->next = proc->objects; - proc->objects = ret; - obj->descriptors++; - proc->next_objdesc++; - return ret->id; -} - -int objdesc_get(struct process* proc, struct object* obj) { - struct obj_descriptor *it = proc->objects; - while (it != 0) { - if (it->obj == obj) return it->id; - it = it->next; - } - return -1; -} - -struct object* objdesc_read(struct process* proc, int id) { - struct obj_descriptor *it = proc->objects; - while (it != 0) { - if (it->id == id) return it->obj; - it = it->next; - } - return 0; -} - -void objdesc_rm(struct process* proc, int id) { - struct obj_descriptor *e = proc->objects; - if (e != 0 && e->id == id) { - proc->objects = e->next; - e->obj->descriptors--; - kfree(e); - return; - } - while (e->next != 0) { - if (e->next->id == id) { - e->next = e->next->next; - e->next->obj->descriptors--; - kfree(e->next); - return; - } - e = e->next; - } -} - -// SYSCALLS - -int object_create() { - return obj_createP(current_thread->process); -} - -int object_owned(int id) { - struct object *obj = objdesc_read(current_thread->process, id); - if (obj == 0) return -10; - if (obj->owner == current_thread->process) return 1; - return 0; -} - -void object_close(int id) { - obj_closeP(current_thread->process, id); -} diff --git a/src/kernel/ipc/object.h b/src/kernel/ipc/object.h deleted file mode 100644 index 4577615..0000000 --- a/src/kernel/ipc/object.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef DEF_OBJECT_H -#define DEF_OBJECT_H - -#include <task/task.h> - -struct object { - struct process *owner; //when 0, object is invalid and cannot handle requests - 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 { - struct object *obj; - int id; - struct obj_descriptor *next; -}; - -//Objects -struct object* obj_new(struct process *owner); -void obj_delete(struct object* obj); - -int obj_createP(struct process* p); -void obj_closeP(struct process* p, int id); -void obj_closeall(struct process* p); - -//Object descriptors -int objdesc_add(struct process* proc, struct object* obj); // add a descriptor -int objdesc_get(struct process* proc, struct object* obj); // look in descriptors for the one corresponding to the object -struct object* objdesc_read(struct process* proc, int id); // get the object correspoinding to the id -void objdesc_rm(struct process* proc, int id); // remove descriptor for an object - -//Syscalls -int object_create(); -int object_owned(int id); //does current process own object ? 1=yes 0=no -void object_close(int id); //closes descriptor to specified object. if we are the owner, make all requests to object fail. - -#endif - diff --git a/src/kernel/ipc/request.c b/src/kernel/ipc/request.c deleted file mode 100644 index 7fe8f2b..0000000 --- a/src/kernel/ipc/request.c +++ /dev/null @@ -1,253 +0,0 @@ -#include "request.h" -#include "shm.h" -#include "object.h" -#include <lib/mutex.h> -#include <mem/seg.h> -#include <mem/mem.h> - -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 && obj->request == 0) return -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]; - p->shmsize[i] = obj->request->shmsize[i]; - } - p->isBlocking = (obj->request->requester != 0); - p->pid = obj->request->pid; - //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 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 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 id, uint32_t answer, uint32_t answer2, int errcode) { - 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 - 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 ((int)answer < 0) { - obj->request->answer.n = answer; - } else { - if (obj->owner == obj->request->requester->process) { - obj->request->answer.n = answer; - } else { - 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; - } - } - break; - case PT_LONG: - obj->request->answer.n = answer; - break; - case PT_LONGLONG: - obj->request->answer.ll = (uint64_t)((uint64_t)answer2 << 32) | answer; - } - obj->request->errcode = errcode; - //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 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 - if (obj->request == 0 || obj->request->acknowledged == RS_PENDING) 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->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++) { - 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 id, struct thread *requester, - uint32_t func, uint32_t a, uint32_t b, uint32_t c, uint32_t *err) { - int i; - // get object from descriptor id, if none return 0 - struct object *obj = objdesc_read(current_thread->process, id); - if (obj == 0) { - *err = -10; - return 0; - } - // waitlock object's busy mutex - mutex_lock(&obj->busyMutex); - // if object cannot answer (owner == 0) return 0 - if (obj->owner == 0) { - mutex_unlock(&obj->busyMutex); - *err = -11; - 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; - rq->pid = current_thread->process->pid; - // 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 ((int)v < 0) { - rq->params[i] = v; - } else { - 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: - 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; -} - -int request(int obj, uint32_t rq_ptr) { - uint32_t e = 0; - - struct user_sendrequest *urq = (void*)rq_ptr; - //call mkrequest with parameters (requester thread = current thread) - struct request *rq = mkrequest(obj, current_thread, urq->func, urq->a, urq->b, urq->c, &e); - //if returned value is 0 (could not create request), return -1 - if (e != 0) return e; - if (rq == 0) return -1; - //sleep until request is handled - 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; - } - urq->errcode = rq->errcode; - kfree(rq); - return 0; -} - -int send_msg(int obj, uint32_t rq_ptr) { - uint32_t e = 0; - - 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, &e); - //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 deleted file mode 100644 index 760a159..0000000 --- a/src/kernel/ipc/request.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef DEF_REQUEST_H -#define DEF_REQUEST_H - -#include "object.h" - -#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], 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 { - int64_t ll; - uint32_t n; - } answer; - int errcode; //returned when function has finished - int pid; //pid of caller -}; - -struct user_request { - uint32_t func, params[3], shmsize[3]; - int isBlocking; // 1 : blocking request, 0 : nonblocking request (message) - int pid; //pid of caller process -}; - -struct user_sendrequest { - uint32_t func, a, b, c; - uint32_t answeri; - int64_t answerll; - int errcode; -}; - -//syscalls -int request_get(int obj, uint32_t ptr, int wait); -int request_has(int obj); -void request_answer(int obj, uint32_t answer, uint32_t answer2, int errcode); //answer2 used for long long. -int request_mapShm(int obj, uint32_t pos, int number); - -int request(int obj, uint32_t rq_ptr); -int send_msg(int obj, uint32_t rq_ptr); - -#endif - diff --git a/src/kernel/task/syscall.c b/src/kernel/task/syscall.c index b490987..46ccff6 100644 --- a/src/kernel/task/syscall.c +++ b/src/kernel/task/syscall.c @@ -21,18 +21,9 @@ CALL1V(process_exit, process_exit_sc); CALL1(monitor_write, printk_sc); CALL1V(idt_waitIrq, irq_wait_sc); CALL0(proc_priv, proc_priv_sc); +CALL2(process_setheapseg, proc_setheap_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); -CALL4V(request_answer, request_answer_sc); -CALL3(request_mapShm, request_mapShm_sc); -CALL2(request, request_sc); -CALL2(send_msg, send_msg_sc); -CALL2(process_setheapseg, proc_setheap_sc); static void thread_new_sc(struct registers* r) { thread_new(current_thread->process, (thread_entry)r->ebx, (void*)r->ecx, (void*)r->edx); @@ -47,16 +38,7 @@ int_callback syscalls[NUMBER_OF_SYSCALLS] = { thread_new_sc, //5 irq_wait_sc, 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, proc_setheap_sc, + shm_create_sc, + shm_delete_sc, //10 0 }; diff --git a/src/kernel/task/task.c b/src/kernel/task/task.c index b8a72ce..f074c77 100644 --- a/src/kernel/task/task.c +++ b/src/kernel/task/task.c @@ -5,13 +5,10 @@ #include <mem/mem.h> #include <mem/seg.h> #include <mem/gdt.h> -#include <ipc/object.h> #include "timer.h" #define KSTACKSIZE 0x8000 -static struct object *manager_object = 0; - //Static routines for handling threads exiting and all cleanup static void thread_exit_stackJmp(uint32_t reason); static void thread_exit2(uint32_t reason); @@ -294,13 +291,6 @@ struct process *process_new(struct process* parent, uint32_t uid, uint32_t privi p->stack = stacksBottom + USER_STACK_SIZE - 4; } - p->next_objdesc = 0; - p->objects = 0; - struct object* o = obj_new(p); - if (manager_object == 0) manager_object = o; - objdesc_add(p, o); //create process' root object and add descriptor 0 to it - objdesc_add(p, manager_object); - processes = p; return p; } @@ -332,7 +322,6 @@ static void process_delete(struct process *pr) { thread_delete(it); it = it->next; } - obj_closeall(pr); if (processes == pr) { processes = pr->next; } else { diff --git a/src/kernel/task/task.h b/src/kernel/task/task.h index 171a9fd..fdffa11 100644 --- a/src/kernel/task/task.h +++ b/src/kernel/task/task.h @@ -28,9 +28,6 @@ struct process { struct page_directory *pagedir; size_t stack; - struct obj_descriptor *objects; - uint32_t next_objdesc; - struct segment_map *heapseg; struct process *next; //Forms a linked list |