diff options
-rw-r--r-- | hurd/faq/old_hurd_faq.txt | 2 | ||||
-rw-r--r-- | idl.mdwn | 22 | ||||
-rw-r--r-- | ipc.mdwn | 15 | ||||
-rw-r--r-- | microkernel/fud.mdwn | 14 | ||||
-rw-r--r-- | microkernel/mach/concepts.mdwn | 27 | ||||
-rw-r--r-- | microkernel/mach/documentation.mdwn | 6 | ||||
-rw-r--r-- | microkernel/mach/external_pager_mechanism.mdwn | 14 | ||||
-rw-r--r-- | microkernel/mach/ipc.mdwn | 19 | ||||
-rw-r--r-- | microkernel/mach/memory_object.mdwn | 31 | ||||
-rw-r--r-- | microkernel/mach/message.mdwn | 31 | ||||
-rw-r--r-- | microkernel/mach/mig.mdwn | 33 | ||||
-rw-r--r-- | microkernel/mach/mig/documentation.mdwn | 14 | ||||
-rw-r--r-- | microkernel/mach/mig/gnu_mig.mdwn | 12 | ||||
-rw-r--r-- | microkernel/mach/port.mdwn | 114 | ||||
-rw-r--r-- | microkernel/mach/rpc.mdwn | 16 | ||||
-rw-r--r-- | microkernel/mach/task.mdwn | 23 | ||||
-rw-r--r-- | microkernel/mach/thread.mdwn | 37 | ||||
-rw-r--r-- | microkernel/mach/virtual_address_space.mdwn | 36 |
18 files changed, 364 insertions, 102 deletions
diff --git a/hurd/faq/old_hurd_faq.txt b/hurd/faq/old_hurd_faq.txt index c7e0ffe8..e6c6cb5a 100644 --- a/hurd/faq/old_hurd_faq.txt +++ b/hurd/faq/old_hurd_faq.txt @@ -89,7 +89,7 @@ Q4. What's all this about Mach 3.0 (and Mach 4.0)? As mentioned above, Mach is a micro-kernel, written at Carnegie Mellon University. A more descriptive term might be a greatest-common-factor kernel, since it provides facilities common to all ``real'' operating -systems, such as memory management, interprocess communication, +systems, such as memory management, inter-process communication, processes, and a bunch of other stuff. Unfortunately, the system calls used to access these facilities are only vaguely related to the familiar and cherished Unix system calls. There are no "fork", @@ -1,15 +1,19 @@ -[[!meta copyright="Copyright © 2007, 2008 Free Software Foundation, Inc."]] +[[!meta copyright="Copyright © 2002, 2003, 2007, 2008, 2010 Free Software +Foundation, Inc."]] [[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable id="license" text="Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license -is included in the section entitled -[[GNU Free Documentation License|/fdl]]."]]"""]] - -An IDL is an interface definition language. The most well-known is -CORBA. An IDL compiler takes a specification and generates stubs -that hide the transport details. In the case of [[microkernel/mach/MIG]], this -hides the marshalling and unmarshalling of parameters according -to [[microkernel/Mach]]'s semantics. +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] + +An *IDL* is an *interface definition language*. The most well-known is CORBA. + +An IDL compiler takes a specification and generates stub code that hides the +transport details, and by this implements a [[RPC]] system. + +In the case of [[Mach's MIG|microkernel/mach/mig]], this hides the marshalling +and unmarshalling of parameters according to [[microkernel/Mach]]'s semantics, +and invoking the respective [[microkernel/mach/port]] operations. @@ -1,16 +1,17 @@ -[[!meta copyright="Copyright © 2007, 2008 Free Software Foundation, Inc."]] +[[!meta copyright="Copyright © 2007, 2008, 2010 Free Software Foundation, +Inc."]] [[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable id="license" text="Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license -is included in the section entitled -[[GNU Free Documentation License|/fdl]]."]]"""]] +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] -IPC stands for interprocess communication. +*IPC* stands for *inter-process communication*. -On [[Unix]], interprocess communication can be achieved using pipes. +On [[Unix]], inter-process communication can be achieved using pipes. This is inefficient for large amounts of data as the data must be copied. This is generally not a problem as most services are provided by the Unix kernel and Unix is not designed to be @@ -22,12 +23,14 @@ of many components. As components are separated by their respective examine and modify the caller's state. The advantage is that if the protocol is carefully designed, the callee cannot cause the caller any [[destructive_interference]] thereby removing the need for the -caller to [[trust]] the callee thus reducing the former's [[tcb]]. +caller to [[trust]] the callee thus reducing the former's [[TCB]]. When done systematically, this can increase the system's [[robustness]]. To this end, microkernels provide richer IPC semantics that include the ability to transfer [[capabilities|capability]] and to use [[virtual_memory]] [[mechanism]]s to copy data. +Continue reading about [[Mach's IPC system|microkernel/mach/IPC]]. + # See Also diff --git a/microkernel/fud.mdwn b/microkernel/fud.mdwn index 6353f81d..3f9229aa 100644 --- a/microkernel/fud.mdwn +++ b/microkernel/fud.mdwn @@ -11,7 +11,19 @@ This article is a response to an [earlier article](http://www.linuxjournal.com/n Miles Nordin claimed that microkernels are dead already. But this is not completely true. The first generation of microkernels, which were in fact no real microkernels, are dead. But there is a new generation, which uses a radically different strategy than the original (so-called) microkernels. Thus, microkernels are still a research topic, and today they look more promising than ever before. By now, this is just something we claim, but read on, and you'll find out why we do so. -Out of our own experience, we can confirm that the first generation microkernel Mach is quite slow, but being microkernel independent is one of the goals of the Hurd and people are already working on porting the Hurd from Mach to the second generation microkernel L4. Those new second generation kernels aren't as slow as Mach and we think that one should not talk about the performance of microkernel based systems without having read at least some of the papers on L4. The L4 people did some interesting benchmarks, which indicate that one can get a lot of performance by making a microkernel really small. How is this supposed to work? Well, the microkernel provides very primitive, highly optimized operations, and applications use them to implement whichever way of interprocess communication is apropriate for them in an efficient way. By deciding this on a per-case basis, you get optimal performance for all applications. +Out of our own experience, we can confirm that the first generation microkernel +Mach is quite slow, but being microkernel independent is one of the goals of +the Hurd and people are already working on porting the Hurd from Mach to the +second generation microkernel L4. Those new second generation kernels aren't +as slow as Mach and we think that one should not talk about the performance of +microkernel based systems without having read at least some of the papers on +L4. The L4 people did some interesting benchmarks, which indicate that one can +get a lot of performance by making a microkernel really small. How is this +supposed to work? Well, the microkernel provides very primitive, highly +optimized operations, and applications use them to implement whichever way of +inter-process communication is apropriate for them in an efficient way. By +deciding this on a per-case basis, you get optimal performance for all +applications. But L4 takes this even further. For example, you can have schedulers in userspace. Therefore you can use a scheduler which is optimized for the specific tasks your system performs. With the Linux kernel, different schedulers are only possible by using a different source tree, thus you cannot switch at run-time and/or have different schedulers for different groups of processes. diff --git a/microkernel/mach/concepts.mdwn b/microkernel/mach/concepts.mdwn index 04dbb1c6..a9e8897d 100644 --- a/microkernel/mach/concepts.mdwn +++ b/microkernel/mach/concepts.mdwn @@ -1,6 +1,25 @@ -[[Mach]] is a first-generation [[microkernel]]. Mach's basic abstractions -include [[address_space]]s in the form of [[task]]s, execution contexts in the -form of [[thread]]s, [[IPC]], [[capabilities|capability]] in the form of [[port]]s, and -[[memory_object]]s, which enable Mach's [[external_pager_mechanism]]. +[[!meta copyright="Copyright © 2002, 2003, 2007, 2010 Free Software Foundation, +Inc."]] + +[[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable +id="license" text="Permission is granted to copy, distribute and/or modify this +document under the terms of the GNU Free Documentation License, Version 1.2 or +any later version published by the Free Software Foundation; with no Invariant +Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] + +[[Mach]] is a first-generation [[microkernel]]. + +Mach's basic abstractions include [[virtual_address_space]]s in the form of +[[task]]s, execution contexts in the form of [[thread]]s, [[IPC]], +[[capabilities|capability]] in the form of [[port]]s, and [[memory_object]]s, +which enable Mach's [[external_pager_mechanism]]. + +Controlling [[task]]s, their [[virtual_address_space]], [[thread]]s, and other +system objects in Mach is implemented by using [[port]]s, as opposed to other +[[kernel]]s' [[system_call]] interface: almost all of the Mach API is +implemented by sending [[message]]s to [[port]]s. Device drivers that reside +in kernel space are controlled by ports, too. Mach's [[API]] is well-[[documented|documentation]]. diff --git a/microkernel/mach/documentation.mdwn b/microkernel/mach/documentation.mdwn index fc6e59c2..4c6702aa 100644 --- a/microkernel/mach/documentation.mdwn +++ b/microkernel/mach/documentation.mdwn @@ -6,8 +6,10 @@ id="license" text="Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license -is included in the section entitled -[[GNU Free Documentation License|/fdl]]."]]"""]] +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] + + * Mach's [[concepts]]. * [*Meet Mach* by James Scott](http://beefchunk.com/documentation/macosx-programming/Meet_Mach.pdf), diff --git a/microkernel/mach/external_pager_mechanism.mdwn b/microkernel/mach/external_pager_mechanism.mdwn index 2040f4ba..e169495a 100644 --- a/microkernel/mach/external_pager_mechanism.mdwn +++ b/microkernel/mach/external_pager_mechanism.mdwn @@ -9,18 +9,16 @@ Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled [[GNU Free Documentation License|/fdl]]."]]"""]] -Mach provides a so-called external pager [[mechanism]]. This +Mach provides a so-called *external pager [[mechanism]]*. This mechanism serves to separate *managing memory* from *managing -content*. Mach does the former while [[user_space]] [[task]]s do the +content*. Mach does the former while user-space processes do the latter. # Introduction -In Mach, a [[task]]'s [[address_space]] consists of references -to [[memory_object]]s. A memory object is [[designated|designation]] using -a [[port]] (a port is just a [[capability]]) and -implemented by a normal [[process]]. +In Mach, a [[task]]'s [[virtual_address_space]] consists of references to +[[memory_object]]s. To associate a memory object with a portion of a task's address space, `vm_map` is invoked on a capability designating @@ -29,7 +27,7 @@ and the offset at which to install it. (The first time a task maps an object, Mach sends an initialization message to the server including a control capability, which it uses to supply pages to the kernel.) This is essentially -the same as mapping a file into an address space on [[Unix]] +the same as mapping a file into an address space on [[UNIX]] using `mmap`. When a task [[faults|page_fault]], Mach checks to see if there is a memory @@ -86,7 +84,7 @@ structures to manage the mapping and then invokes the mappings in the client's address space and then replies to the `vm_map` RPC indicating success. -There is nothing stopping others from playing "the kernel." This is +There is nothing stopping others from playing *the kernel*. This is not a security problem: clients must [[trust]] the server from whom they obtain memory objects and also the servers with whom they share the object. Multiple memory managers are a reality that should be diff --git a/microkernel/mach/ipc.mdwn b/microkernel/mach/ipc.mdwn index aaf3ba23..1bb44b59 100644 --- a/microkernel/mach/ipc.mdwn +++ b/microkernel/mach/ipc.mdwn @@ -1,22 +1,21 @@ -[[!meta copyright="Copyright © 2007, 2008 Free Software Foundation, Inc."]] +[[!meta copyright="Copyright © 2007, 2008, 2010 Free Software Foundation, +Inc."]] [[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable id="license" text="Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license -is included in the section entitled -[[GNU Free Documentation License|/fdl]]."]]"""]] +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] -[[General_information|/ipc]] about IPC. +Read about the [[general concept of *inter-process communication* (IPC)|/ipc]]. -An IPC is sent by invoking a [[port]]. <!-- Isn't this wording a bit strange? -``IPC is sent'' --tschwinge --> +On Mach, an IPC is done by invoking a [[port]]. + +The two fundamental operations, to *send* and *receive* [[message]]s, are used +to implement a [[RPC]] system. [[Sequence_numbering]]. [The Unofficial GNU Mach IPC beginner's guide](http://www.nongnu.org/hurdextras/ipc_guide/ipc_guide.html) - -# See Also - -* [[RPC]] diff --git a/microkernel/mach/memory_object.mdwn b/microkernel/mach/memory_object.mdwn new file mode 100644 index 00000000..2342145c --- /dev/null +++ b/microkernel/mach/memory_object.mdwn @@ -0,0 +1,31 @@ +[[!meta copyright="Copyright © 2002, 2003, 2010 Free Software Foundation, +Inc."]] + +[[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable +id="license" text="Permission is granted to copy, distribute and/or modify this +document under the terms of the GNU Free Documentation License, Version 1.2 or +any later version published by the Free Software Foundation; with no Invariant +Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] + +Mach's [[virtual_memory]] subsystem uses *memory objects* for supplying the +content of regions of virtual memory in an [[virtual_address_space]]. + +All of these objects are managed by *memory manager*s, that are also called +*pager*s. These can be implemented as user-space processes. + +Both the memory objects, and their managers are kernel objects, and are +accessed by [[port]]s. + +A system's physical memory is conceived as a *memory cache* that contains +*memory cache objects*. So when a [[thread]] accesses a page in its task's +address space, the memory object that includes this page is *cached* in the +memory cache. Memory objects are [[paged out and paged +in|external_pager_mechanism]] by the aforementioned memory managers. The +decision when they should be paged in or paged out is left to [[Mach]]. Each +memory object has an ordered list of memory managers that provide paging. The +last one tried is the *default memory manager* that resides in the microkernel, +in contrast to most of the others. The default memory manager is needed +because the microkernel can't wait infinitely for someone else to free the +memory cache: it just calls the next memory manager hoping it to succeed. diff --git a/microkernel/mach/message.mdwn b/microkernel/mach/message.mdwn new file mode 100644 index 00000000..ba47671e --- /dev/null +++ b/microkernel/mach/message.mdwn @@ -0,0 +1,31 @@ +[[!meta copyright="Copyright © 2002, 2003, 2010 Free Software Foundation, +Inc."]] + +[[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable +id="license" text="Permission is granted to copy, distribute and/or modify this +document under the terms of the GNU Free Documentation License, Version 1.2 or +any later version published by the Free Software Foundation; with no Invariant +Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] + +*Messages* are collections of typed data, with a defined layout. + +They are used for [[IPC]], and are sent to and received from [[port]]s. + +These messages are not only opaque data. They can also contain [[port +rights|port]] to be passed to another [[task]]. Port rights are either +*copied* or *moved*. Notice that port receive right must be moved but not +copied because there can't be more than one task that holds the receive right +to a port. The receiving task creates new local port name to the port rights +it received. + +Some data in the message can be *out-of-line data*. In the message, these are +*references* to memory regions ([[memory_object]]s) that are *virtually +copied*. When the message is received in a task, these virtual copies become +part of the task by mapping them into the receiver's [[virtual_address_space]]. +Another key concept that is applied is using *copy-on-write*, which means that +data is not copied immediately, but only when it is changed. This is primarily +used to send large blocks of data efficiently, as it is too expensive to store +them in the kernel address space: extra copied need only be made at the moment +that the memory regions begin to diverge, by threads modifying them. diff --git a/microkernel/mach/mig.mdwn b/microkernel/mach/mig.mdwn index 4275a4b4..331b3bf4 100644 --- a/microkernel/mach/mig.mdwn +++ b/microkernel/mach/mig.mdwn @@ -1,21 +1,34 @@ -[[!meta copyright="Copyright © 2001, 2002, 2003, 2006, 2007, 2008 Free Software -Foundation, Inc."]] +[[!meta copyright="Copyright © 2001, 2002, 2003, 2006, 2007, 2008, 2010 Free +Software Foundation, Inc."]] [[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable id="license" text="Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license -is included in the section entitled -[[GNU Free Documentation License|/fdl]]."]]"""]] +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] -The Mach Interface Generator (MIG) is an [[IDL]] compiler. Based on an -interface definition, it creates stubs to [[invoke]] object methods -and to demultiplex incoming messages. These stubs conveniently hide -the details of Mach's [[IPC]] machinery and make it easy to implement -and use Mach [[interface]]s as [[remote_procedure_calls_(RPC)|rpc]]. +The *Mach Interface Generator* (*MIG*) is an [[IDL]] compiler. Based on an +interface definition, it creates stub code to [[invoke]] object methods and to +demultiplex incoming messages. These stub functions conveniently hide the +details of Mach's [[IPC]] and [[port]] machinery and make it easy to implement +and use Mach [[interface]]s as [[remote procedure calls (RPC)|rpc]]: by using +the stub functions, the client programs can call remote procedures more or less +like any other C function. + +These functions encode arguments into [[message]]s' format (*marshalling*), +wait for a result on a newly created [[reply port|port]], decode return +arguments from the reply message (*demarshalling*, or *unmarshalling*) and pass +them to the client program. Similar actions are provided in the skeletons that +are linked to server programs. + +MIG allows very precise semantics to be specified about what the arguments are +and how to be passed. + + + * [[Documentation]] -* [[Documentation]] # Implementations diff --git a/microkernel/mach/mig/documentation.mdwn b/microkernel/mach/mig/documentation.mdwn index be762960..7d4f1eca 100644 --- a/microkernel/mach/mig/documentation.mdwn +++ b/microkernel/mach/mig/documentation.mdwn @@ -1,13 +1,13 @@ -[[!meta copyright="Copyright © 2002, 2003, 2005, 2007, 2008, 2009 Free Software -Foundation, Inc."]] +[[!meta copyright="Copyright © 2002, 2003, 2005, 2007, 2008, 2009, 2010 Free +Software Foundation, Inc."]] [[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable id="license" text="Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license -is included in the section entitled -[[GNU Free Documentation License|/fdl]]."]]"""]] +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] This is a small collection of links to external documents describing the *Mach Interface Generator* used by GNU Mach. @@ -17,7 +17,7 @@ Interface Generator* used by GNU Mach. A tutorial which demonstrates the use of the C Threads library primitives in writing a multithreaded program and the use of the Mach Interface Generator -(MIG) to generate remote procedure calls for interprocess communication. Like +(MIG) to generate remote procedure calls for inter-process communication. Like its companion tutorial, it is based on the Mach 2.5 system. However, the concepts are applicable to Mach 3.0 user level programming. @@ -41,9 +41,9 @@ Slides to Rich Drave's talk on MIG, on November 21, 1991: Mig is an implementation of a subset of the Matchmaker **language**. "Matchmaker is a language for specifying and automating the generation of -multilingual interprocess communication interfaces. MIG is an interim +multilingual inter-process communication interfaces. MIG is an interim implementation of a subset of the Matchmaker language that generates C and C++ -remote procedure call interfaces for interprocess communication between Mach +remote procedure call interfaces for inter-process communication between Mach tasks." Richard P. Draves, Michael B. Jones, Mary R. Thompson, *MIG - THE MACH diff --git a/microkernel/mach/mig/gnu_mig.mdwn b/microkernel/mach/mig/gnu_mig.mdwn index 1bcbd545..0de1bd67 100644 --- a/microkernel/mach/mig/gnu_mig.mdwn +++ b/microkernel/mach/mig/gnu_mig.mdwn @@ -1,13 +1,13 @@ -[[!meta copyright="Copyright © 2001, 2006, 2008, 2009 Free Software Foundation, -Inc."]] +[[!meta copyright="Copyright © 2001, 2006, 2008, 2009, 2010 Free Software +Foundation, Inc."]] [[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable id="license" text="Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license -is included in the section entitled -[[GNU Free Documentation License|/fdl]]."]]"""]] +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] GNU MIG is the GNU distribution of the [[Mach_3.0_interface_generator_*MIG*|mig]], as maintained by the GNU Hurd @@ -20,5 +20,9 @@ software in the GNU system that uses Mach-based GNU MIG is fully compatible with [[OSF_MIG|mig]]. +Like its predecessor, it can only generate C code, that has to be compiled and +linked to client and server programs respectively ([[!taglink +open_issue_mig]]). + * [[Building]] - building (and obtaining) GNU MIG * [[Open Issues|tag/open_issue_mig]] diff --git a/microkernel/mach/port.mdwn b/microkernel/mach/port.mdwn index af4a0c8d..ba2e22c2 100644 --- a/microkernel/mach/port.mdwn +++ b/microkernel/mach/port.mdwn @@ -1,41 +1,85 @@ -[[!meta copyright="Copyright © 2007, 2008 Free Software Foundation, Inc."]] +[[!meta copyright="Copyright © 2002, 2003, 2007, 2008, 2010 Free Software +Foundation, Inc."]] [[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable id="license" text="Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license -is included in the section entitled -[[GNU Free Documentation License|/fdl]]."]]"""]] - -Mach ports are [[capabilities|capability]]. - -A Mach port is a kernel queue. Each port has associated with -it a receive right and one or more send and send-once rights. -A queue can hold a number of messages. Once the queue is full, -the send blocks until their is space to enqueue the message -(this is interruptible via a timeout mechanism). - -A receive right designates a queue and authorizes the holder to -dequeue messages from the queue, and to create send and send-once -rights. - -Send and send-once rights designate a queue and authorize the -hold to enqueue messages (in the case of a send-once right, -a single message). Enqueuing a message is equivalent to -[[invoke|invoking]] a capability. - -Send and receive rights are named using local names. Each -task has associated with it a port [[address_space]]. A ports -are addressed via this table. Each task thus has its own -private [[naming_context]] for ports. - -Ports can be [[delegate]]d in an [[IPC]] message. When the -receiver dequeues the message, the right is made available -to it. - -A [[thread]] can only block receiving on a single port. To work -around this, the concept of a port set was introduced. A receive -right can be added to (at most) one port set. When a thread -receives from a port set, it dequeues from any of the ports that -has a message available. +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] + +[[Mach]] *port*s are [[capabilities|capability]], and are also essentially +similar to [[UNIX]] pipes. They are communication channels, implemented by +kernel queues. + +Each port has associated with it one *receive right* and one or more *send +right*s and *send-once right*s. That is, there is one receiver and one or more +senders -- a unidirectional communication channel. Only with the corresponding +port right, access to a port is possible; this is enforced by Mach. + +The kernel queue can hold a number of [[message]]s. Once the queue is full, +the send blocks until there is space to enqueue the message (this is +interruptible via a timeout mechanism). + +A receive right [[designates|designation]] a queue and authorizes the holder to +dequeue messages from the queue, and to create send and send-once rights. + +Send and send-once rights designate a queue and authorize the hold to enqueue +messages (in the case of a send-once right, a single message). Enqueuing a +message is equivalent to [[invoke|invoking]] a capability. + +Ports are automatically destroyed when there is no associated port right to +them. + +Mach knows what port rights belong to each task, but [[thread]]s that running +in the context of a task refer to ports by means of send and receive rights +that are named using local *port names*. These port names are plain integers, +like [[UNIX file descriptors|unix/file_descriptor]]. Only these local names +can be used by [[thread]]s for invoking operations on ports, threads do not +deal with port rights directly. + +For that, each task has associated with it a *port address_space*, or *port +name space*. All ports are addressed via this table. Each task thus has its +own private [[naming_context]] for port rights. + +So, the picture is that after obtaining a port send right, the client uses a +port name to send [[message]]s to the port, or exactly one message if it's a +send-once right. These messages are (probably) queued and when the server task +tries to receive messages by having a [[thread]] use its port receive right, it +gets the message(s). This is called [[IPC]]. + +Port rights themselvse can be [[delegate]]d in a [[message]], too. When the +receiver dequeues the message, the right is made available to it. + +The delivery of [[message]]s is reliable and strictly ordered. When a +[[thread]] sends messages *1* and *2*, it is guaranteed that the receiving +[[task]] will catch them in the same order. Of course, there can be +intermediate messages that are sent by other threads. + +Ports are objects that are implemented by the [[kernel]], and they are +kernel-protected resources. There is no way for a [[task]] to do anything with +a port unless it have corresponding port right. + +Due to this, ports are globally unique. This makes them ideal for constituting +system-wide *object references*. For example, the [[RPC]] system as used by +the GNU Hurd works by invoking *methods* on such object references. The +available methods are defined in [[hurd/interface]] files, and are processes by +the [[MIG]] tool. + +Invoking an operation on a port does not transfer the current execution control +to the receiver, but instead is an asynchronous operation. For this, and +especially in a [[RPC]] system, the sender may include a *reply port* using a +send-once right, and synchronize (block) on that one. + +A [[thread]] can only block receiving on a single port. To work around this, +the concept of a *port set* was introduced. A receive right can be added to +(at most) one port set. These port sets look like port receive rights, but +cannot be passed to other tasks, and there are additional operations for adding +and removing port receive rights. + +When a server process' thread receives from a port set, it dequeues exactly one +message from any of the ports that has a message available in its queue. + +This concept of port sets is also the facility that makes convenient +implementation of [[UNIX]]'s `select` [[system_call]] possible. diff --git a/microkernel/mach/rpc.mdwn b/microkernel/mach/rpc.mdwn index 72acfaa0..60275a86 100644 --- a/microkernel/mach/rpc.mdwn +++ b/microkernel/mach/rpc.mdwn @@ -1,15 +1,21 @@ -[[!meta copyright="Copyright © 2007, 2008 Free Software Foundation, Inc."]] +[[!meta copyright="Copyright © 2002, 2003, 2007, 2008, 2010 Free Software +Foundation, Inc."]] [[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable id="license" text="Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license -is included in the section entitled -[[GNU Free Documentation License|/fdl]]."]]"""]] +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] -[[General_information|/rpc]] about RPC. +Read about the [[general concept of a *remote procedure call* (RPC)|/rpc]]. Uses Mach's [[IPC]] [[mechanism]]. -Stub code generated by [[MIG]]. +The [[port]] abstraction allows RPCs to be executed on another computer +transparently. This can be implemented with user [[task]]s, but there is an +implementation in the kernel possible, too, which is called *NORMA*, but is not +avilable in [[GNU Mach|gnumach]]. + +The RPC stub code generated by [[MIG]]. diff --git a/microkernel/mach/task.mdwn b/microkernel/mach/task.mdwn new file mode 100644 index 00000000..c03c6a14 --- /dev/null +++ b/microkernel/mach/task.mdwn @@ -0,0 +1,23 @@ +[[!meta copyright="Copyright © 2002, 2003, 2010 Free Software Foundation, +Inc."]] + +[[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable +id="license" text="Permission is granted to copy, distribute and/or modify this +document under the terms of the GNU Free Documentation License, Version 1.2 or +any later version published by the Free Software Foundation; with no Invariant +Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] + +A Mach *task* is a collection of resources, a [[virtual_address_space]], and a +[[port name space|port]]. They depend on [[thread]]s for executing program +code: a task alone has no means to do so. + +Switching from one task to another one involves doing a *context switch*, which +is usually not a cheap operation, as it involves switching the hardware's idea +of the memory layout ([[virtual_address_space]]), amongst others. + +Mach tasks are distinct from [[UNIX processes|unix/process]] in that they +provide less facilities. In processes, there are [[unix/signal]]s, process / +group / session IDs, [[unix/file_descriptor]]s and many other things. Tasks +are used for resource allocation and sharing; they are *resource container*s. diff --git a/microkernel/mach/thread.mdwn b/microkernel/mach/thread.mdwn new file mode 100644 index 00000000..e27bb117 --- /dev/null +++ b/microkernel/mach/thread.mdwn @@ -0,0 +1,37 @@ +[[!meta copyright="Copyright © 2002, 2003, 2010 Free Software Foundation, +Inc."]] + +[[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable +id="license" text="Permission is granted to copy, distribute and/or modify this +document under the terms of the GNU Free Documentation License, Version 1.2 or +any later version published by the Free Software Foundation; with no Invariant +Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] + +A Mach *thread* belongs to exactly one [[task]], and is the means of execution. +The task supplies the resources. + +Mach threads are implemented inside the [[kernel]], as opposed to other +systems' user-level thread packages. + +A thread (theoretically) runs concurrently with all the other threads of a +system. If the system provides several processors, they can be used for +simultaneously running either several threads of the same task, or several +threads of different tasks. <!-- This is called SMP; the processors use +*shared memory*. --> [[!tag open_issue_documentation]] <!-- This needs a new +page, also covering Mach's `processor_set`s, and non-SMP, but still +multiprocessor systems. --> (But this is currently not support in [[GNU +Mach|gnumach]].) + +It is easy for the kernel to switch execution from one thread to another one +inside the same task: essentially, it only involves exchanging a few processor +registers' state. + +Threads have scheduling parameters and maintain various statistics about +themselves. + +On GNU/Hurd, APIs for Mach threads and thereabouts are provided by the +[[hurd/libthreads]] (cthreads), and [[libpthread]] (POSIX Threads) packages. + +A task backing a thread is the basis for a [[UNIX process|unix/process]]. diff --git a/microkernel/mach/virtual_address_space.mdwn b/microkernel/mach/virtual_address_space.mdwn new file mode 100644 index 00000000..97bc5f6b --- /dev/null +++ b/microkernel/mach/virtual_address_space.mdwn @@ -0,0 +1,36 @@ +[[!meta copyright="Copyright © 2002, 2003, 2010 Free Software Foundation, +Inc."]] + +[[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable +id="license" text="Permission is granted to copy, distribute and/or modify this +document under the terms of the GNU Free Documentation License, Version 1.2 or +any later version published by the Free Software Foundation; with no Invariant +Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license +is included in the section entitled [[GNU Free Documentation +License|/fdl]]."]]"""]] + +*Virtual address space*s in Mach define the valid virtual addresses that can be +used by [[thread]]s under execution in the [[task]] that owns that address +space. Each task has only one address space and each address space belongs to +only one task. So when we want to name an address space (for example, in the +Mach API) we name it by the task it belongs to. + +These address spaces are divided into *pages*. Each page has individual +properties like *access rights* (*read* / *write* / *execute*), *inheritance +attributes* (*no inheritance* / *copy* / *share*) and some other system +properties. Page manipulation is optimized to help moving large blocks of data +from one address space to another, for example when one thread provides data to +another thread -- *client / server* technology. + +Memory ranges of pages that can be controlled as a whole are called +*[[memory_object]]*s. + +*Wired pages* are those that cannot be [[paged out|external_pager_mechanism]]. +For example, Mach itself is a task with its own address space and threads, and +all of its pages are wired. + +*Precious pages* are those that must not be discarded silently when they are +clean and memory is needed. For example, a memory manager that shares memory +across a network could not restore a page if it is silently discarded because +it is unmodified. This is not valid for the well-known [[pager +managers|external_pager_mechanism]] that use disks as backing store. |