Musings of an IPC Starved OS...
Posted: Mon Dec 11, 2006 11:15 am
Hey people!
Long time no see!
It is time to investigate Interprocess communication and after much research and hairpulling, Im still somewhat confused.
So! I shall ask you guys!.
I intend to implement Messagebased communication, mostly because it seems a nice and tidy way of communicating. A nice polite way to do it.
The idea in my head :
- Processes have their own Mailboxes. A mailbox simply holds X entries of Mail. Mail is a simple small structure, holding the PID of the process that sent it and an ID of a Message buffer.
Message Buffers:
Each process has a Messagebuffer tree. These buffers hold the data of the actual message. They are variable sized and are under Kernel control.
They track the data sent, the sender and the buffer size and the actual ID of the Buffer. The Key is simply the Buffer ID.
The idea:
Processes talk to eachother.
A process can send data, a process can retrieve data.
Example:
Process A wants to send a structure, 32bytes in size to Process B.
It does the following call:
send(process_b_pid, &structure, 32);
Im undecided on whether Sends are immediate or are queued, but regardless their function is the same.
The Kernel allocates a new BufferNode and adds it to the Destination processes BufferTree, it then stores the Buffer related data (Sender PID, Size, Buffer ID). It knows the size, so it allocates the buffer itself and copies the data from the current context (process A) to the buffer.
SSWITTCHCHH
We are in Process B now, with its context and addressspace.
It wants to check its inbox for this data.
structure* bla = (structure*)recieve(process_a_pid);
This comes in two peices. First of all, the usermode call checks the Process Mailbox, which is mapped low and viewable by the Process. It finds that t here is a message from process_a, it also retrieves the BufferID.
A systemcall is made to determine the size of the Buffer, once this is done, the usermode recieve call allocates a appropriately sized buffer for the data, another system call is made to copy it from Kernel buffer into the Usermode buffer. This call also deallocates the Buffer once the copy is complete.
The USermode call simply returns the address to its buffer. You can free the buffer easily since the usermode part allocates it like any other usermode allocation.
Mailboxes further:
Okay, so we have mailboxes, sure. That implies a zone of space used for storing Mail, what happens if we dont have anymore mailbox space left?
NO PROBLEM! The Messaging subsystem of the IPC Component maintains queues. Basically, Processes are added to the Messageable list. When the Messager sends a message, itll call something like ... add_message(pid, thismessage). If the message cant be added, it is queued. Everytime a message is sent, the Messager checks the queues and tries to send the waiting messages.
When Mail is read from a Processes Mailbox, it is automatically deleted to make room for further mail.
Ideas I have now:
- You could have the buffer size in the Mail. (pid, bufferid, buffersz).
- This is potentially slow, due to all the copying.
I will eventually do something like Ports or Shared Memory.
Mutex / Semaphores in my mind are mostly useful for Intraprocess synchronization. Multithreaded programming, etc, making sure something doesnt use a variable when its already being used. I can see this stuff would be handy in the Kernel world too, especially in ports.
This is at this point, crazy conceptual thoughts that popped into my brain while chatting with a good friend.
Ideas, suggestions, they are welcome.
~Zeii.
Long time no see!
It is time to investigate Interprocess communication and after much research and hairpulling, Im still somewhat confused.
So! I shall ask you guys!.
I intend to implement Messagebased communication, mostly because it seems a nice and tidy way of communicating. A nice polite way to do it.
The idea in my head :
- Processes have their own Mailboxes. A mailbox simply holds X entries of Mail. Mail is a simple small structure, holding the PID of the process that sent it and an ID of a Message buffer.
Message Buffers:
Each process has a Messagebuffer tree. These buffers hold the data of the actual message. They are variable sized and are under Kernel control.
They track the data sent, the sender and the buffer size and the actual ID of the Buffer. The Key is simply the Buffer ID.
The idea:
Processes talk to eachother.
A process can send data, a process can retrieve data.
Example:
Process A wants to send a structure, 32bytes in size to Process B.
It does the following call:
send(process_b_pid, &structure, 32);
Im undecided on whether Sends are immediate or are queued, but regardless their function is the same.
The Kernel allocates a new BufferNode and adds it to the Destination processes BufferTree, it then stores the Buffer related data (Sender PID, Size, Buffer ID). It knows the size, so it allocates the buffer itself and copies the data from the current context (process A) to the buffer.
SSWITTCHCHH
We are in Process B now, with its context and addressspace.
It wants to check its inbox for this data.
structure* bla = (structure*)recieve(process_a_pid);
This comes in two peices. First of all, the usermode call checks the Process Mailbox, which is mapped low and viewable by the Process. It finds that t here is a message from process_a, it also retrieves the BufferID.
A systemcall is made to determine the size of the Buffer, once this is done, the usermode recieve call allocates a appropriately sized buffer for the data, another system call is made to copy it from Kernel buffer into the Usermode buffer. This call also deallocates the Buffer once the copy is complete.
The USermode call simply returns the address to its buffer. You can free the buffer easily since the usermode part allocates it like any other usermode allocation.
Mailboxes further:
Okay, so we have mailboxes, sure. That implies a zone of space used for storing Mail, what happens if we dont have anymore mailbox space left?
NO PROBLEM! The Messaging subsystem of the IPC Component maintains queues. Basically, Processes are added to the Messageable list. When the Messager sends a message, itll call something like ... add_message(pid, thismessage). If the message cant be added, it is queued. Everytime a message is sent, the Messager checks the queues and tries to send the waiting messages.
When Mail is read from a Processes Mailbox, it is automatically deleted to make room for further mail.
Ideas I have now:
- You could have the buffer size in the Mail. (pid, bufferid, buffersz).
- This is potentially slow, due to all the copying.
I will eventually do something like Ports or Shared Memory.
Mutex / Semaphores in my mind are mostly useful for Intraprocess synchronization. Multithreaded programming, etc, making sure something doesnt use a variable when its already being used. I can see this stuff would be handy in the Kernel world too, especially in ports.
This is at this point, crazy conceptual thoughts that popped into my brain while chatting with a good friend.
Ideas, suggestions, they are welcome.
~Zeii.