summaryrefslogtreecommitdiff
path: root/src/kernel/ipc
diff options
context:
space:
mode:
authorAlexis211 <alexis211@gmail.com>2010-04-07 11:37:21 +0200
committerAlexis211 <alexis211@gmail.com>2010-04-07 11:37:21 +0200
commitee348973b0cb0f6481e4fd6e7494c63167c9759c (patch)
treea9f1cd82703aaeeefbf4cf449203881cfcafc0a5 /src/kernel/ipc
parentca4f5906f284e60a7a59ca7450e3e09c4f9356e5 (diff)
downloadTCE-ee348973b0cb0f6481e4fd6e7494c63167c9759c.tar.gz
TCE-ee348973b0cb0f6481e4fd6e7494c63167c9759c.zip
More work on manager
Diffstat (limited to 'src/kernel/ipc')
-rw-r--r--src/kernel/ipc/object.c1
-rw-r--r--src/kernel/ipc/object.h1
-rw-r--r--src/kernel/ipc/request.c37
-rw-r--r--src/kernel/ipc/request.h2
-rw-r--r--src/kernel/ipc/shm.c6
5 files changed, 35 insertions, 12 deletions
diff --git a/src/kernel/ipc/object.c b/src/kernel/ipc/object.c
index e381c89..cfb9652 100644
--- a/src/kernel/ipc/object.c
+++ b/src/kernel/ipc/object.c
@@ -8,6 +8,7 @@ struct object* obj_new(struct process* owner) {
ret->descriptors = 0;
ret->busyMutex = MUTEX_UNLOCKED;
ret->request = 0;
+ ret->wakeupOnRq = 0;
return ret;
}
diff --git a/src/kernel/ipc/object.h b/src/kernel/ipc/object.h
index 9dd3a1e..4577615 100644
--- a/src/kernel/ipc/object.h
+++ b/src/kernel/ipc/object.h
@@ -8,6 +8,7 @@ struct object {
int descriptors;
uint32_t busyMutex; //if busy, either a blocking request is being processed, or a sent message is waiting for being recieved
struct request *request;
+ struct thread *wakeupOnRq;
};
struct obj_descriptor {
diff --git a/src/kernel/ipc/request.c b/src/kernel/ipc/request.c
index 9ca724e..7fe8f2b 100644
--- a/src/kernel/ipc/request.c
+++ b/src/kernel/ipc/request.c
@@ -15,15 +15,19 @@ int request_get(int id, uint32_t ptr, int wait) {
if (obj->request != 0 && obj->request->acknowledged != RS_PENDING) return -3;
//if not (busymutex unlocked and request==0) && wait, then wait, else return -1
if (wait == 0 && obj->request == 0) return -1;
- while (obj->busyMutex != MUTEX_LOCKED && (obj->request == 0 || obj->request->acknowledged != RS_PENDING)) thread_sleep(1);
+ while (obj->busyMutex != MUTEX_LOCKED && (obj->request == 0 || obj->request->acknowledged != RS_PENDING)) {
+ //set thread to be waked up on request
+ obj->wakeupOnRq = current_thread;
+ //go to sleep
+ thread_goInactive();
+ }
obj->request->acknowledged = RS_PROCESSED;
//when request pending (wait finished), write it to ptr
struct user_request *p = (struct user_request*)ptr;
p->func = obj->request->func;
for (i = 0; i < 3; i++) {
p->params[i] = obj->request->params[i];
- if (obj->request->shm_sndr[i] != 0) p->shmsize[i] = obj->request->shm_sndr[i]->len;
- else p->shmsize[i] = 0;
+ p->shmsize[i] = obj->request->shmsize[i];
}
p->isBlocking = (obj->request->requester != 0);
p->pid = obj->request->pid;
@@ -69,15 +73,19 @@ void request_answer(int id, uint32_t answer, uint32_t answer2, int errcode) {
obj->request->acknowledged = RS_FINISHED;
switch (obj->request->func >> 30) {
case PT_OBJDESC:
- if ((int)answer <= 0) {
+ if ((int)answer < 0) {
obj->request->answer.n = answer;
} else {
if (obj->owner == obj->request->requester->process) {
obj->request->answer.n = answer;
} else {
- int n = objdesc_get(obj->request->requester->process, objdesc_read(obj->owner, answer));
- if (n == -1) {
- n = objdesc_add(obj->request->requester->process, objdesc_read(obj->owner, answer));
+ struct object *o = objdesc_read(obj->owner, answer);
+ int n = -1;
+ if (o != 0) {
+ n = objdesc_get(obj->request->requester->process, o);
+ if (n == -1) {
+ n = objdesc_add(obj->request->requester->process, o);
+ }
}
obj->request->answer.n = n;
}
@@ -110,11 +118,12 @@ int request_mapShm(int id, uint32_t pos, int number) {
int n = (obj->request->func >> (28 - (2 * number))) & 3;
if (n != PT_SHM) return -4;
//check if sender process is different from receiver process, if not return -7
- if (obj->owner == obj->request->requester->process) return -7;
+ if (obj->request->requester != 0 && obj->owner == obj->request->requester->process) return -7;
//check if sender sent a shm seg in parameter [number], if not return -5
if (obj->request->shm_sndr[number] == 0) return -5;
//map shm to position
obj->request->shm_rcv[number] = seg_map(obj->request->shm_sndr[number]->seg, obj->owner->pagedir, pos);
+ obj->request->shm_sndr[number]->seg->mappings--;
//if request is nonblocking and no more shm is to be mapped, delete request and free object busymutex
if (obj->request->requester != 0) return 0;
for (i = 0; i < 3; i++) {
@@ -161,7 +170,7 @@ static struct request *mkrequest(int id, struct thread *requester,
uint32_t v = (i == 0 ? a : (i == 1 ? b : c));
switch (n) {
case PT_OBJDESC:
- if ((int)v <= 0) {
+ if ((int)v < 0) {
rq->params[i] = v;
} else {
if (obj->owner == current_thread->process) {
@@ -180,16 +189,25 @@ static struct request *mkrequest(int id, struct thread *requester,
rq->params[i] = v;
break;
case PT_SHM:
+ rq->shmsize[i] = 0;
if (obj->owner == current_thread->process) {
rq->params[i] = v;
+ struct segment_map *t = shmseg_getByOff(current_thread->process, v);
+ if (t != 0) rq->shmsize[i] = t->len;
} else {
rq->shm_sndr[i] = shmseg_getByOff(current_thread->process, v);
+ rq->shm_sndr[i]->seg->mappings++;
+ if (rq->shm_sndr[i] != 0) rq->shmsize[i] = rq->shm_sndr[i]->len;
}
break;
}
}
// reference request from object
obj->request = rq;
+ if (obj->wakeupOnRq != 0) {
+ thread_wakeUp(obj->wakeupOnRq);
+ obj->wakeupOnRq = 0;
+ }
// return request
return rq;
}
@@ -230,5 +248,6 @@ int send_msg(int obj, uint32_t rq_ptr) {
//if returned value is 0, return -1 else return 0
if (e != 0) return e;
if (rq == 0) return -1;
+ urq->errcode = 0;
return 0;
}
diff --git a/src/kernel/ipc/request.h b/src/kernel/ipc/request.h
index 18eaf84..760a159 100644
--- a/src/kernel/ipc/request.h
+++ b/src/kernel/ipc/request.h
@@ -17,7 +17,7 @@
struct request {
struct object *obj;
struct thread *requester; //0 if nonblocking message
- uint32_t func, params[3], obj_close[3]; //obj_close : object descriptors to close when requests yields an answer
+ uint32_t func, params[3], obj_close[3], shmsize[3]; //obj_close : object descriptors to close when requests yields an answer
struct segment_map *shm_sndr[3], *shm_rcv[3];
int acknowledged; // (only for blocking requests) 0 : request is pending, 1 : request is being processes, 2 : finished, 3 : interrupted
union {
diff --git a/src/kernel/ipc/shm.c b/src/kernel/ipc/shm.c
index 1cdacfb..e760a0f 100644
--- a/src/kernel/ipc/shm.c
+++ b/src/kernel/ipc/shm.c
@@ -2,6 +2,7 @@
#include <mem/mem.h>
#include <mem/seg.h>
#include <task/task.h>
+#include <core/sys.h>
struct segment* shmseg_make(size_t len, struct process* owner) {
struct shmseg *ss = kmalloc(sizeof(struct shmseg));
@@ -29,8 +30,9 @@ struct segment_map *shmseg_map(struct segment *seg, struct page_directory *paged
void shmseg_unmap(struct segment_map *sm) {
size_t i;
- for (i = sm->start; i < sm->start + sm->len; i += 0x1000) {
- page_unmap(pagedir_getPage(sm->pagedir, i, 0));
+ for (i = 0; i < sm->len; i += 0x1000) {
+ struct page *page = pagedir_getPage(sm->pagedir, sm->start + i, 0);
+ if (page != 0) page_unmap(page);
}
}