Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Microkernel
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
==Inter-process communication== [[Inter-process communication]] (IPC) is any mechanism which allows separate processes to communicate with each other, usually by sending [[message passing|messages]]. [[Shared memory]] is, strictly defined, also an inter-process communication mechanism, but the abbreviation IPC usually refers to message passing only, and it is the latter that is particularly relevant to microkernels. IPC allows the operating system to be built from a number of smaller programs called servers, which are used by other programs on the system, invoked via IPC. Most or all support for peripheral hardware is handled in this fashion, with servers for device drivers, [[network protocol stack]]s, file systems, graphics, etc. IPC can be synchronous or asynchronous. Asynchronous IPC is analogous to network communication: the sender dispatches a message and continues executing. The receiver checks ([[Polling (computer science)|polls]]) for the availability of the message, or is alerted to it via some notification mechanism. Asynchronous IPC requires that the kernel maintains buffers and queues for messages, and deals with buffer overflows; it also requires double copying of messages (sender to kernel and kernel to receiver). In synchronous IPC, the first party (sender or receiver) blocks until the other party is ready to perform the IPC. It does not require buffering or multiple copies, but the implicit rendezvous can make programming tricky. Most programmers prefer asynchronous send and synchronous receive. First-generation microkernels typically supported synchronous as well as asynchronous IPC, and suffered from poor IPC performance. [[Jochen Liedtke]] assumed the design and implementation of the IPC mechanisms to be the underlying reason for this poor performance. In his [[L4 microkernel family|L4 microkernel]] he pioneered methods that lowered IPC costs by an [[order of magnitude]].<ref name="Liedtke_93">{{cite conference | first = Jochen | last = Liedtke | author-link = Jochen Liedtke | title = Improving IPC by kernel design | conference = 14th ACM Symposium on Operating System Principles | pages = 175β88 |date=December 1993 | location = Asheville, NC, USA | citeseerx = 10.1.1.40.1293 }}</ref> These include an IPC system call that supports a send as well as a receive operation, making all IPC synchronous, and passing as much data as possible in registers. Furthermore, Liedtke introduced the concept of the ''direct process switch'', where during an IPC execution an (incomplete) [[context switch]] is performed from the sender directly to the receiver. If, as in L4, part or all of the message is passed in registers, this transfers the in-register part of the message without any copying at all. Furthermore, the overhead of invoking the scheduler is avoided; this is especially beneficial in the common case where IPC is used in a [[remote procedure call]] (RPC) type fashion by a client invoking a server. Another optimization, called ''lazy scheduling'', avoids traversing scheduling queues during IPC by leaving threads that block during IPC in the ready queue. Once the scheduler is invoked, it moves such threads to the appropriate waiting queue. As in many cases a thread gets unblocked before the next scheduler invocation, this approach saves significant work. Similar approaches have since been adopted by [[QNX]] and [[MINIX 3]].{{Citation needed|date=August 2010}} In a series of experiments, Chen and Bershad compared memory [[cycles per instruction]] (MCPI) of monolithic [[Ultrix]] with those of microkernel [[Mach (kernel)|Mach]] combined with a [[4.3BSD]] [[Unix]] server running in [[user space]]. Their results explained Mach's poorer performance by higher MCPI and demonstrated that IPC alone is not responsible for much of the system overhead, suggesting that optimizations focused exclusively on IPC will have a limited effect.<ref name="Chen_Bershad_93">{{cite conference | first1 = J. Bradley | last1 = Chen | first2 = Brian N. | last2 = Bershad | title = The Impact of Operating System Structure on Memory System Performance | book-title = SOSP '93 Proceedings of the fourteenth ACM symposium on Operating systems principles | pages = 120β133 | date= December 1993 | location = Asheville, NC, USA | doi = 10.1145/168619.168629 | url = https://people.eecs.berkeley.edu/~prabal/resources/osprelim/CB93.pdf }}</ref> Liedtke later refined Chen and Bershad's results by making an observation that the bulk of the difference between Ultrix and Mach MCPI was caused by capacity [[CPU cache#CACHE-MISS|cache-misses]] and concluding that drastically reducing the cache working set of a microkernel will solve the problem.<ref name="Liedtke_95">{{cite conference | first = Jochen | last = Liedtke | author-link = Jochen Liedtke | title = On Β΅-Kernel Construction | book-title = SOSP '95 Proceedings of the fifteenth ACM symposium on Operating systems principles | pages = 237β250 | date= December 1995 | location = Copper Mountain Resort, CO, USA | doi = 10.1145/224056.224075 | doi-access = free }}</ref> In a client-server system, most communication is essentially synchronous, even if using asynchronous primitives, as the typical operation is a client invoking a server and then waiting for a reply. As it also lends itself to more efficient implementation, most microkernels generally followed L4's lead and only provided a synchronous IPC primitive. Asynchronous IPC could be implemented on top by using helper threads. However, experience has shown that the utility of synchronous IPC is dubious: synchronous IPC forces a multi-threaded design onto otherwise simple systems, with the resulting synchronization complexities. Moreover, an RPC-like server invocation sequentializes client and server, which should be avoided if they are running on separate cores. Versions of L4 deployed in commercial products have therefore found it necessary to add an asynchronous notification mechanism to better support asynchronous communication. This [[signal (computing)|signal]]-like mechanism does not carry data and therefore does not require buffering by the kernel. By having two forms of IPC, they have nonetheless violated the principle of minimality. Other versions of L4 have switched to asynchronous IPC completely.<ref name="elphinstone_2013">{{cite conference | first1 = Kevin | last1 = Elphinstone | first2 = Gernot | last2 = Heiser | title = From L3 to seL4: What Have We Learnt in 20 Years of L4 Microkernels? | book-title = SOSP '13 Proceedings of the Twenty-Fourth ACM Symposium on Operating Systems Principles | pages = 133β150 | date = November 2013 | location = Farmington, PA, USA | doi = 10.1145/2517349.2522720 | doi-access = free }} </ref> As synchronous IPC blocks the first party until the other is ready, unrestricted use could easily lead to deadlocks. Furthermore, a client could easily mount a [[denial-of-service]] attack on a server by sending a request and never attempting to receive the reply. Therefore, synchronous IPC must provide a means to prevent indefinite blocking. Many microkernels provide [[timeout (telecommunication)|timeouts]] on IPC calls, which limit the blocking time. In practice, choosing sensible timeout values is difficult, and systems almost inevitably use infinite timeouts for clients and zero timeouts for servers. As a consequence, the trend is towards not providing arbitrary timeouts, but only a flag which indicates that the IPC should fail immediately if the partner is not ready. This approach effectively provides a choice of the two timeout values of zero and infinity. Recent versions of L4 and MINIX have gone down this path (older versions of L4 used timeouts). QNX avoids the problem by requiring the client to specify the reply buffer as part of the message send call. When the server replies the kernel copies the data to the client's buffer, without having to wait for the client to receive the response explicitly.<ref>{{cite web |title=Synchronous Message Passing |url=https://www.qnx.com/developers/docs/7.0.0/#com.qnx.doc.neutrino.sys_arch/topic/ipc_Sync_messaging.html |access-date=3 September 2024 |ref=qnx_ipc}}</ref>
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)