summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/objects-requests.txt20
-rw-r--r--doc/syscalls.txt15
-rw-r--r--src/include/gc/syscall.h29
-rw-r--r--src/kernel/Makefile2
-rw-r--r--src/kernel/core/kmain.c7
-rw-r--r--src/kernel/ipc/object.c10
-rw-r--r--src/kernel/ipc/request.c201
-rw-r--r--src/kernel/ipc/request.h35
-rw-r--r--src/kernel/mem/gdt.c2
-rw-r--r--src/kernel/mem/mem.c2
-rw-r--r--src/kernel/mem/paging.c6
-rw-r--r--src/kernel/task/idt.c2
-rw-r--r--src/kernel/task/syscall.c21
-rw-r--r--src/kernel/task/task.c7
-rw-r--r--src/kernel/task/task.h2
-rw-r--r--src/kernel/task/timer.c2
-rw-r--r--src/library/gc/syscall.c36
-rw-r--r--src/modules/test/main.c32
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 <lib/mutex.h>
+#include <mem/seg.h>
+#include <mem/mem.h>
-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 <mem/mem.h>
#include <mem/seg.h>
#include <mem/gdt.h>
+#include <ipc/object.h>
#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 <types.h>
#include <mem/paging.h>
-#include <ipc/object.h>
#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;
}