General MicroKernel Design / IPC Relative Speeds
Posted: Tue Nov 20, 2007 4:28 am
Hi All,
Having just started our OS course at uni, my interest has been renewed and have been thinking about various things (apologies if the following ideas are trash or if I'm effectively talking about common knowledge, but it has been some time!).
I'm wanting to design a microkernel, so obviously a major worry is the speed of IPC. The basic design is that each task acts as a server for whatever device/service it provides, except that the kernel will take care of the listening part (i.e. an initial thread for each task sets up that task's data structures etc., and then the kernel manages the worker threads - trying to keep alive/kill threads in a way it deems to be most efficient - another part I'm need to figure out!). The kernel obviously needs to know what each is listening on (which could include IRQs etc.), and other tasks also need to know what task to contact for disk access etc. so this will all be setup in some config file - and these allocations will be protected, i.e. if the config file says that the "fat32" task should use "disk0", it will be unable to use "disk1" even if it tried.
When a task requests one of these other tasks, the kernel will add it to a queue, then allocate it the next available worker thread for the task specified (there'll also be settings for maximum number of threads for each task etc.). When this thread has been allocated, a shared memory region will also be setup between the 2 threads (of either a fixed size, or a size which was specified in the request). The idea is that all communication will be done through this memory region (user-space libraries will be provided so that this can be done easily by apps which don't need/or want to implement their own use of it). Originally I was hoping that this might lead to an incredibly small/simple set of kernel syscalls:-
- Memory Allocation / Freeing (i.e. mem_alloc, mem_realloc, mem_free)
- Task Requesting, Enlarging the Shared Space and Ending a Request* (task_request, task_enlarge, task_end)
*Ending a request will result in the freeing of the shared memory in both threads and the "requestED" worker thread being marked for termination or allocation to another request. There is no need for a call so that a thread can "die" independently as it will always be the "requestED" thread of something (even if it's just an IRQ).
However, I then started to wonder about whether it would be useful to have a syscall such that the requestING thread could share another bit of memory (which might already have data in), and realised that it basically comes down to whether it's quicker to copy data into the existing shared memory (no syscalls required), or to make a few syscalls and not need to copy.
Sorry for the length of the post but could people please comment on the general design, and also the speed comparison of syscalls / memory copying.
Thanks in advance,
Pete
Having just started our OS course at uni, my interest has been renewed and have been thinking about various things (apologies if the following ideas are trash or if I'm effectively talking about common knowledge, but it has been some time!).
I'm wanting to design a microkernel, so obviously a major worry is the speed of IPC. The basic design is that each task acts as a server for whatever device/service it provides, except that the kernel will take care of the listening part (i.e. an initial thread for each task sets up that task's data structures etc., and then the kernel manages the worker threads - trying to keep alive/kill threads in a way it deems to be most efficient - another part I'm need to figure out!). The kernel obviously needs to know what each is listening on (which could include IRQs etc.), and other tasks also need to know what task to contact for disk access etc. so this will all be setup in some config file - and these allocations will be protected, i.e. if the config file says that the "fat32" task should use "disk0", it will be unable to use "disk1" even if it tried.
When a task requests one of these other tasks, the kernel will add it to a queue, then allocate it the next available worker thread for the task specified (there'll also be settings for maximum number of threads for each task etc.). When this thread has been allocated, a shared memory region will also be setup between the 2 threads (of either a fixed size, or a size which was specified in the request). The idea is that all communication will be done through this memory region (user-space libraries will be provided so that this can be done easily by apps which don't need/or want to implement their own use of it). Originally I was hoping that this might lead to an incredibly small/simple set of kernel syscalls:-
- Memory Allocation / Freeing (i.e. mem_alloc, mem_realloc, mem_free)
- Task Requesting, Enlarging the Shared Space and Ending a Request* (task_request, task_enlarge, task_end)
*Ending a request will result in the freeing of the shared memory in both threads and the "requestED" worker thread being marked for termination or allocation to another request. There is no need for a call so that a thread can "die" independently as it will always be the "requestED" thread of something (even if it's just an IRQ).
However, I then started to wonder about whether it would be useful to have a syscall such that the requestING thread could share another bit of memory (which might already have data in), and realised that it basically comes down to whether it's quicker to copy data into the existing shared memory (no syscalls required), or to make a few syscalls and not need to copy.
Sorry for the length of the post but could people please comment on the general design, and also the speed comparison of syscalls / memory copying.
Thanks in advance,
Pete