Haiku and BeOS are not microkernels. They are usually described as “hybrid modular” kernels, whatever that means.
In a microkernel, the idea is to move everything outside of the kernel: drivers, memory allocation, filesystems, network stack, and so on. The idea is that the kernel is a low level thing, cannot benefit from some hardware features because it needs to manage them (MMU, for example), and as such it is risky to write kernel code and any bug could have bad consequences. So, by having as few code as possible on the kernel side, you reduce this risk.
Haiku does not go this way, at all: drivers run inside the kernel, so do filesystems, the network stack and a lot of other things. But there are exceptions: for example, userlandfs allows to run file systems in userland, and app_server accelerants are essentially a large part of graphic drivers moved to userland. In BeOS, I think parts of the network stack were also running in net_server (userland), but they changed their mind on that with Bone.
Anyway, this is all software architecture and completely unrelated to what we are discussing here. You could do a microkernel that freezes the whole UI everytime you are waiting for the hard disk. What makes Haiku react well in high load situations is a set of design principles built into the API:
- Fine grained threading: each window and each application you open has a thread. This forces developers to think about which thread they are using for each task they want to achieve, and allows the scheduler to decide which of these to run
- Forcing to set thread priority: unless you use pthread APIs (pthread_create), you are forced in Haiku to give a priority to each thread you create. This gives the scheduler valuable information on which threads are important for user interaction (we have helpful constants like B_DISPLAY_PRIORITY, B_REALTIME_PRIORITY, etc).
Given these, the scheduler is given all the needed information (thread priorities) and flexibility (because threads are specialized) to decide what to do next. And it is tweaked so it will first run everything that involves user interface interaction: handling mouse and keyboard input, refreshing the display, etc. It is just that simple thing which makes Haiku react immediately when you click on something.
You don’t even need a real-time OS for the UI part, as there is no hard defined constraint on the latency here. Is it ok if the mouse freezes for 1 second? (probably not) 100 milliseconds? (I don’t know) 20 milliseconds? (the user probably wouldn’t notice) 16 milliseconds? (less than the time it takes to draw it on screen, so probably ok). The border is blurry between “ok” and “not ok”.
Haiku does use real-time scheduling only for select threads, and in particular everything that has to do with media. If your video skip frames, or your sound output has “holes” in it because the MP3 decoder doesn’t run fast enough, this is immediately noticeable and clearly not acceptable. Hence, for these tasks we use real-time scheduling.