How do you handle messaging?
Posted: Thu Aug 13, 2015 7:45 pm
Hi,
I've been thinking about message passing lately for my micro-kernel and thought I'd ask how others have implemented it or are planning to do so. Also what criteria do you think is important?
Criteria that comes to mind:
- Simpler is better
- Performance/Efficiency
- Reliable vs unreliable
- Fixed size vs variable sized
- Synchronous vs asynchronous
- Local vs distributed
- Addressing, using PID (or thread ID, task ID, etc) as sender and recipient address or something else?
- Queuing or not
Assuming virtual memory space is used, then it is required to move between memory spaces to deliver the message. Two ways of doing that:
- Message router has access to all memory spaces
- Every address space (task) has (limited) access to message routers address space
So far I've been thinking of using fixed sized messages, probably very small. The smallest message I can think of would only contain the recipient, which I'm pretty sure can't be avoided. The next smallest would have some message data, which should be 32-bit (address sized for IA-32). There would also be a standardized way of sending larger messages by utilizing this recipient+data format, for example the data being a pointer to some type of structure that's in a page frame that can be moved to the receiving task's memory.
One other thing that comes to mind is whether tasks should have only one incoming message queue or if they should be allowed to have multiple. Even if they have only one, they can still create multiple in user land by simply multiplexing everything thru that one inbox, for example the code managing the inbox simply takes the messages and based on their priority (or requested activity) places them in multiple inboxes that the application's main logic then waits on. Having just one would move the complexity from kernel to userland and only when it is needed does it cause overhead. On the other hand if the kernel has to do some lookup anyway (to find out where to put the message in the first place) it might be more efficient to put the message in the recipients proper inbox immediately and not have the application recreate part of the logic.
One reason to have multiple inboxes is related to the point above about minimum message only having a recipient, this could work similar to the linux signals, if a message is received in a specific inbox then do something specific, like terminate the task.
How do you see the message sending semantics? Once a message is sent, should it be at all available for the sending side?
I've been thinking about message passing lately for my micro-kernel and thought I'd ask how others have implemented it or are planning to do so. Also what criteria do you think is important?
Criteria that comes to mind:
- Simpler is better
- Performance/Efficiency
- Reliable vs unreliable
- Fixed size vs variable sized
- Synchronous vs asynchronous
- Local vs distributed
- Addressing, using PID (or thread ID, task ID, etc) as sender and recipient address or something else?
- Queuing or not
Assuming virtual memory space is used, then it is required to move between memory spaces to deliver the message. Two ways of doing that:
- Message router has access to all memory spaces
- Every address space (task) has (limited) access to message routers address space
So far I've been thinking of using fixed sized messages, probably very small. The smallest message I can think of would only contain the recipient, which I'm pretty sure can't be avoided. The next smallest would have some message data, which should be 32-bit (address sized for IA-32). There would also be a standardized way of sending larger messages by utilizing this recipient+data format, for example the data being a pointer to some type of structure that's in a page frame that can be moved to the receiving task's memory.
One other thing that comes to mind is whether tasks should have only one incoming message queue or if they should be allowed to have multiple. Even if they have only one, they can still create multiple in user land by simply multiplexing everything thru that one inbox, for example the code managing the inbox simply takes the messages and based on their priority (or requested activity) places them in multiple inboxes that the application's main logic then waits on. Having just one would move the complexity from kernel to userland and only when it is needed does it cause overhead. On the other hand if the kernel has to do some lookup anyway (to find out where to put the message in the first place) it might be more efficient to put the message in the recipients proper inbox immediately and not have the application recreate part of the logic.
One reason to have multiple inboxes is related to the point above about minimum message only having a recipient, this could work similar to the linux signals, if a message is received in a specific inbox then do something specific, like terminate the task.
How do you see the message sending semantics? Once a message is sent, should it be at all available for the sending side?