Traditionally, system services have been implemented in two ways, depending on their requirements. Either people wrote shared libraries for “light” work, or they wrote daemons that were contacted using bytestream- or message-based IPC primitives (such as pipes, sockets, or D-BUS). With RPC, I have proposed another IPC method that would be more specifically tailored to the job, but how well would it fare against the old ways at a conceptual level ? Well, here is my attempt at a fair comparison.
The comparison criteria
So, what would be a good way of implementing system services ? First, it should be fit for most purposes, so as to avoid the schizophrenic separation between libraries and daemons that we have these days, in which most system services end up implemented half in the form of shared libraries, half in the form of privileged daemons (most obvious example being memory allocation). Second, it should guarantee a good level of reliability. System services shouldn’t crash, and when they do, they should be able to do it quietly, restart automatically, and resume work right away. Third, it should be fast. No one likes laggy operating systems. Fourth, it should be future-proof, because DLL hell and system-breaking updates are evil.
Other criteria which I had considered were security and simplicity. Concerning security, it appears to me that most of the parameters which affect it (user and system code sharing a single address space or communicating through well-controlled entry points, bug likelihood) also affect reliability, so that putting both in the same comparison would be a bit redundant. At this low level, simplicity only affects reliability and performance, so again I am not sure that mentioning it again would be relevant.
|Library||Daemons + RPC||Daemons + Messages|
|Services may access privileged system resources that are beyond client reach||No||Yes||Yes|
|Tasks can be processed with the priority of client code||Yes||Yes||No|
|Tasks can be processed with a service-specific priority||No||Yes||Yes|
|Support is bundled in all programming languages and no wrapper code is required||Yes||No||No|
|Reliability and security
|Client code is forbidden from messing with service code and vice versa||No||Yes||Yes|
|Service bugs only have an indirect impact on client code||No||Yes||Yes|
|If the service crashes for one client, it does not necessarily affect other clients||Yes||No||No|
|The communication protocol can gracefully handle crashes||No||Yes||No|
|Development complexity (and thus bug likelihood) is…||Low||Medium||High|
|Service code has a separate stack, and thus may not cause client stack overflow||No||Yes||Yes|
|Function call overhead is…||Low||Medium||High|
|Services and clients may easily share memory for efficient data exchange||Yes||Yes||No|
|Services can be loaded and initialized in advance||No||Yes||Yes|
|When a new client is started, it can reuse running services instead of initializing a new copy||No||Yes||Yes|
|Thread safety is unnecessary when processing concurrent requests||No||Yes||Yes|
|Service functions can be extended without requiring existing client recompilation||No||Yes||Yes|
|Given some support code, services can be updated without rebooting the whole system||No||Yes||Yes|
From this comparison, the reason why system services are traditionally implemented using a mix of libraries and message-driven daemons becomes pretty apparent : they literally complement each other. Does RPC succeed at its task of bridging the gap between both ? I would say yes. The only defects which it inherits from its daemon-based natures are the need for some automatically generated wrapper code, some coding complexity and function call overhead that would make it unsuitable for very simple tasks, and a centralized nature that requires better-than-usual crash management (it should be noted, however, that libraries have the bad habit of killing clients in cold blood without any hope of recovery when they crash…)
Overall, I’m pretty satisfied with that. But is it all there is to it ? If you have feedback on this comparison or more criteria to add in mind, do not hesitate to talk about it in the comments !