Hello ppl,
I've just started work on IPC on my kernel. I'm using a microkernel based architecture. and I want to implement message-passing as the IPC mechanism. I'm using segmented-paging memory model. I plan to implement demand paging also.
Kindly give me ideas regarding implementation of the message-passing IPC mechanism
Thanking you very sincerely,
Joe
Pro-OS: Inter Process Communication problem
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Pro-OS: Inter Process Communication problem
well, it depends on what you call "message passing"... but basically, it's almost sure you will need to allocate some shared memory for your processes (basically give programs A and B a segment that they will use to talk with each other), and have two semaphores: one telling the "message sender" how much space is left in the queue and one telling the "message receiver" how much message it has in the queue.
okay, this is just a JavaSketch, but it should give you a hint of what i mean if you're aware of what a Semaphore is
Code: Select all
class Queue extends SharedObject {
Semaphore slots_left=new Semaphore(NB_SLOTS);
Semaphore data_ready=new Semaphore(0);
Message data[]=new Message[NB_SLOTS];
int read_next=0, write_next=0;
send(Message msg) {
wait(slots_left);
data[write_next]=msg;
write_next=(write_next+1)%NB_SLOTS;
signal(data_ready);
}
Message receive () {
Message m;
wait (data_ready);
m=data[read_next];
read_next=(read_next+1)%NB_SLOTS;
signal(slots_left);
return m;
}
Re:Pro-OS: Inter Process Communication problem
Hey.. thanks a lot for the reply..
the thing is that, i'm not using any shared memory thing..
i've a pointer called msg_buff in the proc table. when a process blocks with a _recv call, it sends the buffer where to put the recieved msg packet as a parameter. this msg buffer pointer is verified and then saved in msg_buff element of the proc table.
when some one sends, a same thing happens, the buffer containing the msg packet to be delivered is passed as a parameter.. and i check whether the destination process is blocked waiting for a message. if it is ., i copy the contents of sender's packet to the receivers buffer.. and put both of them as READY and hence IPC is achieved..
but the prob is , supposing the process supplied buffer has been swapped out to the block device., and the kernel tries to access it, a page fault will occur in the kernel.. i dont want this to happen.. coz, i'm just disabling all interrupts during the send and recv calls.. by this way i make the 'send' and 'recv' calls as a atomic call which cannot be interrupted and hence avoid race conditions..
so how.. here comes the problem.. during a send i dont know how to handle the possible page fault.. the other way around is that.. the kernel has to verify with the page tables and get the page loaded before doing anything.. i guess you'll understand that this way stupid as, the architecture of the kernel is that of a microkernel and so, if the kernel wants to bring the page up.. it has to wait on the memory manager which is another process .. and the disk task.. which is yet another process.. and hence the whole thing get screwed...
so here is my problem..
please.. please help me.. tell me if there is another workaround..
the kernel should do nothing other than simply multitaska and pass messages between the processes.,
Thanks again..
Joe
the thing is that, i'm not using any shared memory thing..
i've a pointer called msg_buff in the proc table. when a process blocks with a _recv call, it sends the buffer where to put the recieved msg packet as a parameter. this msg buffer pointer is verified and then saved in msg_buff element of the proc table.
when some one sends, a same thing happens, the buffer containing the msg packet to be delivered is passed as a parameter.. and i check whether the destination process is blocked waiting for a message. if it is ., i copy the contents of sender's packet to the receivers buffer.. and put both of them as READY and hence IPC is achieved..
but the prob is , supposing the process supplied buffer has been swapped out to the block device., and the kernel tries to access it, a page fault will occur in the kernel.. i dont want this to happen.. coz, i'm just disabling all interrupts during the send and recv calls.. by this way i make the 'send' and 'recv' calls as a atomic call which cannot be interrupted and hence avoid race conditions..
so how.. here comes the problem.. during a send i dont know how to handle the possible page fault.. the other way around is that.. the kernel has to verify with the page tables and get the page loaded before doing anything.. i guess you'll understand that this way stupid as, the architecture of the kernel is that of a microkernel and so, if the kernel wants to bring the page up.. it has to wait on the memory manager which is another process .. and the disk task.. which is yet another process.. and hence the whole thing get screwed...
so here is my problem..
please.. please help me.. tell me if there is another workaround..
the kernel should do nothing other than simply multitaska and pass messages between the processes.,
Thanks again..
Joe
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Pro-OS: Inter Process Communication problem
well, maybe you could set a bit in the page table entries telling the kernel that the page that hold your buffer is locked and should not be swapped out. The process table entries should be locked aswell, so that you don't have the problem of deadlock anymore.
Let's give it a try:
Now, i think you overcomplicates things by trying to have message allocations at both (sender & receiver) sides.
Why not deciding that the message will be allocated by the sender and that it will be mapped in the address space of the receiver by the kernel, so the receiver simply receives the address of the new mapping and call something like _dispose(buffer) when done ?
Let's give it a try:
Code: Select all
class Process {
_recv(void* from, int size) {
synchronized(this) {
if (!hasMessage) {
foreach (page in Pages.cover(from,from+size)) do {
page.lock();
}
addMsgBuffer(this);
waitForMessage();
}
memcpy(from,msg().data,min(size,msg().size);
return size<msg.size()?size:-ERRTOOSMALL;
}
}
Why not deciding that the message will be allocated by the sender and that it will be mapped in the address space of the receiver by the kernel, so the receiver simply receives the address of the new mapping and call something like _dispose(buffer) when done ?
Re:Pro-OS: Inter Process Communication problem
Hey.. guess what???
>Why not deciding that the message will be allocated
>by the sender and that it will be mapped in the
>address space of the receiver by the kernel, so the
>receiver simply receives the address of the new
>mapping and call something like _dispose(buffer)
>when done ?
is a kick @$$ idea.. the other idea you gave..wont work out.. coz the memory allocation is very very primitive.. i dont differentiate between differnent types of pages.. that might be inside in the future..
but this idea that you gave is a good one.. but there are some problems.. you'd be seeing, that the sender will be blocked on sending.. that shouldnt be.. the sender should not block.. coz, the recv call also blocks.. so both send and recv blocks,, there is a possibility of a deadlock..
and moreover.. how to map the buffer in the senders address space to the reciever's address space.. both their address spaces are completely different.. they use differnt LDTs...
anywayz.. i'll look on the developing on this approach..if you have any more ideas..please please.. post them..
thanking you.
Joe
>Why not deciding that the message will be allocated
>by the sender and that it will be mapped in the
>address space of the receiver by the kernel, so the
>receiver simply receives the address of the new
>mapping and call something like _dispose(buffer)
>when done ?
is a kick @$$ idea.. the other idea you gave..wont work out.. coz the memory allocation is very very primitive.. i dont differentiate between differnent types of pages.. that might be inside in the future..
but this idea that you gave is a good one.. but there are some problems.. you'd be seeing, that the sender will be blocked on sending.. that shouldnt be.. the sender should not block.. coz, the recv call also blocks.. so both send and recv blocks,, there is a possibility of a deadlock..
and moreover.. how to map the buffer in the senders address space to the reciever's address space.. both their address spaces are completely different.. they use differnt LDTs...
anywayz.. i'll look on the developing on this approach..if you have any more ideas..please please.. post them..
thanking you.
Joe
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Pro-OS: Inter Process Communication problem
process A : "send (msg, size)"
Note: if you plan to have a page swapper, you should definitely have a "lock" bit that prevents page from being swapped out or something alike ... Just to avoid devices buffers from being swapped, for instance ...
- --> kernel : either lock the pages for msg..msg+size or allocate a new buffer of size "size" and copy the message into it (less efficient)
- --> kernel : create a message handle that tells which physical memory area has the data for the message and enqueue that message to the receiver's list of message. If the receiver was waiting a message, kick his @$$ (wake it up ...
- --> kernel (just after waken up or if a message is immediately available): get back the message handle, allocate a new segment in B.LDT and make it map the physical memory of the message.
- --> return the selector and the size to the user process.
- --> check it is a "message" selector, release it, get back the message handle for it
- --> either free the internal message copy or unlock the pages for it
- --> free the message handle. You can optionnally decide to confirm the reception to the sender.
Note: if you plan to have a page swapper, you should definitely have a "lock" bit that prevents page from being swapped out or something alike ... Just to avoid devices buffers from being swapped, for instance ...
Re:Pro-OS: Inter Process Communication problem
hey pype,
you aint getting me.. I CANT ACCESS ANY MEMORY MANAGEMENT FUNCTIONS FROM THE KERNEL.. so. i just can set the lock bit.. but there is another problem even if i manage to.. see if the page is already swapped before the syscall. .. This can happen if the msg packet is constant data..
see.. if i create a process. i'll wont load the entire file into mem.. just the first page.. and then load as and when needed.. so., if on the first page being loaded, the process calls a send, and if the msgpacket is not yet loaded.. it'll cause a page fault and worst.. the kernel wont be in a state to handle it..
but hey.. i just kept banging my head on the wall nearby all through the afternoon.. and have found that.. i can actually do a little trick such that if a page fault occurs in a kernel, the mm would be able to distinguish that and do the appropriate.. all i've to see to that is i dont adjust any of the scheduling queues.. if the page fault occurs in the kernel.. this way.. it'll behave perfectly alright.. no blocking..nothing.. just simply re-entry..
do you thinking there would be any problem in this.. please do post your comments..
thanks a lot.
Joe
you aint getting me.. I CANT ACCESS ANY MEMORY MANAGEMENT FUNCTIONS FROM THE KERNEL.. so. i just can set the lock bit.. but there is another problem even if i manage to.. see if the page is already swapped before the syscall. .. This can happen if the msg packet is constant data..
see.. if i create a process. i'll wont load the entire file into mem.. just the first page.. and then load as and when needed.. so., if on the first page being loaded, the process calls a send, and if the msgpacket is not yet loaded.. it'll cause a page fault and worst.. the kernel wont be in a state to handle it..
but hey.. i just kept banging my head on the wall nearby all through the afternoon.. and have found that.. i can actually do a little trick such that if a page fault occurs in a kernel, the mm would be able to distinguish that and do the appropriate.. all i've to see to that is i dont adjust any of the scheduling queues.. if the page fault occurs in the kernel.. this way.. it'll behave perfectly alright.. no blocking..nothing.. just simply re-entry..
do you thinking there would be any problem in this.. please do post your comments..
thanks a lot.
Joe