An IPC design for an microkernel
Posted: Fri Nov 27, 2009 5:24 pm
Hi,
So I'm trying to design a microkernel and I'm plotting the IPC and how to design a POSIX API on top of it.
My basic IPC would be port which you can asynchronously send and recive fixed size messages from, it would be controlled by the kernel using system calls and it could expand in size as needed. It would also allocate some shared memory which would be used to implement a userspace heap which larger data and messages can be stored. This reduces the amount of system calls and typically the larger data would be needed by the reciver for a while anyway. An unique id can optionally be allocated per message so that the kernel can block the sender and catch the returning message (which would share the same id).
Now I not sure at what level I should allocate ports, there is a few (many) possibilities:
Now for POSIX emulation I see two options, one is to implement it in a wrapper library or a wrapper service, which could help with descriptor inheritance with fork and execve. As this could depend upon the result of my process management I think I'll wait a bit with the design.
I also had an idea to have a pointer to a page of shared memory passed with a message instead of using the heap as storage. The typical message payload would be sized from 512 bytes to the size of a page which makes a page a nice medium. It would also have the benefit that you could just map the pages you'd want to swap out to the port. If this is suitable would depend on if the speed of a system call is faster than just copying the data (which could be accelerated with SSE).
I would like some feedback on the design and suggestions for improvement and I can start planning the process creation/management, memory management and page swapping...
So I'm trying to design a microkernel and I'm plotting the IPC and how to design a POSIX API on top of it.
My basic IPC would be port which you can asynchronously send and recive fixed size messages from, it would be controlled by the kernel using system calls and it could expand in size as needed. It would also allocate some shared memory which would be used to implement a userspace heap which larger data and messages can be stored. This reduces the amount of system calls and typically the larger data would be needed by the reciver for a while anyway. An unique id can optionally be allocated per message so that the kernel can block the sender and catch the returning message (which would share the same id).
Now I not sure at what level I should allocate ports, there is a few (many) possibilities:
- They could be allocated per process. This is simple, but would increase the port lock contention.
- They could be allocated per thread. This increases memory usage, but reduces the port lock contention.
- They could be allocated per object. This has the highest amount of memory usage and would require the servers to check a high amount of ports. It would make a POSIX implementation simpler however.
Now for POSIX emulation I see two options, one is to implement it in a wrapper library or a wrapper service, which could help with descriptor inheritance with fork and execve. As this could depend upon the result of my process management I think I'll wait a bit with the design.
I also had an idea to have a pointer to a page of shared memory passed with a message instead of using the heap as storage. The typical message payload would be sized from 512 bytes to the size of a page which makes a page a nice medium. It would also have the benefit that you could just map the pages you'd want to swap out to the port. If this is suitable would depend on if the speed of a system call is faster than just copying the data (which could be accelerated with SSE).
I would like some feedback on the design and suggestions for improvement and I can start planning the process creation/management, memory management and page swapping...