Annotation of Gnu-Mach/doc/mach.info-1, revision 1.1

1.1     ! root        1: This is mach.info, produced by makeinfo version 5.1 from mach.texi.
        !             2: 
        !             3: This file documents the GNU Mach microkernel.
        !             4: 
        !             5:    This is edition 0.4, last updated on 27 September 2013, of 'The GNU
        !             6: Mach Reference Manual', for version 1.4.
        !             7: 
        !             8:    Copyright (C) 2001, 2002, 2006, 2007, 2008 Free Software Foundation,
        !             9: Inc.
        !            10: 
        !            11:      Permission is granted to copy, distribute and/or modify this
        !            12:      document under the terms of the GNU Free Documentation License,
        !            13:      Version 1.2 or any later version published by the Free Software
        !            14:      Foundation; with no Invariant Section, with no Front-Cover Texts,
        !            15:      and with no Back-Cover Texts.  A copy of the license is included in
        !            16:      the section entitled "GNU Free Documentation License".
        !            17: 
        !            18:      This work is based on manual pages under the following copyright
        !            19:      and license:
        !            20: 
        !            21:      Mach Operating System
        !            22:      Copyright (C) 1991,1990 Carnegie Mellon University
        !            23:      All Rights Reserved.
        !            24: 
        !            25:      Permission to use, copy, modify and distribute this software and
        !            26:      its documentation is hereby granted, provided that both the
        !            27:      copyright notice and this permission notice appear in all copies of
        !            28:      the software, derivative works or modified versions, and any
        !            29:      portions thereof, and that both notices appear in supporting
        !            30:      documentation.
        !            31: 
        !            32:      CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            33:      CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            34:      ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            35: INFO-DIR-SECTION Kernel
        !            36: START-INFO-DIR-ENTRY
        !            37: * GNUMach: (mach).              Using and programming the GNU Mach microkernel.
        !            38: END-INFO-DIR-ENTRY
        !            39: 
        !            40: 
        !            41: File: mach.info,  Node: Top,  Next: Introduction,  Up: (dir)
        !            42: 
        !            43: Main Menu
        !            44: *********
        !            45: 
        !            46: This file documents the GNU Mach microkernel.
        !            47: 
        !            48:    This is edition 0.4, last updated on 27 September 2013, of 'The GNU
        !            49: Mach Reference Manual', for version 1.4.
        !            50: 
        !            51:    Copyright (C) 2001, 2002, 2006, 2007, 2008 Free Software Foundation,
        !            52: Inc.
        !            53: 
        !            54:      Permission is granted to copy, distribute and/or modify this
        !            55:      document under the terms of the GNU Free Documentation License,
        !            56:      Version 1.2 or any later version published by the Free Software
        !            57:      Foundation; with no Invariant Section, with no Front-Cover Texts,
        !            58:      and with no Back-Cover Texts.  A copy of the license is included in
        !            59:      the section entitled "GNU Free Documentation License".
        !            60: 
        !            61:      This work is based on manual pages under the following copyright
        !            62:      and license:
        !            63: 
        !            64:      Mach Operating System
        !            65:      Copyright (C) 1991,1990 Carnegie Mellon University
        !            66:      All Rights Reserved.
        !            67: 
        !            68:      Permission to use, copy, modify and distribute this software and
        !            69:      its documentation is hereby granted, provided that both the
        !            70:      copyright notice and this permission notice appear in all copies of
        !            71:      the software, derivative works or modified versions, and any
        !            72:      portions thereof, and that both notices appear in supporting
        !            73:      documentation.
        !            74: 
        !            75:      CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            76:      CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            77:      ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            78: 
        !            79: * Menu:
        !            80: 
        !            81: * Introduction::                  How to use this manual.
        !            82: * Installing::                    Setting up GNU Mach on your computer.
        !            83: * Bootstrap::                     Running GNU Mach on your machine.
        !            84: * Inter Process Communication::   Communication between process.
        !            85: * Virtual Memory Interface::      Allocating and deallocating virtual memory.
        !            86: * External Memory Management::    Handling memory pages in user space.
        !            87: * Threads and Tasks::             Handling of threads and tasks.
        !            88: * Host Interface::                Interface to a Mach host.
        !            89: * Processors and Processor Sets:: Handling processors and sets of processors.
        !            90: * Device Interface::              Accessing kernel devices.
        !            91: * Kernel Debugger::               How to use the built-in kernel debugger.
        !            92: 
        !            93: Appendices
        !            94: 
        !            95: * Copying::                       The GNU General Public License says how you
        !            96:                                   can copy and share the GNU Mach microkernel.
        !            97: * Documentation License::         This manual is under the GNU Free
        !            98:                                   Documentation License.
        !            99: 
        !           100: Indices
        !           101: 
        !           102: * Concept Index::                 Index of concepts and programs.
        !           103: * Function and Data Index::       Index of functions, variables and data types.
        !           104: 
        !           105: 
        !           106:  -- The Detailed Node Listing --
        !           107: 
        !           108: Introduction
        !           109: 
        !           110: * Audience::                      The people for whom this manual is written.
        !           111: * Features::                      Reasons to install and use GNU Mach.
        !           112: * Overview::                      Basic architecture of the Mach microkernel.
        !           113: * History::                       The story about Mach.
        !           114: 
        !           115: Installing
        !           116: 
        !           117: * Binary Distributions::          Obtaining ready-to-run GNU distributions.
        !           118: * Compilation::                   Building GNU Mach from its source code.
        !           119: * Configuration::                 Configuration options at compilation time.
        !           120: * Cross-Compilation::             Building GNU Mach from another system.
        !           121: 
        !           122: Bootstrap
        !           123: 
        !           124: * Bootloader::                    Starting the microkernel, or other OSes.
        !           125: * Modules::                       Starting the first task of the OS.
        !           126: 
        !           127: Inter Process Communication
        !           128: 
        !           129: * Major Concepts::                The concepts behind the Mach IPC system.
        !           130: * Messaging Interface::           Composing, sending and receiving messages.
        !           131: * Port Manipulation Interface::   Manipulating ports, port rights, port sets.
        !           132: 
        !           133: Messaging Interface
        !           134: 
        !           135: * Mach Message Call::             Sending and receiving messages.
        !           136: * Message Format::                The format of Mach messages.
        !           137: * Exchanging Port Rights::        Sending and receiving port rights.
        !           138: * Memory::                        Passing memory regions in messages.
        !           139: * Message Send::                  Sending messages.
        !           140: * Message Receive::               Receiving messages.
        !           141: * Atomicity::                     Atomicity of port rights.
        !           142: 
        !           143: Port Manipulation Interface
        !           144: 
        !           145: * Port Creation::                 How to create new ports and port sets.
        !           146: * Port Destruction::              How to destroy ports and port sets.
        !           147: * Port Names::                    How to query and manipulate port names.
        !           148: * Port Rights::                   How to work with port rights.
        !           149: * Ports and other Tasks::         How to move rights between tasks.
        !           150: * Receive Rights::                How to work with receive rights.
        !           151: * Port Sets::                     How to work with port sets.
        !           152: * Request Notifications::         How to request notifications for events.
        !           153: 
        !           154: Virtual Memory Interface
        !           155: 
        !           156: * Memory Allocation::             Allocation of new virtual memory.
        !           157: * Memory Deallocation::           Freeing unused virtual memory.
        !           158: * Data Transfer::                 Reading, writing and copying memory.
        !           159: * Memory Attributes::             Tweaking memory regions.
        !           160: * Mapping Memory Objects::        How to map memory objects.
        !           161: * Memory Statistics::             How to get statistics about memory usage.
        !           162: 
        !           163: External Memory Management
        !           164: 
        !           165: * Memory Object Server::          The basics of external memory management.
        !           166: * Memory Object Creation::        How new memory objects are created.
        !           167: * Memory Object Termination::     How memory objects are terminated.
        !           168: * Memory Objects and Data::       Data transfer to and from memory objects.
        !           169: * Memory Object Locking::         How memory objects are locked.
        !           170: * Memory Object Attributes::      Manipulating attributes of memory objects.
        !           171: * Default Memory Manager::        Setting and using the default memory manager.
        !           172: 
        !           173: Threads and Tasks
        !           174: 
        !           175: * Thread Interface::              Manipulating threads.
        !           176: * Task Interface::                Manipulating tasks.
        !           177: * Profiling::                     Profiling threads and tasks.
        !           178: 
        !           179: Thread Interface
        !           180: 
        !           181: * Thread Creation::               Creating threads.
        !           182: * Thread Termination::            Terminating threads.
        !           183: * Thread Information::            How to get informations on threads.
        !           184: * Thread Settings::               How to set threads related informations.
        !           185: * Thread Execution::              How to control the thread's machine state.
        !           186: * Scheduling::                    Operations on thread scheduling.
        !           187: * Thread Special Ports::          How to handle the thread's special ports.
        !           188: * Exceptions::                    Managing exceptions.
        !           189: 
        !           190: Scheduling
        !           191: 
        !           192: * Thread Priority::               Changing the priority of a thread.
        !           193: * Hand-Off Scheduling::           Switch to a new thread.
        !           194: * Scheduling Policy::             Setting the scheduling policy.
        !           195: 
        !           196: Task Interface
        !           197: 
        !           198: * Task Creation::                 Creating tasks.
        !           199: * Task Termination::              Terminating tasks.
        !           200: * Task Information::              Informations on tasks.
        !           201: * Task Execution::                Thread scheduling in a task.
        !           202: * Task Special Ports::            How to get and set the task's special ports.
        !           203: * Syscall Emulation::             How to emulate system calls.
        !           204: 
        !           205: Host Interface
        !           206: 
        !           207: * Host Ports::                    Ports representing a host.
        !           208: * Host Information::              Query information about a host.
        !           209: * Host Time::                     Functions to query manipulate the host time.
        !           210: * Host Reboot::                   Rebooting the system.
        !           211: 
        !           212: Processors and Processor Sets
        !           213: 
        !           214: * Processor Set Interface::       How to work with processor sets.
        !           215: * Processor Interface::           How to work with individual processors.
        !           216: 
        !           217: Processor Set Interface
        !           218: 
        !           219: * Processor Set Ports::           Ports representing a processor set.
        !           220: * Processor Set Access::          How the processor sets are accessed.
        !           221: * Processor Set Creation::        How new processor sets are created.
        !           222: * Processor Set Destruction::     How processor sets are destroyed.
        !           223: * Tasks and Threads on Sets::     Assigning tasks or threads to processor sets.
        !           224: * Processor Set Priority::        Specifying the priority of a processor set.
        !           225: * Processor Set Policy::          Changing the processor set policies.
        !           226: * Processor Set Info::            Obtaining information about a processor set.
        !           227: 
        !           228: Processor Interface
        !           229: 
        !           230: * Hosted Processors::             Getting a list of all processors on a host.
        !           231: * Processor Control::             Starting, stopping, controlling processors.
        !           232: * Processors and Sets::           Combining processors into processor sets.
        !           233: * Processor Info::                Obtaining information on processors.
        !           234: 
        !           235: Device Interface
        !           236: 
        !           237: * Device Open::                   Opening hardware devices.
        !           238: * Device Close::                  Closing hardware devices.
        !           239: * Device Read::                   Reading data from the device.
        !           240: * Device Write::                  Writing data to the device.
        !           241: * Device Map::                    Mapping devices into virtual memory.
        !           242: * Device Status::                 Querying and manipulating a device.
        !           243: * Device Filter::                 Filtering packets arriving on a device.
        !           244: 
        !           245: Kernel Debugger
        !           246: 
        !           247: * Operation::                     Basic architecture of the kernel debugger.
        !           248: * Commands::                      Available commands in the kernel debugger.
        !           249: * Variables::                     Access of variables from the kernel debugger.
        !           250: * Expressions::                   Usage of expressions in the kernel debugger.
        !           251: 
        !           252: Documentation License
        !           253: 
        !           254: * GNU Free Documentation License:: The GNU Free Documentation License.
        !           255: * CMU License::                   The CMU license applies to the original Mach
        !           256:                                   kernel and its documentation.
        !           257: 
        !           258: 
        !           259: 
        !           260: File: mach.info,  Node: Introduction,  Next: Installing,  Prev: Top,  Up: Top
        !           261: 
        !           262: 1 Introduction
        !           263: **************
        !           264: 
        !           265: GNU Mach is the microkernel of the GNU Project.  It is the base of the
        !           266: operating system, and provides its functionality to the Hurd servers,
        !           267: the GNU C Library and all user applications.  The microkernel itself
        !           268: does not provide much functionality of the system, just enough to make
        !           269: it possible for the Hurd servers and the C library to implement the
        !           270: missing features you would expect from a POSIX compatible operating
        !           271: system.
        !           272: 
        !           273: * Menu:
        !           274: 
        !           275: * Audience::                      The people for whom this manual is written.
        !           276: * Features::                      Reasons to install and use GNU Mach.
        !           277: * Overview::                      Basic architecture of the Mach microkernel.
        !           278: * History::                       The story about Mach.
        !           279: 
        !           280: 
        !           281: File: mach.info,  Node: Audience,  Next: Features,  Up: Introduction
        !           282: 
        !           283: 1.1 Audience
        !           284: ============
        !           285: 
        !           286: This manual is designed to be useful to everybody who is interested in
        !           287: using, administering, or programming the Mach microkernel.
        !           288: 
        !           289:    If you are an end-user and you are looking for help on running the
        !           290: Mach kernel, the first few chapters of this manual describe the
        !           291: essential parts of installing and using the kernel in the GNU operating
        !           292: system.
        !           293: 
        !           294:    The rest of this manual is a technical discussion of the Mach
        !           295: programming interface and its implementation, and would not be helpful
        !           296: until you want to learn how to extend the system or modify the kernel.
        !           297: 
        !           298:    This manual is organized according to the subsystems of Mach, and
        !           299: each chapter begins with descriptions of conceptual ideas that are
        !           300: related to that subsystem.  If you are a programmer and want to learn
        !           301: more about, say, the Mach IPC subsystem, you can skip to the IPC chapter
        !           302: (*note Inter Process Communication::), and read about the related
        !           303: concepts and interface definitions.
        !           304: 
        !           305: 
        !           306: File: mach.info,  Node: Features,  Next: Overview,  Prev: Audience,  Up: Introduction
        !           307: 
        !           308: 1.2 Features
        !           309: ============
        !           310: 
        !           311: GNU Mach is not the most advanced microkernel known to the planet, nor
        !           312: is it the fastest or smallest, but it has a rich set of interfaces and
        !           313: some features which make it useful as the base of the Hurd system.
        !           314: 
        !           315: it's free software
        !           316:      Anybody can use, modify, and redistribute it under the terms of the
        !           317:      GNU General Public License (*note Copying::).  GNU Mach is part of
        !           318:      the GNU system, which is a complete operating system licensed under
        !           319:      the GPL.
        !           320: 
        !           321: it's built to survive
        !           322:      As a microkernel, GNU Mach doesn't implement a lot of the features
        !           323:      commonly found in an operating system, but only the bare minimum
        !           324:      that is required to implement a full operating system on top of it.
        !           325:      This means that a lot of the operating system code is maintained
        !           326:      outside of GNU Mach, and while this code may go through a complete
        !           327:      redesign, the code of the microkernel can remain comparatively
        !           328:      stable.
        !           329: 
        !           330: it's scalable
        !           331:      Mach is particularly well suited for SMP and network cluster
        !           332:      techniques.  Thread support is provided at the kernel level, and
        !           333:      the kernel itself takes advantage of that.  Network transparency at
        !           334:      the IPC level makes resources of the system available across
        !           335:      machine boundaries (with NORMA IPC, currently not available in GNU
        !           336:      Mach).
        !           337: 
        !           338: it exists
        !           339:      The Mach microkernel is real software that works Right Now.  It is
        !           340:      not a research or a proposal.  You don't have to wait at all before
        !           341:      you can start using and developing it.  Mach has been used in many
        !           342:      operating systems in the past, usually as the base for a single
        !           343:      UNIX server.  In the GNU system, Mach is the base of a functional
        !           344:      multi-server operating system, the Hurd.
        !           345: 
        !           346: 
        !           347: File: mach.info,  Node: Overview,  Next: History,  Prev: Features,  Up: Introduction
        !           348: 
        !           349: 1.3 Overview
        !           350: ============
        !           351: 
        !           352: An operating system kernel provides a framework for programs to share a
        !           353: computer's hardware resources securely and efficiently.  This requires
        !           354: that the programs are separated and protected from each other.  To make
        !           355: running multiple programs in parallel useful, there also needs to be a
        !           356: facility for programs to exchange information by communication.
        !           357: 
        !           358:    The Mach microkernel provides abstractions of the underlying hardware
        !           359: resources like devices and memory.  It organizes the running programs
        !           360: into tasks and threads (points of execution in the tasks).  In addition,
        !           361: Mach provides a rich interface for inter-process communication.
        !           362: 
        !           363:    What Mach does not provide is a POSIX compatible programming
        !           364: interface.  In fact, it has no understanding of file systems, POSIX
        !           365: process semantics, network protocols and many more.  All this is
        !           366: implemented in tasks running on top of the microkernel.  In the GNU
        !           367: operating system, the Hurd servers and the C library share the
        !           368: responsibility to implement the POSIX interface, and the additional
        !           369: interfaces which are specific to the GNU system.
        !           370: 
        !           371: 
        !           372: File: mach.info,  Node: History,  Prev: Overview,  Up: Introduction
        !           373: 
        !           374: 1.4 History
        !           375: ===========
        !           376: 
        !           377: XXX A few lines about the history of Mach here.
        !           378: 
        !           379: 
        !           380: File: mach.info,  Node: Installing,  Next: Bootstrap,  Prev: Introduction,  Up: Top
        !           381: 
        !           382: 2 Installing
        !           383: ************
        !           384: 
        !           385: Before you can use the Mach microkernel in your system you'll need to
        !           386: install it and all components you want to use with it, e.g.  the rest of
        !           387: the operating system.  You also need a bootloader to load the kernel
        !           388: from the storage medium and run it when the computer is started.
        !           389: 
        !           390:    GNU Mach is only available for Intel i386-compatible architectures
        !           391: (such as the Pentium) currently.  If you have a different architecture
        !           392: and want to run the GNU Mach microkernel, you will need to port the
        !           393: kernel and all other software of the system to your machine's
        !           394: architecture.  Porting is an involved process which requires
        !           395: considerable programming skills, and it is not recommended for the
        !           396: faint-of-heart.  If you have the talent and desire to do a port, contact
        !           397: <[email protected]> in order to coordinate the effort.
        !           398: 
        !           399: * Menu:
        !           400: 
        !           401: * Binary Distributions::          Obtaining ready-to-run GNU distributions.
        !           402: * Compilation::                   Building GNU Mach from its source code.
        !           403: * Configuration::                 Configuration options at compile time.
        !           404: * Cross-Compilation::             Building GNU Mach from another system.
        !           405: 
        !           406: 
        !           407: File: mach.info,  Node: Binary Distributions,  Next: Compilation,  Up: Installing
        !           408: 
        !           409: 2.1 Binary Distributions
        !           410: ========================
        !           411: 
        !           412: By far the easiest and best way to install GNU Mach and the operating
        !           413: system is to obtain a GNU binary distribution.  The GNU operating system
        !           414: consists of GNU Mach, the Hurd, the C library and many applications.
        !           415: Without the GNU operating system, you will only have a microkernel,
        !           416: which is not very useful by itself, without the other programs.
        !           417: 
        !           418:    Building the whole operating system takes a huge effort, and you are
        !           419: well advised to not do it yourself, but to get a binary distribution of
        !           420: the GNU operating system.  The distribution also includes a binary of
        !           421: the GNU Mach microkernel.
        !           422: 
        !           423:    Information on how to obtain the GNU system can be found in the Hurd
        !           424: info manual.
        !           425: 
        !           426: 
        !           427: File: mach.info,  Node: Compilation,  Next: Configuration,  Prev: Binary Distributions,  Up: Installing
        !           428: 
        !           429: 2.2 Compilation
        !           430: ===============
        !           431: 
        !           432: If you already have a running GNU system, and only want to recompile the
        !           433: kernel, for example to select a different set of included hardware
        !           434: drivers, you can easily do this.  You need the GNU C compiler and MIG,
        !           435: the Mach interface generator, which both come in their own packages.
        !           436: 
        !           437:    Building and installing the kernel is as easy as with any other GNU
        !           438: software package.  The configure script is used to configure the source
        !           439: and set the compile time options.  The compilation is done by running:
        !           440: 
        !           441:      make
        !           442: 
        !           443:    To install the kernel and its header files, just enter the command:
        !           444: 
        !           445:      make install
        !           446: 
        !           447:    This will install the kernel as 'EXEC_PREFIX/boot/gnumach', the
        !           448: header files into 'PREFIX/include/', the list of message ids as
        !           449: 'PREFIX/share/msgids/gnumach.msgids' and the documentation into
        !           450: 'PREFIX/share/info/'.
        !           451: 
        !           452:    Note that there is also a way to only install the header and
        !           453: documentation files without having to actually build the whole package:
        !           454: run 'make install-data' after having ran 'configure' to do so.  (This is
        !           455: needed for bootstrapping a cross compiler and similar procedures.)
        !           456: 
        !           457: 
        !           458: File: mach.info,  Node: Configuration,  Next: Cross-Compilation,  Prev: Compilation,  Up: Installing
        !           459: 
        !           460: 2.3 Configuration
        !           461: =================
        !           462: 
        !           463: See the following tables for the options can be passed to the
        !           464: 'configure' script as command line arguments to control what components
        !           465: are built into the kernel, how certain things are configured and so on.
        !           466: 
        !           467:    See the top-level 'INSTALL' file for information about generic
        !           468: 'configure' options, like under which paths to install the package's
        !           469: components.  It also describes how to control the process by setting
        !           470: environment variables.
        !           471: 
        !           472:    The file 'i386/README-Drivers' has some i386-specific information for
        !           473: device drivers.  You should only need to consult this file in case a
        !           474: device driver is not working for you.
        !           475: 
        !           476: 2.3.1 Table of configure switches not related to device drivers
        !           477: ---------------------------------------------------------------
        !           478: 
        !           479: '--enable-kdb'
        !           480:      In-kernel debugger.  This is only useful if you actually anticipate
        !           481:      debugging the kernel.  It is not enabled by default because it adds
        !           482:      considerably to the unpageable memory footprint of the kernel.
        !           483:      *Note Kernel Debugger::.
        !           484: 
        !           485: '--enable-pae'
        !           486:      PAE (Physical Address Extension) feature ('ix86'-only), which is
        !           487:      available on modern 'ix86' processors; on 'ix86-at' disabled by
        !           488:      default, on 'ix86-xen' enabled by default.
        !           489: 
        !           490: 2.3.2 Turning device drivers on or off
        !           491: --------------------------------------
        !           492: 
        !           493: Each device driver has an associated configure switch.  The following
        !           494: table indicates whether a device driver is enabled by default or not.
        !           495: It also gives -- if possible at all -- the configure switches to use for
        !           496: disabling or enabling device drivers, in case you're not satisfied with
        !           497: the default choices.  You can specify '--enable-device-drivers=WHICH'
        !           498: (where WHICH on 'ix86-at' must be one of 'default', 'qemu', 'none') to
        !           499: preset a certain subset of all available device drivers.
        !           500: '--enable-device-drivers' is sugar for '--enable-device-drivers=default'
        !           501: (and is the implicit default nevertheless) and
        !           502: '--disable-device-drivers' is short for '--enable-device-drivers=none'.
        !           503: 'qemu' will include only the set of device drivers that is useful when
        !           504: using the resulting kernel binary to drive a Hurd system in the QEMU
        !           505: system emulator.  This is only useful for reducing the kernel build time
        !           506: and the kernel image size.
        !           507: 
        !           508: 2.3.3 What the configure switches do
        !           509: ------------------------------------
        !           510: 
        !           511: Each configure switch has two effects.  First, it defines a CPP symbol
        !           512: that turns on or off the hooks that autoconfigure the device and add it
        !           513: to the list of available devices.  Second, it adds the source code for
        !           514: the driver to a make variable so that the code for the driver is
        !           515: compiled and linked into the kernel.  Also follow this route to find the
        !           516: file(s) which are implementing a certain device driver.
        !           517: 
        !           518: 2.3.4 Table of configure switches related to device drivers
        !           519: -----------------------------------------------------------
        !           520: 
        !           521: ('%d' in the following denotes a unit number, starting with '0'.)
        !           522: 
        !           523: '--disable-kmsg'
        !           524:      Kernel message device 'kmsg'.
        !           525: 
        !           526: '--enable-lpr'
        !           527:      Parallel port device driver for the 'lpr%d' devices.  On 'ix86-at'
        !           528:      enabled by 'default'.
        !           529: 
        !           530: '--enable-floppy'
        !           531:      PC floppy disk controller device driver for the 'fd%d' devices.  On
        !           532:      'ix86-at' enabled by 'default' and for 'qemu'.
        !           533: 
        !           534: '--enable-ide'
        !           535:      IDE controller device driver for the 'hd%d' and 'hd%ds%d' (disks
        !           536:      and their partitions) devices.  On 'ix86-at' enabled by 'default'
        !           537:      and for 'qemu'.
        !           538: 
        !           539:    The following options control drivers for various SCSI controller.
        !           540: SCSI devices are named 'sd%d' and 'sd%ds$d' (disks and their partitions)
        !           541: or 'cd%d' (CD ROMs).
        !           542: 
        !           543: '--enable-advansys'
        !           544:      AdvanSys SCSI controller device driver.  On 'ix86-at' enabled by
        !           545:      'default'.
        !           546: 
        !           547: '--enable-buslogic'
        !           548:      BusLogic SCSI controller device driver.  On 'ix86-at' enabled by
        !           549:      'default'.
        !           550: 
        !           551: '--enable-flashpoint'
        !           552:      Only meaningful in conjunction with the above BusLogic SCSI
        !           553:      controller device driver.  Enable the FlashPoint support.
        !           554: 
        !           555: '--enable-u14-34f'
        !           556:      UltraStor 14F/34F SCSI controller device driver.  On 'ix86-at'
        !           557:      enabled by 'default'.
        !           558: 
        !           559: '--enable-ultrastor'
        !           560:      UltraStor SCSI controller device driver.  On 'ix86-at' enabled by
        !           561:      'default'.
        !           562: 
        !           563: '--enable-aha152x'
        !           564:      Adaptec AHA-152x/2825 SCSI controller device driver.  On 'ix86-at'
        !           565:      enabled by 'default'.
        !           566: 
        !           567: '--enable-aha1542'
        !           568:      Adaptec AHA-1542 SCSI controller device driver.  On 'ix86-at'
        !           569:      enabled by 'default'.
        !           570: 
        !           571: '--enable-aha1740'
        !           572:      Adaptec AHA-1740 SCSI controller device driver.  On 'ix86-at'
        !           573:      enabled by 'default'.
        !           574: 
        !           575: '--enable-aic7xxx'
        !           576:      Adaptec AIC7xxx SCSI controller device driver.  On 'ix86-at'
        !           577:      enabled by 'default'.
        !           578: 
        !           579: '--enable-fdomain'
        !           580:      Future Domain 16xx SCSI controller device driver.  On 'ix86-at'
        !           581:      enabled by 'default'.
        !           582: 
        !           583: '--enable-in2000'
        !           584:      Always IN 2000 SCSI controller device driver.  On 'ix86-at' enabled
        !           585:      by 'default'.
        !           586: 
        !           587: '--enable-g_NCR5380'
        !           588:      Generic NCR5380/53c400 SCSI controller device driver.
        !           589: 
        !           590: '--enable-NCR53c406a'
        !           591:      NCR53c406a SCSI controller device driver.
        !           592: 
        !           593: '--enable-pas16'
        !           594:      PAS16 SCSI controller device driver.  On 'ix86-at' enabled by
        !           595:      'default'.
        !           596: 
        !           597: '--enable-seagate'
        !           598:      Seagate ST02 and Future Domain TMC-8xx SCSI controller device
        !           599:      driver.  On 'ix86-at' enabled by 'default'.
        !           600: 
        !           601: '--enable-t128'
        !           602:      Trantor T128/T128F/T228 SCSI controller device driver.  On
        !           603:      'ix86-at' enabled by 'default'.
        !           604: 
        !           605: '--enable-53c78xx'
        !           606:      NCR53C7,8xx SCSI controller device driver.  On 'ix86-at' enabled by
        !           607:      'default'.
        !           608: 
        !           609: '--enable-eata_dma'
        !           610:      EATA-DMA (DPT, NEC, AT&T, SNI, AST, Olivetti, Alphatronix) SCSI
        !           611:      controller device driver.
        !           612: 
        !           613: '--enable-eata_pio'
        !           614:      EATA-PIO (old DPT PM2001, PM2012A) SCSI controller device driver.
        !           615:      On 'ix86-at' enabled by 'default'.
        !           616: 
        !           617: '--enable-wd7000'
        !           618:      WD 7000 SCSI controller device driver.  On 'ix86-at' enabled by
        !           619:      'default'.
        !           620: 
        !           621: '--enable-eata'
        !           622:      EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) SCSI
        !           623:      controller device driver.  On 'ix86-at' enabled by 'default'.
        !           624: 
        !           625: '--enable-am53c974'
        !           626:      AM53/79C974 SCSI controller device driver.  On 'ix86-at' enabled by
        !           627:      'default'.
        !           628: 
        !           629: '--enable-dtc'
        !           630:      DTC3180/3280 SCSI controller device driver.  On 'ix86-at' enabled
        !           631:      by 'default'.
        !           632: 
        !           633: '--enable-ncr53c8xx'
        !           634:      NCR53C8XX, dc390w, dc390u, dc390f SCSI controller device driver.
        !           635:      On 'ix86-at' enabled by 'default'.
        !           636: 
        !           637: '--enable-tmscsim'
        !           638:      Tekram DC-390(T) SCSI controller device driver.  On 'ix86-at'
        !           639:      enabled by 'default'.
        !           640: 
        !           641: '--enable-ppa'
        !           642:      IOMEGA Parallel Port ZIP drive device driver.  On 'ix86-at' enabled
        !           643:      by 'default'.
        !           644: 
        !           645: '--enable-qlogicfas'
        !           646:      Qlogic FAS SCSI controller device driver.  On 'ix86-at' enabled by
        !           647:      'default'.
        !           648: 
        !           649: '--enable-qlogicisp'
        !           650:      Qlogic ISP SCSI controller device driver.  On 'ix86-at' enabled by
        !           651:      'default'.
        !           652: 
        !           653: '--enable-gdth'
        !           654:      GDT SCSI Disk Array controller device driver.  On 'ix86-at' enabled
        !           655:      by 'default'.
        !           656: 
        !           657:    The following options enable drivers for various ethernet cards.  NIC
        !           658: devices are usually named 'eth%d', except for the pocket adaptors.
        !           659: 
        !           660: '--enable-ne'
        !           661:      NE2000/NE1000 ISA network card device driver.  On 'ix86-at' enabled
        !           662:      by 'default' and for 'qemu'.
        !           663: 
        !           664: '--enable-3c503'
        !           665:      3Com 503 (Etherlink II) network card device driver.  On 'ix86-at'
        !           666:      enabled by 'default'.
        !           667: 
        !           668: '--enable-3c509'
        !           669:      3Com 509/579 (Etherlink III) network card device driver.  On
        !           670:      'ix86-at' enabled by 'default'.
        !           671: 
        !           672: '--enable-wd'
        !           673:      WD80X3 network card device driver.  On 'ix86-at' enabled by
        !           674:      'default'.
        !           675: 
        !           676: '--enable-3c501'
        !           677:      3COM 501/Etherlink I network card device driver.  On 'ix86-at'
        !           678:      enabled by 'default'.
        !           679: 
        !           680: '--enable-smc-ultra'
        !           681:      SMC Ultra network card device driver.  On 'ix86-at' enabled by
        !           682:      'default'.
        !           683: 
        !           684: '--enable-smc-ultra32'
        !           685:      SMC Ultra 32 network card device driver.  On 'ix86-at' enabled by
        !           686:      'default'.
        !           687: 
        !           688: '--enable-hp-plus'
        !           689:      HP PCLAN+ (27247B and 27252A) network card device driver.  On
        !           690:      'ix86-at' enabled by 'default'.
        !           691: 
        !           692: '--enable-hp'
        !           693:      HP PCLAN (27245 and other 27xxx series) network card device driver.
        !           694:      On 'ix86-at' enabled by 'default'.
        !           695: 
        !           696: '--enable-3c59x'
        !           697:      3Com 590/900 series (592/595/597/900/905) "Vortex/Boomerang"
        !           698:      network card device driver.  On 'ix86-at' enabled by 'default'.
        !           699: 
        !           700: '--enable-seeq8005'
        !           701:      Seeq8005 network card device driver.  On 'ix86-at' enabled by
        !           702:      'default'.
        !           703: 
        !           704: '--enable-hp100'
        !           705:      HP 10/100VG PCLAN (ISA, EISA, PCI) network card device driver.  On
        !           706:      'ix86-at' enabled by 'default'.
        !           707: 
        !           708: '--enable-ac3200'
        !           709:      Ansel Communications EISA 3200 network card device driver.  On
        !           710:      'ix86-at' enabled by 'default'.
        !           711: 
        !           712: '--enable-e2100'
        !           713:      Cabletron E21xx network card device driver.  On 'ix86-at' enabled
        !           714:      by 'default'.
        !           715: 
        !           716: '--enable-at1700'
        !           717:      AT1700 (Fujitsu 86965) network card device driver.  On 'ix86-at'
        !           718:      enabled by 'default'.
        !           719: 
        !           720: '--enable-eth16i'
        !           721:      ICL EtherTeam 16i/32 network card device driver.  On 'ix86-at'
        !           722:      enabled by 'default'.
        !           723: 
        !           724: '--enable-znet'
        !           725:      Zenith Z-Note network card device driver.  On 'ix86-at' enabled by
        !           726:      'default'.
        !           727: 
        !           728: '--enable-eexpress'
        !           729:      EtherExpress 16 network card device driver.  On 'ix86-at' enabled
        !           730:      by 'default'.
        !           731: 
        !           732: '--enable-eepro'
        !           733:      EtherExpressPro network card device driver.  On 'ix86-at' enabled
        !           734:      by 'default'.
        !           735: 
        !           736: '--enable-eepro100'
        !           737:      Intel EtherExpressPro PCI 10+/100B/100+ network card device driver.
        !           738:      On 'ix86-at' enabled by 'default'.
        !           739: 
        !           740: '--enable-depca'
        !           741:      DEPCA, DE10x, DE200, DE201, DE202, DE210, DE422 network card device
        !           742:      driver.  On 'ix86-at' enabled by 'default'.
        !           743: 
        !           744: '--enable-ewrk3'
        !           745:      EtherWORKS 3 (DE203, DE204, DE205) network card device driver.  On
        !           746:      'ix86-at' enabled by 'default'.
        !           747: 
        !           748: '--enable-de4x5'
        !           749:      DE425, DE434, DE435, DE450, DE500 network card device driver.  On
        !           750:      'ix86-at' enabled by 'default'.
        !           751: 
        !           752: '--enable-apricot'
        !           753:      Apricot XEN-II on board ethernet network card device driver.  On
        !           754:      'ix86-at' enabled by 'default'.
        !           755: 
        !           756: '--enable-wavelan'
        !           757:      AT&T WaveLAN & DEC RoamAbout DS network card device driver.
        !           758: 
        !           759: '--enable-3c507'
        !           760:      3Com 507 network card device driver.  On 'ix86-at' enabled by
        !           761:      'default'.
        !           762: 
        !           763: '--enable-3c505'
        !           764:      3Com 505/Etherlink II network card device driver.  On 'ix86-at'
        !           765:      enabled by 'default'.
        !           766: 
        !           767: '--enable-de600'
        !           768:      D-Link DE-600 network card device driver.  On 'ix86-at' enabled by
        !           769:      'default'.
        !           770: 
        !           771: '--enable-de620'
        !           772:      D-Link DE-620 network card device driver.  On 'ix86-at' enabled by
        !           773:      'default'.
        !           774: 
        !           775: '--enable-sk_g16'
        !           776:      Schneider & Koch G16 network card device driver.  On 'ix86-at'
        !           777:      enabled by 'default'.
        !           778: 
        !           779: '--enable-ni52'
        !           780:      NI5210 network card device driver.  On 'ix86-at' enabled by
        !           781:      'default'.
        !           782: 
        !           783: '--enable-ni65'
        !           784:      NI6510 network card device driver.  On 'ix86-at' enabled by
        !           785:      'default'.
        !           786: 
        !           787: '--enable-atp'
        !           788:      AT-LAN-TEC/RealTek pocket adaptor network card device driver for
        !           789:      the 'atp%d' devices.
        !           790: 
        !           791: '--enable-lance'
        !           792:      AMD LANCE and PCnet (AT1500 and NE2100) network card device driver.
        !           793:      On 'ix86-at' enabled by 'default'.
        !           794: 
        !           795: '--enable-tulip'
        !           796:      DECchip Tulip (dc21x4x) PCI network card device driver.  On
        !           797:      'ix86-at' enabled by 'default'.
        !           798: 
        !           799: '--enable-fmv18x'
        !           800:      FMV-181/182/183/184 network card device driver.  On 'ix86-at'
        !           801:      enabled by 'default'.
        !           802: 
        !           803: '--enable-3c515'
        !           804:      3Com 515 ISA Fast EtherLink network card device driver.  On
        !           805:      'ix86-at' enabled by 'default'.
        !           806: 
        !           807: '--enable-pcnet32'
        !           808:      AMD PCI PCnet32 (PCI bus NE2100 cards) network card device driver.
        !           809:      On 'ix86-at' enabled by 'default'.
        !           810: 
        !           811: '--enable-ne2k-pci'
        !           812:      PCI NE2000 network card device driver.  On 'ix86-at' enabled by
        !           813:      'default'.
        !           814: 
        !           815: '--enable-yellowfin'
        !           816:      Packet Engines Yellowfin Gigabit-NIC network card device driver.
        !           817:      On 'ix86-at' enabled by 'default'.
        !           818: 
        !           819: '--enable-rtl8139'
        !           820:      RealTek 8129/8139 (not 8019/8029!)  network card device driver.  On
        !           821:      'ix86-at' enabled by 'default'.
        !           822: 
        !           823: '--enable-epic100'
        !           824:      SMC 83c170/175 EPIC/100 (EtherPower II) network card device driver.
        !           825:      On 'ix86-at' enabled by 'default'.
        !           826: 
        !           827: '--enable-tlan'
        !           828:      TI ThunderLAN network card device driver.  On 'ix86-at' enabled by
        !           829:      'default'.
        !           830: 
        !           831: '--enable-via-rhine'
        !           832:      VIA Rhine network card device driver.  On 'ix86-at' enabled by
        !           833:      'default'.
        !           834: 
        !           835: '--enable-hamachi'
        !           836:      Packet Engines "Hamachi" GNIC-2 Gigabit Ethernet device driver.  On
        !           837:      'ix86-at' enabled by 'default'.
        !           838: 
        !           839: '--enable-intel-gige'
        !           840:      Intel PCI Gigabit Ethernet device driver.  On 'ix86-at' enabled by
        !           841:      'default'.
        !           842: 
        !           843: '--enable-myson803'
        !           844:      Myson MTD803 Ethernet adapter series device driver.  On 'ix86-at'
        !           845:      enabled by 'default'.
        !           846: 
        !           847: '--enable-natsemi'
        !           848:      National Semiconductor DP8381x series PCI Ethernet device driver.
        !           849:      On 'ix86-at' enabled by 'default'.
        !           850: 
        !           851: '--enable-ns820'
        !           852:      National Semiconductor DP8382x series PCI Ethernet device driver.
        !           853:      On 'ix86-at' enabled by 'default'.
        !           854: 
        !           855: '--enable-starfire'
        !           856:      Adaptec Starfire network adapter device driver.  On 'ix86-at'
        !           857:      enabled by 'default'.
        !           858: 
        !           859: '--enable-sundance'
        !           860:      Sundance ST201 "Alta" PCI Ethernet device driver.  On 'ix86-at'
        !           861:      enabled by 'default'.
        !           862: 
        !           863: '--enable-winbond-840'
        !           864:      Winbond W89c840 PCI Ethernet device driver.  On 'ix86-at' enabled
        !           865:      by 'default'.
        !           866: 
        !           867:    The following options either control device drivers for supported
        !           868: PCMCIA bridges or control the overall behaviour of the GNU Mach PCMCIA
        !           869: core.  To make use of GNU Mach PCMCIA support you need to have the
        !           870: corresponding userland applications (GNU Mach Card Services) installed.
        !           871: 
        !           872: '--enable-i82365'
        !           873:      Device driver for the Intel 82365 and compatible PC Card
        !           874:      controllers, and Yenta-compatible PCI-to-CardBus controllers.  On
        !           875:      'ix86-at' enabled by 'default'.
        !           876: 
        !           877: '--enable-pcmcia-isa'
        !           878:      ISA bus related bits in the GNU Mach PCMCIA core.  Keeping it
        !           879:      enabled is generally a good idea, since it does not only have
        !           880:      effect if your PC Card bridge is attached to the ISA bus, but
        !           881:      provides more (ISA) interrupts to the Card Services for it to
        !           882:      assign to the cards in turn.  On 'ix86-at' enabled by 'default'.
        !           883: 
        !           884:    The following options control device drivers for supported PCMCIA
        !           885: Ethernet controllers.  NIC devices are usually named 'eth%d'.
        !           886: 
        !           887: '--enable-3c574_cs'
        !           888:      PCMCIA ethernet driver for the 3Com 3c574 "RoadRunner".  On
        !           889:      'ix86-at' enabled by 'default'.
        !           890: 
        !           891: '--enable-3c589_cs'
        !           892:      Driver for the 3Com 3c589 PCMCIA card.  On 'ix86-at' enabled by
        !           893:      'default'.
        !           894: 
        !           895: '--enable-axnet_cs'
        !           896:      Driver for the Asix AX88190-based PCMCIA cards.  On 'ix86-at'
        !           897:      enabled by 'default'.
        !           898: 
        !           899: '--enable-fmvj18x_cs'
        !           900:      Driver for PCMCIA cards with the fmvj18x chipset.  On 'ix86-at'
        !           901:      enabled by 'default'.
        !           902: 
        !           903: '--enable-nmclan_cs'
        !           904:      Driver for the New Media Ethernet LAN PCMCIA cards.  On 'ix86-at'
        !           905:      enabled by 'default'.
        !           906: 
        !           907: '--enable-pcnet_cs'
        !           908:      Driver for NS8390-based PCMCIA cards.  This driver supports the
        !           909:      D-Link DE-650 and Linksys EthernetCard cards, the newer D-Link and
        !           910:      Linksys combo cards, Accton EN2212 cards, the RPTI EP400, and the
        !           911:      PreMax PE-200 in non-shared-memory mode, and the IBM Credit Card
        !           912:      Adapter, the NE4100, the Thomas Conrad ethernet card, and the
        !           913:      Kingston KNE-PCM/x in shared-memory mode.  It will also handle the
        !           914:      Socket EA card in either mode.  On 'ix86-at' enabled by 'default'.
        !           915: 
        !           916: '--enable-smc91c92_cs'
        !           917:      Driver for SMC91c92-based PCMCIA cards.  On 'ix86-at' enabled by
        !           918:      'default'.
        !           919: 
        !           920: '--enable-xirc2ps_cs'
        !           921:      Driver for Xircom CreditCard and Realport PCMCIA ethernet adapters.
        !           922:      On 'ix86-at' enabled by 'default'.
        !           923: 
        !           924:    The following options control device drivers for supported PCMCIA
        !           925: Wireless LAN network controllers.  NIC devices are usually named
        !           926: 'eth%d'.
        !           927: 
        !           928:    Please mind, that you need to have some userland applications (the
        !           929: GNU Mach Wireless Tools) installed, in order to make use of these
        !           930: devices.
        !           931: 
        !           932: '--enable-orinoco_cs'
        !           933:      Driver for the Hermes or Prism 2 chipset based PCMCIA wireless
        !           934:      adapters, with Lucent/Agere, Intersil or Symbol firmware.  This
        !           935:      driver is suitable for PCMCIA wireless adapters, such as the Lucent
        !           936:      WavelanIEEE/Orinoco cards and their OEM (Cabletron/EnteraSys
        !           937:      RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and others).  It
        !           938:      should also be usable on various Prism II based cards such as the
        !           939:      Linksys, D-Link and Farallon Skyline.  It should also work on
        !           940:      Symbol cards such as the 3Com AirConnect and Ericsson WLAN. On
        !           941:      'ix86-at' enabled by 'default'.
        !           942: 
        !           943: 
        !           944: File: mach.info,  Node: Cross-Compilation,  Prev: Configuration,  Up: Installing
        !           945: 
        !           946: 2.4 Cross-Compilation
        !           947: =====================
        !           948: 
        !           949: Another way to install the kernel is to use an existing operating system
        !           950: in order to compile the kernel binary.  This is called
        !           951: "cross-compiling", because it is done between two different platforms.
        !           952: If the pre-built kernels are not working for you, and you can't ask
        !           953: someone to compile a custom kernel for your machine, this is your last
        !           954: chance to get a kernel that boots on your hardware.
        !           955: 
        !           956:    Luckily, the kernel does have light dependencies.  You don't even
        !           957: need a cross compiler if your build machine has a compiler and is the
        !           958: same architecture as the system you want to run GNU Mach on.
        !           959: 
        !           960:    You need a cross-mig, though.
        !           961: 
        !           962:    XXX More info needed.
        !           963: 
        !           964: 
        !           965: File: mach.info,  Node: Bootstrap,  Next: Inter Process Communication,  Prev: Installing,  Up: Top
        !           966: 
        !           967: 3 Bootstrap
        !           968: ***********
        !           969: 
        !           970: Bootstrapping(1) is the procedure by which your machine loads the
        !           971: microkernel and transfers control to the operating system.
        !           972: 
        !           973: * Menu:
        !           974: 
        !           975: * Bootloader::                    Starting the microkernel, or other OSes.
        !           976: * Modules::                       Starting the first task of the OS.
        !           977: 
        !           978:    ---------- Footnotes ----------
        !           979: 
        !           980:    (1) The term "bootstrapping" refers to a Dutch legend about a boy who
        !           981: was able to fly by pulling himself up by his bootstraps.  In computers,
        !           982: this term refers to any process where a simple system activates a more
        !           983: complicated system.
        !           984: 
        !           985: 
        !           986: File: mach.info,  Node: Bootloader,  Next: Modules,  Up: Bootstrap
        !           987: 
        !           988: 3.1 Bootloader
        !           989: ==============
        !           990: 
        !           991: The "bootloader" is the first software that runs on your machine.  Many
        !           992: hardware architectures have a very simple startup routine which reads a
        !           993: very simple bootloader from the beginning of the internal hard disk,
        !           994: then transfers control to it.  Other architectures have startup routines
        !           995: which are able to understand more of the contents of the hard disk, and
        !           996: directly start a more advanced bootloader.
        !           997: 
        !           998:    "GRUB"(1) is the GNU bootloader.  GRUB provides advanced
        !           999: functionality, and is capable of loading several different kernels (such
        !          1000: as Mach, Linux, DOS, and the *BSD family).  *Note Introduction:
        !          1001: (grub)Top.
        !          1002: 
        !          1003:    GNU Mach conforms to the Multiboot specification which defines an
        !          1004: interface between the bootloader and the components that run very early
        !          1005: at startup.  GNU Mach can be started by any bootloader which supports
        !          1006: the multiboot standard.  After the bootloader loaded the kernel image to
        !          1007: a designated address in the system memory, it jumps into the startup
        !          1008: code of the kernel.  This code initializes the kernel and detects the
        !          1009: available hardware devices.  Afterwards, the first system task is
        !          1010: started.  *Note Overview: (multiboot)Top.
        !          1011: 
        !          1012:    ---------- Footnotes ----------
        !          1013: 
        !          1014:    (1) The GRand Unified Bootloader, available from
        !          1015: <http://gnu.org/software/grub/>.
        !          1016: 
        !          1017: 
        !          1018: File: mach.info,  Node: Modules,  Prev: Bootloader,  Up: Bootstrap
        !          1019: 
        !          1020: 3.2 Modules
        !          1021: ===========
        !          1022: 
        !          1023: This is outdated.
        !          1024: 
        !          1025:    Because the microkernel does not provide filesystem support and other
        !          1026: features necessary to load the first system task from a storage medium,
        !          1027: the first task is loaded by the bootloader as a module to a specified
        !          1028: address.  In the GNU system, this first program is the 'serverboot'
        !          1029: executable.  GNU Mach inserts the host control port and the device
        !          1030: master port into this task and appends the port numbers to the command
        !          1031: line before executing it.
        !          1032: 
        !          1033:    The 'serverboot' program is responsible for loading and executing the
        !          1034: rest of the Hurd servers.  Rather than containing specific instructions
        !          1035: for starting the Hurd, it follows general steps given in a user-supplied
        !          1036: boot script.
        !          1037: 
        !          1038:    XXX More about boot scripts.
        !          1039: 
        !          1040: 
        !          1041: File: mach.info,  Node: Inter Process Communication,  Next: Virtual Memory Interface,  Prev: Bootstrap,  Up: Top
        !          1042: 
        !          1043: 4 Inter Process Communication
        !          1044: *****************************
        !          1045: 
        !          1046: This chapter describes the details of the Mach IPC system.  First the
        !          1047: actual calls concerned with sending and receiving messages are
        !          1048: discussed, then the details of the port system are described in detail.
        !          1049: 
        !          1050: * Menu:
        !          1051: 
        !          1052: * Major Concepts::                The concepts behind the Mach IPC system.
        !          1053: * Messaging Interface::           Composing, sending and receiving messages.
        !          1054: * Port Manipulation Interface::   Manipulating ports, port rights, port sets.
        !          1055: 
        !          1056: 
        !          1057: File: mach.info,  Node: Major Concepts,  Next: Messaging Interface,  Up: Inter Process Communication
        !          1058: 
        !          1059: 4.1 Major Concepts
        !          1060: ==================
        !          1061: 
        !          1062: The Mach kernel provides message-oriented, capability-based interprocess
        !          1063: communication.  The interprocess communication (IPC) primitives
        !          1064: efficiently support many different styles of interaction, including
        !          1065: remote procedure calls (RPC), object-oriented distributed programming,
        !          1066: streaming of data, and sending very large amounts of data.
        !          1067: 
        !          1068:    The IPC primitives operate on three abstractions: messages, ports,
        !          1069: and port sets.  User tasks access all other kernel services and
        !          1070: abstractions via the IPC primitives.
        !          1071: 
        !          1072:    The message primitives let tasks send and receive messages.  Tasks
        !          1073: send messages to ports.  Messages sent to a port are delivered reliably
        !          1074: (messages may not be lost) and are received in the order in which they
        !          1075: were sent.  Messages contain a fixed-size header and a variable amount
        !          1076: of typed data following the header.  The header describes the
        !          1077: destination and size of the message.
        !          1078: 
        !          1079:    The IPC implementation makes use of the VM system to efficiently
        !          1080: transfer large amounts of data.  The message body can contain the
        !          1081: address of a region in the sender's address space which should be
        !          1082: transferred as part of the message.  When a task receives a message
        !          1083: containing an out-of-line region of data, the data appears in an unused
        !          1084: portion of the receiver's address space.  This transmission of
        !          1085: out-of-line data is optimized so that sender and receiver share the
        !          1086: physical pages of data copy-on-write, and no actual data copy occurs
        !          1087: unless the pages are written.  Regions of memory up to the size of a
        !          1088: full address space may be sent in this manner.
        !          1089: 
        !          1090:    Ports hold a queue of messages.  Tasks operate on a port to send and
        !          1091: receive messages by exercising capabilities for the port.  Multiple
        !          1092: tasks can hold send capabilities, or rights, for a port.  Tasks can also
        !          1093: hold send-once rights, which grant the ability to send a single message.
        !          1094: Only one task can hold the receive capability, or receive right, for a
        !          1095: port.  Port rights can be transferred between tasks via messages.  The
        !          1096: sender of a message can specify in the message body that the message
        !          1097: contains a port right.  If a message contains a receive right for a
        !          1098: port, then the receive right is removed from the sender of the message
        !          1099: and the right is transferred to the receiver of the message.  While the
        !          1100: receive right is in transit, tasks holding send rights can still send
        !          1101: messages to the port, and they are queued until a task acquires the
        !          1102: receive right and uses it to receive the messages.
        !          1103: 
        !          1104:    Tasks can receive messages from ports and port sets.  The port set
        !          1105: abstraction allows a single thread to wait for a message from any of
        !          1106: several ports.  Tasks manipulate port sets with a capability, or
        !          1107: port-set right, which is taken from the same space as the port
        !          1108: capabilities.  The port-set right may not be transferred in a message.
        !          1109: A port set holds receive rights, and a receive operation on a port set
        !          1110: blocks waiting for a message sent to any of the constituent ports.  A
        !          1111: port may not belong to more than one port set, and if a port is a member
        !          1112: of a port set, the holder of the receive right can't receive directly
        !          1113: from the port.
        !          1114: 
        !          1115:    Port rights are a secure, location-independent way of naming ports.
        !          1116: The port queue is a protected data structure, only accessible via the
        !          1117: kernel's exported message primitives.  Rights are also protected by the
        !          1118: kernel; there is no way for a malicious user task to guess a port name
        !          1119: and send a message to a port to which it shouldn't have access.  Port
        !          1120: rights do not carry any location information.  When a receive right for
        !          1121: a port moves from task to task, and even between tasks on different
        !          1122: machines, the send rights for the port remain unchanged and continue to
        !          1123: function.
        !          1124: 
        !          1125: 
        !          1126: File: mach.info,  Node: Messaging Interface,  Next: Port Manipulation Interface,  Prev: Major Concepts,  Up: Inter Process Communication
        !          1127: 
        !          1128: 4.2 Messaging Interface
        !          1129: =======================
        !          1130: 
        !          1131: This section describes how messages are composed, sent and received
        !          1132: within the Mach IPC system.
        !          1133: 
        !          1134: * Menu:
        !          1135: 
        !          1136: * Mach Message Call::             Sending and receiving messages.
        !          1137: * Message Format::                The format of Mach messages.
        !          1138: * Exchanging Port Rights::        Sending and receiving port rights.
        !          1139: * Memory::                        Passing memory regions in messages.
        !          1140: * Message Send::                  Sending messages.
        !          1141: * Message Receive::               Receiving messages.
        !          1142: * Atomicity::                     Atomicity of port rights.
        !          1143: 
        !          1144: 
        !          1145: File: mach.info,  Node: Mach Message Call,  Next: Message Format,  Up: Messaging Interface
        !          1146: 
        !          1147: 4.2.1 Mach Message Call
        !          1148: -----------------------
        !          1149: 
        !          1150: To use the 'mach_msg' call, you can include the header files
        !          1151: 'mach/port.h' and 'mach/message.h'.
        !          1152: 
        !          1153:  -- Function: mach_msg_return_t mach_msg (mach_msg_header_t *MSG,
        !          1154:           mach_msg_option_t OPTION, mach_msg_size_t SEND_SIZE,
        !          1155:           mach_msg_size_t RCV_SIZE, mach_port_t RCV_NAME,
        !          1156:           mach_msg_timeout_t TIMEOUT, mach_port_t NOTIFY)
        !          1157:      The 'mach_msg' function is used to send and receive messages.  Mach
        !          1158:      messages contain typed data, which can include port rights and
        !          1159:      references to large regions of memory.
        !          1160: 
        !          1161:      MSG is the address of a buffer in the caller's address space.
        !          1162:      Message buffers should be aligned on long-word boundaries.  The
        !          1163:      message options OPTION are bit values, combined with bitwise-or.
        !          1164:      One or both of 'MACH_SEND_MSG' and 'MACH_RCV_MSG' should be used.
        !          1165:      Other options act as modifiers.  When sending a message, SEND_SIZE
        !          1166:      specifies the size of the message buffer.  Otherwise zero should be
        !          1167:      supplied.  When receiving a message, RCV_SIZE specifies the size of
        !          1168:      the message buffer.  Otherwise zero should be supplied.  When
        !          1169:      receiving a message, RCV_NAME specifies the port or port set.
        !          1170:      Otherwise 'MACH_PORT_NULL' should be supplied.  When using the
        !          1171:      'MACH_SEND_TIMEOUT' and 'MACH_RCV_TIMEOUT' options, TIMEOUT
        !          1172:      specifies the time in milliseconds to wait before giving up.
        !          1173:      Otherwise 'MACH_MSG_TIMEOUT_NONE' should be supplied.  When using
        !          1174:      the 'MACH_SEND_NOTIFY', 'MACH_SEND_CANCEL', and 'MACH_RCV_NOTIFY'
        !          1175:      options, NOTIFY specifies the port used for the notification.
        !          1176:      Otherwise 'MACH_PORT_NULL' should be supplied.
        !          1177: 
        !          1178:      If the option argument is 'MACH_SEND_MSG', it sends a message.  The
        !          1179:      SEND_SIZE argument specifies the size of the message to send.  The
        !          1180:      'msgh_remote_port' field of the message header specifies the
        !          1181:      destination of the message.
        !          1182: 
        !          1183:      If the option argument is 'MACH_RCV_MSG', it receives a message.
        !          1184:      The RCV_SIZE argument specifies the size of the message buffer that
        !          1185:      will receive the message; messages larger than RCV_SIZE are not
        !          1186:      received.  The RCV_NAME argument specifies the port or port set
        !          1187:      from which to receive.
        !          1188: 
        !          1189:      If the option argument is 'MACH_SEND_MSG|MACH_RCV_MSG', then
        !          1190:      'mach_msg' does both send and receive operations.  If the send
        !          1191:      operation encounters an error (any return code other than
        !          1192:      'MACH_MSG_SUCCESS'), then the call returns immediately without
        !          1193:      attempting the receive operation.  Semantically the combined call
        !          1194:      is equivalent to separate send and receive calls, but it saves a
        !          1195:      system call and enables other internal optimizations.
        !          1196: 
        !          1197:      If the option argument specifies neither 'MACH_SEND_MSG' nor
        !          1198:      'MACH_RCV_MSG', then 'mach_msg' does nothing.
        !          1199: 
        !          1200:      Some options, like 'MACH_SEND_TIMEOUT' and 'MACH_RCV_TIMEOUT',
        !          1201:      share a supporting argument.  If these options are used together,
        !          1202:      they make independent use of the supporting argument's value.
        !          1203: 
        !          1204:  -- Data type: mach_msg_timeout_t
        !          1205:      This is a 'natural_t' used by the timeout mechanism.  The units are
        !          1206:      milliseconds.  The value to be used when there is no timeout is
        !          1207:      'MACH_MSG_TIMEOUT_NONE'.
        !          1208: 
        !          1209: 
        !          1210: File: mach.info,  Node: Message Format,  Next: Exchanging Port Rights,  Prev: Mach Message Call,  Up: Messaging Interface
        !          1211: 
        !          1212: 4.2.2 Message Format
        !          1213: --------------------
        !          1214: 
        !          1215: A Mach message consists of a fixed size message header, a
        !          1216: 'mach_msg_header_t', followed by zero or more data items.  Data items
        !          1217: are typed.  Each item has a type descriptor followed by the actual data
        !          1218: (or the address of the data, for out-of-line memory regions).
        !          1219: 
        !          1220:    The following data types are related to Mach ports:
        !          1221: 
        !          1222:  -- Data type: mach_port_t
        !          1223:      The 'mach_port_t' data type is an unsigned integer type which
        !          1224:      represents a port name in the task's port name space.  In GNU Mach,
        !          1225:      this is an 'unsigned int'.
        !          1226: 
        !          1227:    The following data types are related to Mach messages:
        !          1228: 
        !          1229:  -- Data type: mach_msg_bits_t
        !          1230:      The 'mach_msg_bits_t' data type is an 'unsigned int' used to store
        !          1231:      various flags for a message.
        !          1232: 
        !          1233:  -- Data type: mach_msg_size_t
        !          1234:      The 'mach_msg_size_t' data type is an 'unsigned int' used to store
        !          1235:      the size of a message.
        !          1236: 
        !          1237:  -- Data type: mach_msg_id_t
        !          1238:      The 'mach_msg_id_t' data type is an 'integer_t' typically used to
        !          1239:      convey a function or operation id for the receiver.
        !          1240: 
        !          1241:  -- Data type: mach_msg_header_t
        !          1242:      This structure is the start of every message in the Mach IPC
        !          1243:      system.  It has the following members:
        !          1244: 
        !          1245:      'mach_msg_bits_t msgh_bits'
        !          1246:           The 'msgh_bits' field has the following bits defined, all
        !          1247:           other bits should be zero:
        !          1248: 
        !          1249:           'MACH_MSGH_BITS_REMOTE_MASK'
        !          1250:           'MACH_MSGH_BITS_LOCAL_MASK'
        !          1251:                The remote and local bits encode 'mach_msg_type_name_t'
        !          1252:                values that specify the port rights in the
        !          1253:                'msgh_remote_port' and 'msgh_local_port' fields.  The
        !          1254:                remote value must specify a send or send-once right for
        !          1255:                the destination of the message.  If the local value
        !          1256:                doesn't specify a send or send-once right for the
        !          1257:                message's reply port, it must be zero and msgh_local_port
        !          1258:                must be 'MACH_PORT_NULL'.
        !          1259: 
        !          1260:           'MACH_MSGH_BITS_COMPLEX'
        !          1261:                The complex bit must be specified if the message body
        !          1262:                contains port rights or out-of-line memory regions.  If
        !          1263:                it is not specified, then the message body carries no
        !          1264:                port rights or memory, no matter what the type
        !          1265:                descriptors may seem to indicate.
        !          1266: 
        !          1267:           'MACH_MSGH_BITS_REMOTE' and 'MACH_MSGH_BITS_LOCAL' macros
        !          1268:           return the appropriate 'mach_msg_type_name_t' values, given a
        !          1269:           'msgh_bits' value.  The 'MACH_MSGH_BITS' macro constructs a
        !          1270:           value for 'msgh_bits', given two 'mach_msg_type_name_t'
        !          1271:           values.
        !          1272: 
        !          1273:      'mach_msg_size_t msgh_size'
        !          1274:           The 'msgh_size' field in the header of a received message
        !          1275:           contains the message's size.  The message size, a byte
        !          1276:           quantity, includes the message header, type descriptors, and
        !          1277:           in-line data.  For out-of-line memory regions, the message
        !          1278:           size includes the size of the in-line address, not the size of
        !          1279:           the actual memory region.  There are no arbitrary limits on
        !          1280:           the size of a Mach message, the number of data items in a
        !          1281:           message, or the size of the data items.
        !          1282: 
        !          1283:      'mach_port_t msgh_remote_port'
        !          1284:           The 'msgh_remote_port' field specifies the destination port of
        !          1285:           the message.  The field must carry a legitimate send or
        !          1286:           send-once right for a port.
        !          1287: 
        !          1288:      'mach_port_t msgh_local_port'
        !          1289:           The 'msgh_local_port' field specifies an auxiliary port right,
        !          1290:           which is conventionally used as a reply port by the recipient
        !          1291:           of the message.  The field must carry a send right, a
        !          1292:           send-once right, 'MACH_PORT_NULL', or 'MACH_PORT_DEAD'.
        !          1293: 
        !          1294:      'mach_port_seqno_t msgh_seqno'
        !          1295:           The 'msgh_seqno' field provides a sequence number for the
        !          1296:           message.  It is only valid in received messages; its value in
        !          1297:           sent messages is overwritten.
        !          1298: 
        !          1299:      'mach_msg_id_t msgh_id'
        !          1300:           The 'mach_msg' call doesn't use the 'msgh_id' field, but it
        !          1301:           conventionally conveys an operation or function id.
        !          1302: 
        !          1303:  -- Macro: mach_msg_bits_t MACH_MSGH_BITS (mach_msg_type_name_t REMOTE,
        !          1304:           mach_msg_type_name_t LOCAL)
        !          1305:      This macro composes two 'mach_msg_type_name_t' values that specify
        !          1306:      the port rights in the 'msgh_remote_port' and 'msgh_local_port'
        !          1307:      fields of a 'mach_msg' call into an appropriate 'mach_msg_bits_t'
        !          1308:      value.
        !          1309: 
        !          1310:  -- Macro: mach_msg_type_name_t MACH_MSGH_BITS_REMOTE
        !          1311:           (mach_msg_bits_t BITS)
        !          1312:      This macro extracts the 'mach_msg_type_name_t' value for the remote
        !          1313:      port right in a 'mach_msg_bits_t' value.
        !          1314: 
        !          1315:  -- Macro: mach_msg_type_name_t MACH_MSGH_BITS_LOCAL
        !          1316:           (mach_msg_bits_t BITS)
        !          1317:      This macro extracts the 'mach_msg_type_name_t' value for the local
        !          1318:      port right in a 'mach_msg_bits_t' value.
        !          1319: 
        !          1320:  -- Macro: mach_msg_bits_t MACH_MSGH_BITS_PORTS (mach_msg_bits_t BITS)
        !          1321:      This macro extracts the 'mach_msg_bits_t' component consisting of
        !          1322:      the 'mach_msg_type_name_t' values for the remote and local port
        !          1323:      right in a 'mach_msg_bits_t' value.
        !          1324: 
        !          1325:  -- Macro: mach_msg_bits_t MACH_MSGH_BITS_OTHER (mach_msg_bits_t BITS)
        !          1326:      This macro extracts the 'mach_msg_bits_t' component consisting of
        !          1327:      everything except the 'mach_msg_type_name_t' values for the remote
        !          1328:      and local port right in a 'mach_msg_bits_t' value.
        !          1329: 
        !          1330:    Each data item has a type descriptor, a 'mach_msg_type_t' or a
        !          1331: 'mach_msg_type_long_t'.  The 'mach_msg_type_long_t' type descriptor
        !          1332: allows larger values for some fields.  The 'msgtl_header' field in the
        !          1333: long descriptor is only used for its inline, longform, and deallocate
        !          1334: bits.
        !          1335: 
        !          1336:  -- Data type: mach_msg_type_name_t
        !          1337:      This is an 'unsigned int' and can be used to hold the 'msgt_name'
        !          1338:      component of the 'mach_msg_type_t' and 'mach_msg_type_long_t'
        !          1339:      structure.
        !          1340: 
        !          1341:  -- Data type: mach_msg_type_size_t
        !          1342:      This is an 'unsigned int' and can be used to hold the 'msgt_size'
        !          1343:      component of the 'mach_msg_type_t' and 'mach_msg_type_long_t'
        !          1344:      structure.
        !          1345: 
        !          1346:  -- Data type: mach_msg_type_number_t
        !          1347:      This is an 'natural_t' and can be used to hold the 'msgt_number'
        !          1348:      component of the 'mach_msg_type_t' and 'mach_msg_type_long_t'
        !          1349:      structure.
        !          1350: 
        !          1351:  -- Data type: mach_msg_type_t
        !          1352:      This structure has the following members:
        !          1353: 
        !          1354:      'unsigned int msgt_name : 8'
        !          1355:           The 'msgt_name' field specifies the data's type.  The
        !          1356:           following types are predefined:
        !          1357: 
        !          1358:           'MACH_MSG_TYPE_UNSTRUCTURED'
        !          1359:           'MACH_MSG_TYPE_BIT'
        !          1360:           'MACH_MSG_TYPE_BOOLEAN'
        !          1361:           'MACH_MSG_TYPE_INTEGER_16'
        !          1362:           'MACH_MSG_TYPE_INTEGER_32'
        !          1363:           'MACH_MSG_TYPE_CHAR'
        !          1364:           'MACH_MSG_TYPE_BYTE'
        !          1365:           'MACH_MSG_TYPE_INTEGER_8'
        !          1366:           'MACH_MSG_TYPE_REAL'
        !          1367:           'MACH_MSG_TYPE_STRING'
        !          1368:           'MACH_MSG_TYPE_STRING_C'
        !          1369:           'MACH_MSG_TYPE_PORT_NAME'
        !          1370: 
        !          1371:           The following predefined types specify port rights, and
        !          1372:           receive special treatment.  The next section discusses these
        !          1373:           types in detail.  The type 'MACH_MSG_TYPE_PORT_NAME' describes
        !          1374:           port right names, when no rights are being transferred, but
        !          1375:           just names.  For this purpose, it should be used in preference
        !          1376:           to 'MACH_MSG_TYPE_INTEGER_32'.
        !          1377: 
        !          1378:           'MACH_MSG_TYPE_MOVE_RECEIVE'
        !          1379:           'MACH_MSG_TYPE_MOVE_SEND'
        !          1380:           'MACH_MSG_TYPE_MOVE_SEND_ONCE'
        !          1381:           'MACH_MSG_TYPE_COPY_SEND'
        !          1382:           'MACH_MSG_TYPE_MAKE_SEND'
        !          1383:           'MACH_MSG_TYPE_MAKE_SEND_ONCE'
        !          1384: 
        !          1385:      'msgt_size : 8'
        !          1386:           The 'msgt_size' field specifies the size of each datum, in
        !          1387:           bits.  For example, the msgt_size of
        !          1388:           'MACH_MSG_TYPE_INTEGER_32' data is 32.
        !          1389: 
        !          1390:      'msgt_number : 12'
        !          1391:           The 'msgt_number' field specifies how many data elements
        !          1392:           comprise the data item.  Zero is a legitimate number.
        !          1393: 
        !          1394:           The total length specified by a type descriptor is
        !          1395:           '(msgt_size * msgt_number)', rounded up to an integral number
        !          1396:           of bytes.  In-line data is then padded to an integral number
        !          1397:           of long-words.  This ensures that type descriptors always
        !          1398:           start on long-word boundaries.  It implies that message sizes
        !          1399:           are always an integral multiple of a long-word's size.
        !          1400: 
        !          1401:      'msgt_inline : 1'
        !          1402:           The 'msgt_inline' bit specifies, when 'FALSE', that the data
        !          1403:           actually resides in an out-of-line region.  The address of the
        !          1404:           memory region (a 'vm_offset_t' or 'vm_address_t') follows the
        !          1405:           type descriptor in the message body.  The 'msgt_name',
        !          1406:           'msgt_size', and 'msgt_number' fields describe the memory
        !          1407:           region, not the address.
        !          1408: 
        !          1409:      'msgt_longform : 1'
        !          1410:           The 'msgt_longform' bit specifies, when 'TRUE', that this type
        !          1411:           descriptor is a 'mach_msg_type_long_t' instead of a
        !          1412:           'mach_msg_type_t'.  The 'msgt_name', 'msgt_size', and
        !          1413:           'msgt_number' fields should be zero.  Instead, 'mach_msg' uses
        !          1414:           the following 'msgtl_name', 'msgtl_size', and 'msgtl_number'
        !          1415:           fields.
        !          1416: 
        !          1417:      'msgt_deallocate : 1'
        !          1418:           The 'msgt_deallocate' bit is used with out-of-line regions.
        !          1419:           When 'TRUE', it specifies that the memory region should be
        !          1420:           deallocated from the sender's address space (as if with
        !          1421:           'vm_deallocate') when the message is sent.
        !          1422: 
        !          1423:      'msgt_unused : 1'
        !          1424:           The 'msgt_unused' bit should be zero.
        !          1425: 
        !          1426:  -- Macro: boolean_t MACH_MSG_TYPE_PORT_ANY (mach_msg_type_name_t type)
        !          1427:      This macro returns 'TRUE' if the given type name specifies a port
        !          1428:      type, otherwise it returns 'FALSE'.
        !          1429: 
        !          1430:  -- Macro: boolean_t MACH_MSG_TYPE_PORT_ANY_SEND (mach_msg_type_name_t
        !          1431:           type)
        !          1432:      This macro returns 'TRUE' if the given type name specifies a port
        !          1433:      type with a send or send-once right, otherwise it returns 'FALSE'.
        !          1434: 
        !          1435:  -- Macro: boolean_t MACH_MSG_TYPE_PORT_ANY_RIGHT (mach_msg_type_name_t
        !          1436:           type)
        !          1437:      This macro returns 'TRUE' if the given type name specifies a port
        !          1438:      right type which is moved, otherwise it returns 'FALSE'.
        !          1439: 
        !          1440:  -- Data type: mach_msg_type_long_t
        !          1441:      This structure has the following members:
        !          1442: 
        !          1443:      'mach_msg_type_t msgtl_header'
        !          1444:           Same meaning as 'msgt_header'.
        !          1445: 
        !          1446:      'unsigned short msgtl_name'
        !          1447:           Same meaning as 'msgt_name'.
        !          1448: 
        !          1449:      'unsigned short msgtl_size'
        !          1450:           Same meaning as 'msgt_size'.
        !          1451: 
        !          1452:      'unsigned int msgtl_number'
        !          1453:           Same meaning as 'msgt_number'.
        !          1454: 
        !          1455: 
        !          1456: File: mach.info,  Node: Exchanging Port Rights,  Next: Memory,  Prev: Message Format,  Up: Messaging Interface
        !          1457: 
        !          1458: 4.2.3 Exchanging Port Rights
        !          1459: ----------------------------
        !          1460: 
        !          1461: Each task has its own space of port rights.  Port rights are named with
        !          1462: positive integers.  Except for the reserved values 'MACH_PORT_NULL (0)'(1)
        !          1463: and 'MACH_PORT_DEAD (~0)', this is a full 32-bit name space.  When the
        !          1464: kernel chooses a name for a new right, it is free to pick any unused
        !          1465: name (one which denotes no right) in the space.
        !          1466: 
        !          1467:    There are five basic kinds of rights: receive rights, send rights,
        !          1468: send-once rights, port-set rights, and dead names.  Dead names are not
        !          1469: capabilities.  They act as place-holders to prevent a name from being
        !          1470: otherwise used.
        !          1471: 
        !          1472:    A port is destroyed, or dies, when its receive right is deallocated.
        !          1473: When a port dies, send and send-once rights for the port turn into dead
        !          1474: names.  Any messages queued at the port are destroyed, which deallocates
        !          1475: the port rights and out-of-line memory in the messages.
        !          1476: 
        !          1477:    Tasks may hold multiple user-references for send rights and dead
        !          1478: names.  When a task receives a send right which it already holds, the
        !          1479: kernel increments the right's user-reference count.  When a task
        !          1480: deallocates a send right, the kernel decrements its user-reference
        !          1481: count, and the task only loses the send right when the count goes to
        !          1482: zero.
        !          1483: 
        !          1484:    Send-once rights always have a user-reference count of one, although
        !          1485: a port can have multiple send-once rights, because each send-once right
        !          1486: held by a task has a different name.  In contrast, when a task holds
        !          1487: send rights or a receive right for a port, the rights share a single
        !          1488: name.
        !          1489: 
        !          1490:    A message body can carry port rights; the 'msgt_name' ('msgtl_name')
        !          1491: field in a type descriptor specifies the type of port right and how the
        !          1492: port right is to be extracted from the caller.  The values
        !          1493: 'MACH_PORT_NULL' and 'MACH_PORT_DEAD' are always valid in place of a
        !          1494: port right in a message body.  In a sent message, the following
        !          1495: 'msgt_name' values denote port rights:
        !          1496: 
        !          1497: 'MACH_MSG_TYPE_MAKE_SEND'
        !          1498:      The message will carry a send right, but the caller must supply a
        !          1499:      receive right.  The send right is created from the receive right,
        !          1500:      and the receive right's make-send count is incremented.
        !          1501: 
        !          1502: 'MACH_MSG_TYPE_COPY_SEND'
        !          1503:      The message will carry a send right, and the caller should supply a
        !          1504:      send right.  The user reference count for the supplied send right
        !          1505:      is not changed.  The caller may also supply a dead name and the
        !          1506:      receiving task will get 'MACH_PORT_DEAD'.
        !          1507: 
        !          1508: 'MACH_MSG_TYPE_MOVE_SEND'
        !          1509:      The message will carry a send right, and the caller should supply a
        !          1510:      send right.  The user reference count for the supplied send right
        !          1511:      is decremented, and the right is destroyed if the count becomes
        !          1512:      zero.  Unless a receive right remains, the name becomes available
        !          1513:      for recycling.  The caller may also supply a dead name, which loses
        !          1514:      a user reference, and the receiving task will get 'MACH_PORT_DEAD'.
        !          1515: 
        !          1516: 'MACH_MSG_TYPE_MAKE_SEND_ONCE'
        !          1517:      The message will carry a send-once right, but the caller must
        !          1518:      supply a receive right.  The send-once right is created from the
        !          1519:      receive right.
        !          1520: 
        !          1521: 'MACH_MSG_TYPE_MOVE_SEND_ONCE'
        !          1522:      The message will carry a send-once right, and the caller should
        !          1523:      supply a send-once right.  The caller loses the supplied send-once
        !          1524:      right.  The caller may also supply a dead name, which loses a user
        !          1525:      reference, and the receiving task will get 'MACH_PORT_DEAD'.
        !          1526: 
        !          1527: 'MACH_MSG_TYPE_MOVE_RECEIVE'
        !          1528:      The message will carry a receive right, and the caller should
        !          1529:      supply a receive right.  The caller loses the supplied receive
        !          1530:      right, but retains any send rights with the same name.
        !          1531: 
        !          1532:    If a message carries a send or send-once right, and the port dies
        !          1533: while the message is in transit, then the receiving task will get
        !          1534: 'MACH_PORT_DEAD' instead of a right.  The following 'msgt_name' values
        !          1535: in a received message indicate that it carries port rights:
        !          1536: 
        !          1537: 'MACH_MSG_TYPE_PORT_SEND'
        !          1538:      This name is an alias for 'MACH_MSG_TYPE_MOVE_SEND'.  The message
        !          1539:      carried a send right.  If the receiving task already has send
        !          1540:      and/or receive rights for the port, then that name for the port
        !          1541:      will be reused.  Otherwise, the new right will have a new name.  If
        !          1542:      the task already has send rights, it gains a user reference for the
        !          1543:      right (unless this would cause the user-reference count to
        !          1544:      overflow).  Otherwise, it acquires the send right, with a
        !          1545:      user-reference count of one.
        !          1546: 
        !          1547: 'MACH_MSG_TYPE_PORT_SEND_ONCE'
        !          1548:      This name is an alias for 'MACH_MSG_TYPE_MOVE_SEND_ONCE'.  The
        !          1549:      message carried a send-once right.  The right will have a new name.
        !          1550: 
        !          1551: 'MACH_MSG_TYPE_PORT_RECEIVE'
        !          1552:      This name is an alias for 'MACH_MSG_TYPE_MOVE_RECEIVE'.  The
        !          1553:      message carried a receive right.  If the receiving task already has
        !          1554:      send rights for the port, then that name for the port will be
        !          1555:      reused.  Otherwise, the right will have a new name.  The make-send
        !          1556:      count of the receive right is reset to zero, but the port retains
        !          1557:      other attributes like queued messages, extant send and send-once
        !          1558:      rights, and requests for port-destroyed and no-senders
        !          1559:      notifications.
        !          1560: 
        !          1561:    When the kernel chooses a new name for a port right, it can choose
        !          1562: any name, other than 'MACH_PORT_NULL' and 'MACH_PORT_DEAD', which is not
        !          1563: currently being used for a port right or dead name.  It might choose a
        !          1564: name which at some previous time denoted a port right, but is currently
        !          1565: unused.
        !          1566: 
        !          1567:    ---------- Footnotes ----------
        !          1568: 
        !          1569:    (1) In the Hurd system, we don't make the assumption that
        !          1570: 'MACH_PORT_NULL' is zero and evaluates to false, but rather compare port
        !          1571: names to 'MACH_PORT_NULL' explicitly
        !          1572: 
        !          1573: 
        !          1574: File: mach.info,  Node: Memory,  Next: Message Send,  Prev: Exchanging Port Rights,  Up: Messaging Interface
        !          1575: 
        !          1576: 4.2.4 Memory
        !          1577: ------------
        !          1578: 
        !          1579: A message body can contain the address of a region in the sender's
        !          1580: address space which should be transferred as part of the message.  The
        !          1581: message carries a logical copy of the memory, but the kernel uses VM
        !          1582: techniques to defer any actual page copies.  Unless the sender or the
        !          1583: receiver modifies the data, the physical pages remain shared.
        !          1584: 
        !          1585:    An out-of-line transfer occurs when the data's type descriptor
        !          1586: specifies 'msgt_inline' as 'FALSE'.  The address of the memory region (a
        !          1587: 'vm_offset_t' or 'vm_address_t') should follow the type descriptor in
        !          1588: the message body.  The type descriptor and the address contribute to the
        !          1589: message's size ('send_size', 'msgh_size').  The out-of-line data does
        !          1590: not contribute to the message's size.
        !          1591: 
        !          1592:    The name, size, and number fields in the type descriptor describe the
        !          1593: type and length of the out-of-line data, not the in-line address.
        !          1594: Out-of-line memory frequently requires long type descriptors
        !          1595: ('mach_msg_type_long_t'), because the 'msgt_number' field is too small
        !          1596: to describe a page of 4K bytes.
        !          1597: 
        !          1598:    Out-of-line memory arrives somewhere in the receiver's address space
        !          1599: as new memory.  It has the same inheritance and protection attributes as
        !          1600: newly 'vm_allocate''d memory.  The receiver has the responsibility of
        !          1601: deallocating (with 'vm_deallocate') the memory when it is no longer
        !          1602: needed.  Security-conscious receivers should exercise caution when using
        !          1603: out-of-line memory from untrustworthy sources, because the memory may be
        !          1604: backed by an unreliable memory manager.
        !          1605: 
        !          1606:    Null out-of-line memory is legal.  If the out-of-line region size is
        !          1607: zero (for example, because 'msgtl_number' is zero), then the region's
        !          1608: specified address is ignored.  A received null out-of-line memory region
        !          1609: always has a zero address.
        !          1610: 
        !          1611:    Unaligned addresses and region sizes that are not page multiples are
        !          1612: legal.  A received message can also contain memory with unaligned
        !          1613: addresses and funny sizes.  In the general case, the first and last
        !          1614: pages in the new memory region in the receiver do not contain only data
        !          1615: from the sender, but are partly zero.(1)  The received address points to
        !          1616: the start of the data in the first page.  This possibility doesn't
        !          1617: complicate deallocation, because 'vm_deallocate' does the right thing,
        !          1618: rounding the start address down and the end address up to deallocate all
        !          1619: arrived pages.
        !          1620: 
        !          1621:    Out-of-line memory has a deallocate option, controlled by the
        !          1622: 'msgt_deallocate' bit.  If it is 'TRUE' and the out-of-line memory
        !          1623: region is not null, then the region is implicitly deallocated from the
        !          1624: sender, as if by 'vm_deallocate'.  In particular, the start and end
        !          1625: addresses are rounded so that every page overlapped by the memory region
        !          1626: is deallocated.  The use of 'msgt_deallocate' effectively changes the
        !          1627: memory copy into a memory movement.  In a received message,
        !          1628: 'msgt_deallocate' is 'TRUE' in type descriptors for out-of-line memory.
        !          1629: 
        !          1630:    Out-of-line memory can carry port rights.
        !          1631: 
        !          1632:    ---------- Footnotes ----------
        !          1633: 
        !          1634:    (1) Sending out-of-line memory with a non-page-aligned address, or a
        !          1635: size which is not a page multiple, works but with a caveat.  The extra
        !          1636: bytes in the first and last page of the received memory are not zeroed,
        !          1637: so the receiver can peek at more data than the sender intended to
        !          1638: transfer.  This might be a security problem for the sender.
        !          1639: 
        !          1640: 
        !          1641: File: mach.info,  Node: Message Send,  Next: Message Receive,  Prev: Memory,  Up: Messaging Interface
        !          1642: 
        !          1643: 4.2.5 Message Send
        !          1644: ------------------
        !          1645: 
        !          1646: The send operation queues a message to a port.  The message carries a
        !          1647: copy of the caller's data.  After the send, the caller can freely modify
        !          1648: the message buffer or the out-of-line memory regions and the message
        !          1649: contents will remain unchanged.
        !          1650: 
        !          1651:    Message delivery is reliable and sequenced.  Messages are not lost,
        !          1652: and messages sent to a port, from a single thread, are received in the
        !          1653: order in which they were sent.
        !          1654: 
        !          1655:    If the destination port's queue is full, then several things can
        !          1656: happen.  If the message is sent to a send-once right ('msgh_remote_port'
        !          1657: carries a send-once right), then the kernel ignores the queue limit and
        !          1658: delivers the message.  Otherwise the caller blocks until there is room
        !          1659: in the queue, unless the 'MACH_SEND_TIMEOUT' or 'MACH_SEND_NOTIFY'
        !          1660: options are used.  If a port has several blocked senders, then any of
        !          1661: them may queue the next message when space in the queue becomes
        !          1662: available, with the proviso that a blocked sender will not be
        !          1663: indefinitely starved.
        !          1664: 
        !          1665:    These options modify 'MACH_SEND_MSG'.  If 'MACH_SEND_MSG' is not also
        !          1666: specified, they are ignored.
        !          1667: 
        !          1668: 'MACH_SEND_TIMEOUT'
        !          1669:      The timeout argument should specify a maximum time (in
        !          1670:      milliseconds) for the call to block before giving up.(1)  If the
        !          1671:      message can't be queued before the timeout interval elapses, then
        !          1672:      the call returns 'MACH_SEND_TIMED_OUT'.  A zero timeout is
        !          1673:      legitimate.
        !          1674: 
        !          1675: 'MACH_SEND_NOTIFY'
        !          1676:      The notify argument should specify a receive right for a notify
        !          1677:      port.  If the send were to block, then instead the message is
        !          1678:      queued, 'MACH_SEND_WILL_NOTIFY' is returned, and a msg-accepted
        !          1679:      notification is requested.  If 'MACH_SEND_TIMEOUT' is also
        !          1680:      specified, then 'MACH_SEND_NOTIFY' doesn't take effect until the
        !          1681:      timeout interval elapses.
        !          1682: 
        !          1683:      With 'MACH_SEND_NOTIFY', a task can forcibly queue to a send right
        !          1684:      one message at a time.  A msg-accepted notification is sent to the
        !          1685:      notify port when another message can be forcibly queued.  If an
        !          1686:      attempt is made to use 'MACH_SEND_NOTIFY' before then, the call
        !          1687:      returns a 'MACH_SEND_NOTIFY_IN_PROGRESS' error.
        !          1688: 
        !          1689:      The msg-accepted notification carries the name of the send right.
        !          1690:      If the send right is deallocated before the msg-accepted
        !          1691:      notification is generated, then the msg-accepted notification
        !          1692:      carries the value 'MACH_PORT_NULL'.  If the destination port is
        !          1693:      destroyed before the notification is generated, then a send-once
        !          1694:      notification is generated instead.
        !          1695: 
        !          1696: 'MACH_SEND_INTERRUPT'
        !          1697:      If specified, the 'mach_msg' call will return
        !          1698:      'MACH_SEND_INTERRUPTED' if a software interrupt aborts the call.
        !          1699:      Otherwise, the send operation will be retried.
        !          1700: 
        !          1701: 'MACH_SEND_CANCEL'
        !          1702:      The notify argument should specify a receive right for a notify
        !          1703:      port.  If the send operation removes the destination port right
        !          1704:      from the caller, and the removed right had a dead-name request
        !          1705:      registered for it, and notify is the notify port for the dead-name
        !          1706:      request, then the dead-name request may be silently canceled
        !          1707:      (instead of resulting in a port-deleted notification).
        !          1708: 
        !          1709:      This option is typically used to cancel a dead-name request made
        !          1710:      with the 'MACH_RCV_NOTIFY' option.  It should only be used as an
        !          1711:      optimization.
        !          1712: 
        !          1713:    The send operation can generate the following return codes.  These
        !          1714: return codes imply that the call did nothing:
        !          1715: 
        !          1716: 'MACH_SEND_MSG_TOO_SMALL'
        !          1717:      The specified send_size was smaller than the minimum size for a
        !          1718:      message.
        !          1719: 
        !          1720: 'MACH_SEND_NO_BUFFER'
        !          1721:      A resource shortage prevented the kernel from allocating a message
        !          1722:      buffer.
        !          1723: 
        !          1724: 'MACH_SEND_INVALID_DATA'
        !          1725:      The supplied message buffer was not readable.
        !          1726: 
        !          1727: 'MACH_SEND_INVALID_HEADER'
        !          1728:      The 'msgh_bits' value was invalid.
        !          1729: 
        !          1730: 'MACH_SEND_INVALID_DEST'
        !          1731:      The 'msgh_remote_port' value was invalid.
        !          1732: 
        !          1733: 'MACH_SEND_INVALID_REPLY'
        !          1734:      The 'msgh_local_port' value was invalid.
        !          1735: 
        !          1736: 'MACH_SEND_INVALID_NOTIFY'
        !          1737:      When using 'MACH_SEND_CANCEL', the notify argument did not denote a
        !          1738:      valid receive right.
        !          1739: 
        !          1740:    These return codes imply that some or all of the message was
        !          1741: destroyed:
        !          1742: 
        !          1743: 'MACH_SEND_INVALID_MEMORY'
        !          1744:      The message body specified out-of-line data that was not readable.
        !          1745: 
        !          1746: 'MACH_SEND_INVALID_RIGHT'
        !          1747:      The message body specified a port right which the caller didn't
        !          1748:      possess.
        !          1749: 
        !          1750: 'MACH_SEND_INVALID_TYPE'
        !          1751:      A type descriptor was invalid.
        !          1752: 
        !          1753: 'MACH_SEND_MSG_TOO_SMALL'
        !          1754:      The last data item in the message ran over the end of the message.
        !          1755: 
        !          1756:    These return codes imply that the message was returned to the caller
        !          1757: with a pseudo-receive operation:
        !          1758: 
        !          1759: 'MACH_SEND_TIMED_OUT'
        !          1760:      The timeout interval expired.
        !          1761: 
        !          1762: 'MACH_SEND_INTERRUPTED'
        !          1763:      A software interrupt occurred.
        !          1764: 
        !          1765: 'MACH_SEND_INVALID_NOTIFY'
        !          1766:      When using 'MACH_SEND_NOTIFY', the notify argument did not denote a
        !          1767:      valid receive right.
        !          1768: 
        !          1769: 'MACH_SEND_NO_NOTIFY'
        !          1770:      A resource shortage prevented the kernel from setting up a
        !          1771:      msg-accepted notification.
        !          1772: 
        !          1773: 'MACH_SEND_NOTIFY_IN_PROGRESS'
        !          1774:      A msg-accepted notification was already requested, and hasn't yet
        !          1775:      been generated.
        !          1776: 
        !          1777:    These return codes imply that the message was queued:
        !          1778: 
        !          1779: 'MACH_SEND_WILL_NOTIFY'
        !          1780:      The message was forcibly queued, and a msg-accepted notification
        !          1781:      was requested.
        !          1782: 
        !          1783: 'MACH_MSG_SUCCESS'
        !          1784:      The message was queued.
        !          1785: 
        !          1786:    Some return codes, like 'MACH_SEND_TIMED_OUT', imply that the message
        !          1787: was almost sent, but could not be queued.  In these situations, the
        !          1788: kernel tries to return the message contents to the caller with a
        !          1789: pseudo-receive operation.  This prevents the loss of port rights or
        !          1790: memory which only exist in the message.  For example, a receive right
        !          1791: which was moved into the message, or out-of-line memory sent with the
        !          1792: deallocate bit.
        !          1793: 
        !          1794:    The pseudo-receive operation is very similar to a normal receive
        !          1795: operation.  The pseudo-receive handles the port rights in the message
        !          1796: header as if they were in the message body.  They are not reversed.
        !          1797: After the pseudo-receive, the message is ready to be resent.  If the
        !          1798: message is not resent, note that out-of-line memory regions may have
        !          1799: moved and some port rights may have changed names.
        !          1800: 
        !          1801:    The pseudo-receive operation may encounter resource shortages.  This
        !          1802: is similar to a 'MACH_RCV_BODY_ERROR' return code from a receive
        !          1803: operation.  When this happens, the normal send return codes are
        !          1804: augmented with the 'MACH_MSG_IPC_SPACE', 'MACH_MSG_VM_SPACE',
        !          1805: 'MACH_MSG_IPC_KERNEL', and 'MACH_MSG_VM_KERNEL' bits to indicate the
        !          1806: nature of the resource shortage.
        !          1807: 
        !          1808:    The queueing of a message carrying receive rights may create a
        !          1809: circular loop of receive rights and messages, which can never be
        !          1810: received.  For example, a message carrying a receive right can be sent
        !          1811: to that receive right.  This situation is not an error, but the kernel
        !          1812: will garbage-collect such loops, destroying the messages and ports
        !          1813: involved.
        !          1814: 
        !          1815:    ---------- Footnotes ----------
        !          1816: 
        !          1817:    (1) If MACH_SEND_TIMEOUT is used without MACH_SEND_INTERRUPT, then
        !          1818: the timeout duration might not be accurate.  When the call is
        !          1819: interrupted and automatically retried, the original timeout is used.  If
        !          1820: interrupts occur frequently enough, the timeout interval might never
        !          1821: expire.
        !          1822: 
        !          1823: 
        !          1824: File: mach.info,  Node: Message Receive,  Next: Atomicity,  Prev: Message Send,  Up: Messaging Interface
        !          1825: 
        !          1826: 4.2.6 Message Receive
        !          1827: ---------------------
        !          1828: 
        !          1829: The receive operation dequeues a message from a port.  The receiving
        !          1830: task acquires the port rights and out-of-line memory regions carried in
        !          1831: the message.
        !          1832: 
        !          1833:    The 'rcv_name' argument specifies a port or port set from which to
        !          1834: receive.  If a port is specified, the caller must possess the receive
        !          1835: right for the port and the port must not be a member of a port set.  If
        !          1836: no message is present, then the call blocks, subject to the
        !          1837: 'MACH_RCV_TIMEOUT' option.
        !          1838: 
        !          1839:    If a port set is specified, the call will receive a message sent to
        !          1840: any of the member ports.  It is permissible for the port set to have no
        !          1841: member ports, and ports may be added and removed while a receive from
        !          1842: the port set is in progress.  The received message can come from any of
        !          1843: the member ports which have messages, with the proviso that a member
        !          1844: port with messages will not be indefinitely starved.  The
        !          1845: 'msgh_local_port' field in the received message header specifies from
        !          1846: which port in the port set the message came.
        !          1847: 
        !          1848:    The 'rcv_size' argument specifies the size of the caller's message
        !          1849: buffer.  The 'mach_msg' call will not receive a message larger than
        !          1850: 'rcv_size'.  Messages that are too large are destroyed, unless the
        !          1851: 'MACH_RCV_LARGE' option is used.
        !          1852: 
        !          1853:    The destination and reply ports are reversed in a received message
        !          1854: header.  The 'msgh_local_port' field names the destination port, from
        !          1855: which the message was received, and the 'msgh_remote_port' field names
        !          1856: the reply port right.  The bits in 'msgh_bits' are also reversed.  The
        !          1857: 'MACH_MSGH_BITS_LOCAL' bits have the value 'MACH_MSG_TYPE_PORT_SEND' if
        !          1858: the message was sent to a send right, and the value
        !          1859: 'MACH_MSG_TYPE_PORT_SEND_ONCE' if was sent to a send-once right.  The
        !          1860: 'MACH_MSGH_BITS_REMOTE' bits describe the reply port right.
        !          1861: 
        !          1862:    A received message can contain port rights and out-of-line memory.
        !          1863: The 'msgh_local_port' field does not receive a port right; the act of
        !          1864: receiving the message destroys the send or send-once right for the
        !          1865: destination port.  The msgh_remote_port field does name a received port
        !          1866: right, the reply port right, and the message body can carry port rights
        !          1867: and memory if 'MACH_MSGH_BITS_COMPLEX' is present in msgh_bits.
        !          1868: Received port rights and memory should be consumed or deallocated in
        !          1869: some fashion.
        !          1870: 
        !          1871:    In almost all cases, 'msgh_local_port' will specify the name of a
        !          1872: receive right, either 'rcv_name' or if 'rcv_name' is a port set, a
        !          1873: member of 'rcv_name'.  If other threads are concurrently manipulating
        !          1874: the receive right, the situation is more complicated.  If the receive
        !          1875: right is renamed during the call, then 'msgh_local_port' specifies the
        !          1876: right's new name.  If the caller loses the receive right after the
        !          1877: message was dequeued from it, then 'mach_msg' will proceed instead of
        !          1878: returning 'MACH_RCV_PORT_DIED'.  If the receive right was destroyed,
        !          1879: then 'msgh_local_port' specifies 'MACH_PORT_DEAD'.  If the receive right
        !          1880: still exists, but isn't held by the caller, then 'msgh_local_port'
        !          1881: specifies 'MACH_PORT_NULL'.
        !          1882: 
        !          1883:    Received messages are stamped with a sequence number, taken from the
        !          1884: port from which the message was received.  (Messages received from a
        !          1885: port set are stamped with a sequence number from the appropriate member
        !          1886: port.)  Newly created ports start with a zero sequence number, and the
        !          1887: sequence number is reset to zero whenever the port's receive right moves
        !          1888: between tasks.  When a message is dequeued from the port, it is stamped
        !          1889: with the port's sequence number and the port's sequence number is then
        !          1890: incremented.  The dequeue and increment operations are atomic, so that
        !          1891: multiple threads receiving messages from a port can use the 'msgh_seqno'
        !          1892: field to reconstruct the original order of the messages.
        !          1893: 
        !          1894:    These options modify 'MACH_RCV_MSG'.  If 'MACH_RCV_MSG' is not also
        !          1895: specified, they are ignored.
        !          1896: 
        !          1897: 'MACH_RCV_TIMEOUT'
        !          1898:      The timeout argument should specify a maximum time (in
        !          1899:      milliseconds) for the call to block before giving up.(1)  If no
        !          1900:      message arrives before the timeout interval elapses, then the call
        !          1901:      returns 'MACH_RCV_TIMED_OUT'.  A zero timeout is legitimate.
        !          1902: 
        !          1903: 'MACH_RCV_NOTIFY'
        !          1904:      The notify argument should specify a receive right for a notify
        !          1905:      port.  If receiving the reply port creates a new port right in the
        !          1906:      caller, then the notify port is used to request a dead-name
        !          1907:      notification for the new port right.
        !          1908: 
        !          1909: 'MACH_RCV_INTERRUPT'
        !          1910:      If specified, the 'mach_msg' call will return
        !          1911:      'MACH_RCV_INTERRUPTED' if a software interrupt aborts the call.
        !          1912:      Otherwise, the receive operation will be retried.
        !          1913: 
        !          1914: 'MACH_RCV_LARGE'
        !          1915:      If the message is larger than 'rcv_size', then the message remains
        !          1916:      queued instead of being destroyed.  The call returns
        !          1917:      'MACH_RCV_TOO_LARGE' and the actual size of the message is returned
        !          1918:      in the 'msgh_size' field of the message header.
        !          1919: 
        !          1920:    The receive operation can generate the following return codes.  These
        !          1921: return codes imply that the call did not dequeue a message:
        !          1922: 
        !          1923: 'MACH_RCV_INVALID_NAME'
        !          1924:      The specified 'rcv_name' was invalid.
        !          1925: 
        !          1926: 'MACH_RCV_IN_SET'
        !          1927:      The specified port was a member of a port set.
        !          1928: 
        !          1929: 'MACH_RCV_TIMED_OUT'
        !          1930:      The timeout interval expired.
        !          1931: 
        !          1932: 'MACH_RCV_INTERRUPTED'
        !          1933:      A software interrupt occurred.
        !          1934: 
        !          1935: 'MACH_RCV_PORT_DIED'
        !          1936:      The caller lost the rights specified by 'rcv_name'.
        !          1937: 
        !          1938: 'MACH_RCV_PORT_CHANGED'
        !          1939:      'rcv_name' specified a receive right which was moved into a port
        !          1940:      set during the call.
        !          1941: 
        !          1942: 'MACH_RCV_TOO_LARGE'
        !          1943:      When using 'MACH_RCV_LARGE', and the message was larger than
        !          1944:      'rcv_size'.  The message is left queued, and its actual size is
        !          1945:      returned in the 'msgh_size' field of the message buffer.
        !          1946: 
        !          1947:    These return codes imply that a message was dequeued and destroyed:
        !          1948: 
        !          1949: 'MACH_RCV_HEADER_ERROR'
        !          1950:      A resource shortage prevented the reception of the port rights in
        !          1951:      the message header.
        !          1952: 
        !          1953: 'MACH_RCV_INVALID_NOTIFY'
        !          1954:      When using 'MACH_RCV_NOTIFY', the notify argument did not denote a
        !          1955:      valid receive right.
        !          1956: 
        !          1957: 'MACH_RCV_TOO_LARGE'
        !          1958:      When not using 'MACH_RCV_LARGE', a message larger than 'rcv_size'
        !          1959:      was dequeued and destroyed.
        !          1960: 
        !          1961:    In these situations, when a message is dequeued and then destroyed,
        !          1962: the reply port and all port rights and memory in the message body are
        !          1963: destroyed.  However, the caller receives the message's header, with all
        !          1964: fields correct, including the destination port but excepting the reply
        !          1965: port, which is 'MACH_PORT_NULL'.
        !          1966: 
        !          1967:    These return codes imply that a message was received:
        !          1968: 
        !          1969: 'MACH_RCV_BODY_ERROR'
        !          1970:      A resource shortage prevented the reception of a port right or
        !          1971:      out-of-line memory region in the message body.  The message header,
        !          1972:      including the reply port, is correct.  The kernel attempts to
        !          1973:      transfer all port rights and memory regions in the body, and only
        !          1974:      destroys those that can't be transferred.
        !          1975: 
        !          1976: 'MACH_RCV_INVALID_DATA'
        !          1977:      The specified message buffer was not writable.  The calling task
        !          1978:      did successfully receive the port rights and out-of-line memory
        !          1979:      regions in the message.
        !          1980: 
        !          1981: 'MACH_MSG_SUCCESS'
        !          1982:      A message was received.
        !          1983: 
        !          1984:    Resource shortages can occur after a message is dequeued, while
        !          1985: transferring port rights and out-of-line memory regions to the receiving
        !          1986: task.  The 'mach_msg' call returns 'MACH_RCV_HEADER_ERROR' or
        !          1987: 'MACH_RCV_BODY_ERROR' in this situation.  These return codes always
        !          1988: carry extra bits (bitwise-ored) that indicate the nature of the resource
        !          1989: shortage:
        !          1990: 
        !          1991: 'MACH_MSG_IPC_SPACE'
        !          1992:      There was no room in the task's IPC name space for another port
        !          1993:      name.
        !          1994: 
        !          1995: 'MACH_MSG_VM_SPACE'
        !          1996:      There was no room in the task's VM address space for an out-of-line
        !          1997:      memory region.
        !          1998: 
        !          1999: 'MACH_MSG_IPC_KERNEL'
        !          2000:      A kernel resource shortage prevented the reception of a port right.
        !          2001: 
        !          2002: 'MACH_MSG_VM_KERNEL'
        !          2003:      A kernel resource shortage prevented the reception of an
        !          2004:      out-of-line memory region.
        !          2005: 
        !          2006:    If a resource shortage prevents the reception of a port right, the
        !          2007: port right is destroyed and the caller sees the name 'MACH_PORT_NULL'.
        !          2008: If a resource shortage prevents the reception of an out-of-line memory
        !          2009: region, the region is destroyed and the caller receives a zero address.
        !          2010: In addition, the 'msgt_size' ('msgtl_size') field in the data's type
        !          2011: descriptor is changed to zero.  If a resource shortage prevents the
        !          2012: reception of out-of-line memory carrying port rights, then the port
        !          2013: rights are always destroyed if the memory region can not be received.  A
        !          2014: task never receives port rights or memory regions that it isn't told
        !          2015: about.
        !          2016: 
        !          2017:    ---------- Footnotes ----------
        !          2018: 
        !          2019:    (1) If MACH_RCV_TIMEOUT is used without MACH_RCV_INTERRUPT, then the
        !          2020: timeout duration might not be accurate.  When the call is interrupted
        !          2021: and automatically retried, the original timeout is used.  If interrupts
        !          2022: occur frequently enough, the timeout interval might never expire.
        !          2023: 
        !          2024: 
        !          2025: File: mach.info,  Node: Atomicity,  Prev: Message Receive,  Up: Messaging Interface
        !          2026: 
        !          2027: 4.2.7 Atomicity
        !          2028: ---------------
        !          2029: 
        !          2030: The 'mach_msg' call handles port rights in a message header atomically.
        !          2031: Port rights and out-of-line memory in a message body do not enjoy this
        !          2032: atomicity guarantee.  The message body may be processed front-to-back,
        !          2033: back-to-front, first out-of-line memory then port rights, in some random
        !          2034: order, or even atomically.
        !          2035: 
        !          2036:    For example, consider sending a message with the destination port
        !          2037: specified as 'MACH_MSG_TYPE_MOVE_SEND' and the reply port specified as
        !          2038: 'MACH_MSG_TYPE_COPY_SEND'.  The same send right, with one
        !          2039: user-reference, is supplied for both the 'msgh_remote_port' and
        !          2040: 'msgh_local_port' fields.  Because 'mach_msg' processes the message
        !          2041: header atomically, this succeeds.  If 'msgh_remote_port' were processed
        !          2042: before 'msgh_local_port', then 'mach_msg' would return
        !          2043: 'MACH_SEND_INVALID_REPLY' in this situation.
        !          2044: 
        !          2045:    On the other hand, suppose the destination and reply port are both
        !          2046: specified as 'MACH_MSG_TYPE_MOVE_SEND', and again the same send right
        !          2047: with one user-reference is supplied for both.  Now the send operation
        !          2048: fails, but because it processes the header atomically, mach_msg can
        !          2049: return either 'MACH_SEND_INVALID_DEST' or 'MACH_SEND_INVALID_REPLY'.
        !          2050: 
        !          2051:    For example, consider receiving a message at the same time another
        !          2052: thread is deallocating the destination receive right.  Suppose the reply
        !          2053: port field carries a send right for the destination port.  If the
        !          2054: deallocation happens before the dequeuing, then the receiver gets
        !          2055: 'MACH_RCV_PORT_DIED'.  If the deallocation happens after the receive,
        !          2056: then the 'msgh_local_port' and the 'msgh_remote_port' fields both
        !          2057: specify the same right, which becomes a dead name when the receive right
        !          2058: is deallocated.  If the deallocation happens between the dequeue and the
        !          2059: receive, then the 'msgh_local_port' and 'msgh_remote_port' fields both
        !          2060: specify 'MACH_PORT_DEAD'.  Because the header is processed atomically,
        !          2061: it is not possible for just one of the two fields to hold
        !          2062: 'MACH_PORT_DEAD'.
        !          2063: 
        !          2064:    The 'MACH_RCV_NOTIFY' option provides a more likely example.  Suppose
        !          2065: a message carrying a send-once right reply port is received with
        !          2066: 'MACH_RCV_NOTIFY' at the same time the reply port is destroyed.  If the
        !          2067: reply port is destroyed first, then 'msgh_remote_port' specifies
        !          2068: 'MACH_PORT_DEAD' and the kernel does not generate a dead-name
        !          2069: notification.  If the reply port is destroyed after it is received, then
        !          2070: 'msgh_remote_port' specifies a dead name for which the kernel generates
        !          2071: a dead-name notification.  It is not possible to receive the reply port
        !          2072: right and have it turn into a dead name before the dead-name
        !          2073: notification is requested; as part of the message header the reply port
        !          2074: is received atomically.
        !          2075: 
        !          2076: 
        !          2077: File: mach.info,  Node: Port Manipulation Interface,  Prev: Messaging Interface,  Up: Inter Process Communication
        !          2078: 
        !          2079: 4.3 Port Manipulation Interface
        !          2080: ===============================
        !          2081: 
        !          2082: This section describes the interface to create, destroy and manipulate
        !          2083: ports, port rights and port sets.
        !          2084: 
        !          2085:  -- Data type: ipc_space_t
        !          2086:      This is a 'task_t' (and as such a 'mach_port_t'), which holds a
        !          2087:      port name associated with a port that represents an IPC space in
        !          2088:      the kernel.  An IPC space is used by the kernel to manage the port
        !          2089:      names and rights available to a task.  The IPC space doesn't get a
        !          2090:      port name of its own.  Instead the port name of the task containing
        !          2091:      the IPC space is used to name the IPC space of the task (as is
        !          2092:      indicated by the fact that the type of 'ipc_space_t' is actually
        !          2093:      'task_t').
        !          2094: 
        !          2095:      The IPC spaces of tasks are the only ones accessible outside of the
        !          2096:      kernel.
        !          2097: 
        !          2098: * Menu:
        !          2099: 
        !          2100: * Port Creation::                 How to create new ports and port sets.
        !          2101: * Port Destruction::              How to destroy ports and port sets.
        !          2102: * Port Names::                    How to query and manipulate port names.
        !          2103: * Port Rights::                   How to work with port rights.
        !          2104: * Ports and other Tasks::         How to move rights between tasks.
        !          2105: * Receive Rights::                How to work with receive rights.
        !          2106: * Port Sets::                     How to work with port sets.
        !          2107: * Request Notifications::         How to request notifications for events.
        !          2108: 
        !          2109: 
        !          2110: File: mach.info,  Node: Port Creation,  Next: Port Destruction,  Up: Port Manipulation Interface
        !          2111: 
        !          2112: 4.3.1 Port Creation
        !          2113: -------------------
        !          2114: 
        !          2115:  -- Function: kern_return_t mach_port_allocate (ipc_space_t TASK,
        !          2116:           mach_port_right_t RIGHT, mach_port_t *NAME)
        !          2117:      The 'mach_port_allocate' function creates a new right in the
        !          2118:      specified task.  The new right's name is returned in NAME, which
        !          2119:      may be any name that wasn't in use.
        !          2120: 
        !          2121:      The RIGHT argument takes the following values:
        !          2122: 
        !          2123:      'MACH_PORT_RIGHT_RECEIVE'
        !          2124:           'mach_port_allocate' creates a port.  The new port is not a
        !          2125:           member of any port set.  It doesn't have any extant send or
        !          2126:           send-once rights.  Its make-send count is zero, its sequence
        !          2127:           number is zero, its queue limit is 'MACH_PORT_QLIMIT_DEFAULT',
        !          2128:           and it has no queued messages.  NAME denotes the receive right
        !          2129:           for the new port.
        !          2130: 
        !          2131:           TASK does not hold send rights for the new port, only the
        !          2132:           receive right.  'mach_port_insert_right' and
        !          2133:           'mach_port_extract_right' can be used to convert the receive
        !          2134:           right into a combined send/receive right.
        !          2135: 
        !          2136:      'MACH_PORT_RIGHT_PORT_SET'
        !          2137:           'mach_port_allocate' creates a port set.  The new port set has
        !          2138:           no members.
        !          2139: 
        !          2140:      'MACH_PORT_RIGHT_DEAD_NAME'
        !          2141:           'mach_port_allocate' creates a dead name.  The new dead name
        !          2142:           has one user reference.
        !          2143: 
        !          2144:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2145:      'KERN_INVALID_TASK' if TASK was invalid, 'KERN_INVALID_VALUE' if
        !          2146:      RIGHT was invalid, 'KERN_NO_SPACE' if there was no room in TASK's
        !          2147:      IPC name space for another right and 'KERN_RESOURCE_SHORTAGE' if
        !          2148:      the kernel ran out of memory.
        !          2149: 
        !          2150:      The 'mach_port_allocate' call is actually an RPC to TASK, normally
        !          2151:      a send right for a task port, but potentially any send right.  In
        !          2152:      addition to the normal diagnostic return codes from the call's
        !          2153:      server (normally the kernel), the call may return 'mach_msg' return
        !          2154:      codes.
        !          2155: 
        !          2156:  -- Function: mach_port_t mach_reply_port ()
        !          2157:      The 'mach_reply_port' system call creates a reply port in the
        !          2158:      calling task.
        !          2159: 
        !          2160:      'mach_reply_port' creates a port, giving the calling task the
        !          2161:      receive right for the port.  The call returns the name of the new
        !          2162:      receive right.
        !          2163: 
        !          2164:      This is very much like creating a receive right with the
        !          2165:      'mach_port_allocate' call, with two differences.  First,
        !          2166:      'mach_reply_port' is a system call and not an RPC (which requires a
        !          2167:      reply port).  Second, the port created by 'mach_reply_port' may be
        !          2168:      optimized for use as a reply port.
        !          2169: 
        !          2170:      The function returns 'MACH_PORT_NULL' if a resource shortage
        !          2171:      prevented the creation of the receive right.
        !          2172: 
        !          2173:  -- Function: kern_return_t mach_port_allocate_name (ipc_space_t TASK,
        !          2174:           mach_port_right_t RIGHT, mach_port_t NAME)
        !          2175:      The function 'mach_port_allocate_name' creates a new right in the
        !          2176:      specified task, with a specified name for the new right.  NAME must
        !          2177:      not already be in use for some right, and it can't be the reserved
        !          2178:      values 'MACH_PORT_NULL' and 'MACH_PORT_DEAD'.
        !          2179: 
        !          2180:      The RIGHT argument takes the following values:
        !          2181: 
        !          2182:      'MACH_PORT_RIGHT_RECEIVE'
        !          2183:           'mach_port_allocate_name' creates a port.  The new port is not
        !          2184:           a member of any port set.  It doesn't have any extant send or
        !          2185:           send-once rights.  Its make-send count is zero, its sequence
        !          2186:           number is zero, its queue limit is 'MACH_PORT_QLIMIT_DEFAULT',
        !          2187:           and it has no queued messages.  NAME denotes the receive right
        !          2188:           for the new port.
        !          2189: 
        !          2190:           TASK does not hold send rights for the new port, only the
        !          2191:           receive right.  'mach_port_insert_right' and
        !          2192:           'mach_port_extract_right' can be used to convert the receive
        !          2193:           right into a combined send/receive right.
        !          2194: 
        !          2195:      'MACH_PORT_RIGHT_PORT_SET'
        !          2196:           'mach_port_allocate_name' creates a port set.  The new port
        !          2197:           set has no members.
        !          2198: 
        !          2199:      'MACH_PORT_RIGHT_DEAD_NAME'
        !          2200:           'mach_port_allocate_name' creates a new dead name.  The new
        !          2201:           dead name has one user reference.
        !          2202: 
        !          2203:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2204:      'KERN_INVALID_TASK' if TASK was invalid, 'KERN_INVALID_VALUE' if
        !          2205:      RIGHT was invalid or NAME was 'MACH_PORT_NULL' or 'MACH_PORT_DEAD',
        !          2206:      'KERN_NAME_EXISTS' if NAME was already in use for a port right and
        !          2207:      'KERN_RESOURCE_SHORTAGE' if the kernel ran out of memory.
        !          2208: 
        !          2209:      The 'mach_port_allocate_name' call is actually an RPC to TASK,
        !          2210:      normally a send right for a task port, but potentially any send
        !          2211:      right.  In addition to the normal diagnostic return codes from the
        !          2212:      call's server (normally the kernel), the call may return 'mach_msg'
        !          2213:      return codes.
        !          2214: 
        !          2215: 
        !          2216: File: mach.info,  Node: Port Destruction,  Next: Port Names,  Prev: Port Creation,  Up: Port Manipulation Interface
        !          2217: 
        !          2218: 4.3.2 Port Destruction
        !          2219: ----------------------
        !          2220: 
        !          2221:  -- Function: kern_return_t mach_port_deallocate (ipc_space_t TASK,
        !          2222:           mach_port_t NAME)
        !          2223:      The function 'mach_port_deallocate' releases a user reference for a
        !          2224:      right in TASK's IPC name space.  It allows a task to release a user
        !          2225:      reference for a send or send-once right without failing if the port
        !          2226:      has died and the right is now actually a dead name.
        !          2227: 
        !          2228:      If NAME denotes a dead name, send right, or send-once right, then
        !          2229:      the right loses one user reference.  If it only had one user
        !          2230:      reference, then the right is destroyed.
        !          2231: 
        !          2232:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2233:      'KERN_INVALID_TASK' if TASK was invalid, 'KERN_INVALID_NAME' if
        !          2234:      NAME did not denote a right and 'KERN_INVALID_RIGHT' if NAME
        !          2235:      denoted an invalid right.
        !          2236: 
        !          2237:      The 'mach_port_deallocate' call is actually an RPC to TASK,
        !          2238:      normally a send right for a task port, but potentially any send
        !          2239:      right.  In addition to the normal diagnostic return codes from the
        !          2240:      call's server (normally the kernel), the call may return 'mach_msg'
        !          2241:      return codes.
        !          2242: 
        !          2243:  -- Function: kern_return_t mach_port_destroy (ipc_space_t TASK,
        !          2244:           mach_port_t NAME)
        !          2245:      The function 'mach_port_destroy' deallocates all rights denoted by
        !          2246:      a name.  The name becomes immediately available for reuse.
        !          2247: 
        !          2248:      For most purposes, 'mach_port_mod_refs' and 'mach_port_deallocate'
        !          2249:      are preferable.
        !          2250: 
        !          2251:      If NAME denotes a port set, then all members of the port set are
        !          2252:      implicitly removed from the port set.
        !          2253: 
        !          2254:      If NAME denotes a receive right that is a member of a port set, the
        !          2255:      receive right is implicitly removed from the port set.  If there is
        !          2256:      a port-destroyed request registered for the port, then the receive
        !          2257:      right is not actually destroyed, but instead is sent in a
        !          2258:      port-destroyed notification to the backup port.  If there is no
        !          2259:      registered port-destroyed request, remaining messages queued to the
        !          2260:      port are destroyed and extant send and send-once rights turn into
        !          2261:      dead names.  If those send and send-once rights have dead-name
        !          2262:      requests registered, then dead-name notifications are generated for
        !          2263:      them.
        !          2264: 
        !          2265:      If NAME denotes a send-once right, then the send-once right is used
        !          2266:      to produce a send-once notification for the port.
        !          2267: 
        !          2268:      If NAME denotes a send-once, send, and/or receive right, and it has
        !          2269:      a dead-name request registered, then the registered send-once right
        !          2270:      is used to produce a port-deleted notification for the name.
        !          2271: 
        !          2272:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2273:      'KERN_INVALID_TASK' if TASK was invalid, 'KERN_INVALID_NAME' if
        !          2274:      NAME did not denote a right.
        !          2275: 
        !          2276:      The 'mach_port_destroy' call is actually an RPC to TASK, normally a
        !          2277:      send right for a task port, but potentially any send right.  In
        !          2278:      addition to the normal diagnostic return codes from the call's
        !          2279:      server (normally the kernel), the call may return 'mach_msg' return
        !          2280:      codes.
        !          2281: 
        !          2282: 
        !          2283: File: mach.info,  Node: Port Names,  Next: Port Rights,  Prev: Port Destruction,  Up: Port Manipulation Interface
        !          2284: 
        !          2285: 4.3.3 Port Names
        !          2286: ----------------
        !          2287: 
        !          2288:  -- Function: kern_return_t mach_port_names (ipc_space_t TASK,
        !          2289:           mach_port_array_t *NAMES, mach_msg_type_number_t *NCOUNT,
        !          2290:           mach_port_type_array_t *TYPES, mach_msg_type_number_t *TCOUNT)
        !          2291:      The function 'mach_port_names' returns information about TASK's
        !          2292:      port name space.  For each name, it also returns what type of
        !          2293:      rights TASK holds.  (The same information returned by
        !          2294:      'mach_port_type'.)  NAMES and TYPES are arrays that are
        !          2295:      automatically allocated when the reply message is received.  The
        !          2296:      user should 'vm_deallocate' them when the data is no longer needed.
        !          2297: 
        !          2298:      'mach_port_names' will return in NAMES the names of the ports, port
        !          2299:      sets, and dead names in the task's port name space, in no
        !          2300:      particular order and in NCOUNT the number of names returned.  It
        !          2301:      will return in TYPES the type of each corresponding name, which
        !          2302:      indicates what kind of rights the task holds with that name.
        !          2303:      TCOUNT should be the same as NCOUNT.
        !          2304: 
        !          2305:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2306:      'KERN_INVALID_TASK' if TASK was invalid, 'KERN_RESOURCE_SHORTAGE'
        !          2307:      if the kernel ran out of memory.
        !          2308: 
        !          2309:      The 'mach_port_names' call is actually an RPC to TASK, normally a
        !          2310:      send right for a task port, but potentially any send right.  In
        !          2311:      addition to the normal diagnostic return codes from the call's
        !          2312:      server (normally the kernel), the call may return 'mach_msg' return
        !          2313:      codes.
        !          2314: 
        !          2315:  -- Function: kern_return_t mach_port_type (ipc_space_t TASK,
        !          2316:           mach_port_t NAME, mach_port_type_t *PTYPE)
        !          2317:      The function 'mach_port_type' returns information about TASK's
        !          2318:      rights for a specific name in its port name space.  The returned
        !          2319:      PTYPE is a bitmask indicating what rights TASK holds for the port,
        !          2320:      port set or dead name.  The bitmask is composed of the following
        !          2321:      bits:
        !          2322: 
        !          2323:      'MACH_PORT_TYPE_SEND'
        !          2324:           The name denotes a send right.
        !          2325: 
        !          2326:      'MACH_PORT_TYPE_RECEIVE'
        !          2327:           The name denotes a receive right.
        !          2328: 
        !          2329:      'MACH_PORT_TYPE_SEND_ONCE'
        !          2330:           The name denotes a send-once right.
        !          2331: 
        !          2332:      'MACH_PORT_TYPE_PORT_SET'
        !          2333:           The name denotes a port set.
        !          2334: 
        !          2335:      'MACH_PORT_TYPE_DEAD_NAME'
        !          2336:           The name is a dead name.
        !          2337: 
        !          2338:      'MACH_PORT_TYPE_DNREQUEST'
        !          2339:           A dead-name request has been registered for the right.
        !          2340: 
        !          2341:      'MACH_PORT_TYPE_MAREQUEST'
        !          2342:           A msg-accepted request for the right is pending.
        !          2343: 
        !          2344:      'MACH_PORT_TYPE_COMPAT'
        !          2345:           The port right was created in the compatibility mode.
        !          2346: 
        !          2347:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2348:      'KERN_INVALID_TASK' if TASK was invalid and 'KERN_INVALID_NAME' if
        !          2349:      NAME did not denote a right.
        !          2350: 
        !          2351:      The 'mach_port_type' call is actually an RPC to TASK, normally a
        !          2352:      send right for a task port, but potentially any send right.  In
        !          2353:      addition to the normal diagnostic return codes from the call's
        !          2354:      server (normally the kernel), the call may return 'mach_msg' return
        !          2355:      codes.
        !          2356: 
        !          2357:  -- Function: kern_return_t mach_port_rename (ipc_space_t TASK,
        !          2358:           mach_port_t OLD_NAME, mach_port_t NEW_NAME)
        !          2359:      The function 'mach_port_rename' changes the name by which a port,
        !          2360:      port set, or dead name is known to TASK.  OLD_NAME is the original
        !          2361:      name and NEW_NAME the new name for the port right.  NEW_NAME must
        !          2362:      not already be in use, and it can't be the distinguished values
        !          2363:      'MACH_PORT_NULL' and 'MACH_PORT_DEAD'.
        !          2364: 
        !          2365:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2366:      'KERN_INVALID_TASK' if TASK was invalid, 'KERN_INVALID_NAME' if
        !          2367:      OLD_NAME did not denote a right, 'KERN_INVALID_VALUE' if NEW_NAME
        !          2368:      was 'MACH_PORT_NULL' or 'MACH_PORT_DEAD', 'KERN_NAME_EXISTS' if
        !          2369:      'new_name' already denoted a right and 'KERN_RESOURCE_SHORTAGE' if
        !          2370:      the kernel ran out of memory.
        !          2371: 
        !          2372:      The 'mach_port_rename' call is actually an RPC to TASK, normally a
        !          2373:      send right for a task port, but potentially any send right.  In
        !          2374:      addition to the normal diagnostic return codes from the call's
        !          2375:      server (normally the kernel), the call may return 'mach_msg' return
        !          2376:      codes.
        !          2377: 
        !          2378: 
        !          2379: File: mach.info,  Node: Port Rights,  Next: Ports and other Tasks,  Prev: Port Names,  Up: Port Manipulation Interface
        !          2380: 
        !          2381: 4.3.4 Port Rights
        !          2382: -----------------
        !          2383: 
        !          2384:  -- Function: kern_return_t mach_port_get_refs (ipc_space_t TASK,
        !          2385:           mach_port_t NAME, mach_port_right_t RIGHT,
        !          2386:           mach_port_urefs_t *REFS)
        !          2387:      The function 'mach_port_get_refs' returns the number of user
        !          2388:      references a task has for a right.
        !          2389: 
        !          2390:      The RIGHT argument takes the following values:
        !          2391:         * 'MACH_PORT_RIGHT_SEND'
        !          2392:         * 'MACH_PORT_RIGHT_RECEIVE'
        !          2393:         * 'MACH_PORT_RIGHT_SEND_ONCE'
        !          2394:         * 'MACH_PORT_RIGHT_PORT_SET'
        !          2395:         * 'MACH_PORT_RIGHT_DEAD_NAME'
        !          2396: 
        !          2397:      If NAME denotes a right, but not the type of right specified, then
        !          2398:      zero is returned.  Otherwise a positive number of user references
        !          2399:      is returned.  Note that a name may simultaneously denote send and
        !          2400:      receive rights.
        !          2401: 
        !          2402:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2403:      'KERN_INVALID_TASK' if TASK was invalid, 'KERN_INVALID_VALUE' if
        !          2404:      RIGHT was invalid and 'KERN_INVALID_NAME' if NAME did not denote a
        !          2405:      right.
        !          2406: 
        !          2407:      The 'mach_port_get_refs' call is actually an RPC to TASK, normally
        !          2408:      a send right for a task port, but potentially any send right.  In
        !          2409:      addition to the normal diagnostic return codes from the call's
        !          2410:      server (normally the kernel), the call may return 'mach_msg' return
        !          2411:      codes.
        !          2412: 
        !          2413:  -- Function: kern_return_t mach_port_mod_refs (ipc_space_t TASK,
        !          2414:           mach_port_t NAME, mach_port_right_t RIGHT,
        !          2415:           mach_port_delta_t DELTA)
        !          2416:      The function 'mach_port_mod_refs' requests that the number of user
        !          2417:      references a task has for a right be changed.  This results in the
        !          2418:      right being destroyed, if the number of user references is changed
        !          2419:      to zero.  The task holding the right is TASK, NAME should denote
        !          2420:      the specified right.  RIGHT denotes the type of right being
        !          2421:      modified.  DELTA is the signed change to the number of user
        !          2422:      references.
        !          2423: 
        !          2424:      The RIGHT argument takes the following values:
        !          2425:         * 'MACH_PORT_RIGHT_SEND'
        !          2426:         * 'MACH_PORT_RIGHT_RECEIVE'
        !          2427:         * 'MACH_PORT_RIGHT_SEND_ONCE'
        !          2428:         * 'MACH_PORT_RIGHT_PORT_SET'
        !          2429:         * 'MACH_PORT_RIGHT_DEAD_NAME'
        !          2430: 
        !          2431:      The number of user references for the right is changed by the
        !          2432:      amount DELTA, subject to the following restrictions: port sets,
        !          2433:      receive rights, and send-once rights may only have one user
        !          2434:      reference.  The resulting number of user references can't be
        !          2435:      negative.  If the resulting number of user references is zero, the
        !          2436:      effect is to deallocate the right.  For dead names and send rights,
        !          2437:      there is an implementation-defined maximum number of user
        !          2438:      references.
        !          2439: 
        !          2440:      If the call destroys the right, then the effect is as described for
        !          2441:      'mach_port_destroy', with the exception that 'mach_port_destroy'
        !          2442:      simultaneously destroys all the rights denoted by a name, while
        !          2443:      'mach_port_mod_refs' can only destroy one right.  The name will be
        !          2444:      available for reuse if it only denoted the one right.
        !          2445: 
        !          2446:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2447:      'KERN_INVALID_TASK' if TASK was invalid, 'KERN_INVALID_VALUE' if
        !          2448:      RIGHT was invalid or the user-reference count would become
        !          2449:      negative, 'KERN_INVALID_NAME' if NAME did not denote a right,
        !          2450:      'KERN_INVALID_RIGHT' if NAME denoted a right, but not the specified
        !          2451:      right and 'KERN_UREFS_OVERFLOW' if the user-reference count would
        !          2452:      overflow.
        !          2453: 
        !          2454:      The 'mach_port_mod_refs' call is actually an RPC to TASK, normally
        !          2455:      a send right for a task port, but potentially any send right.  In
        !          2456:      addition to the normal diagnostic return codes from the call's
        !          2457:      server (normally the kernel), the call may return 'mach_msg' return
        !          2458:      codes.
        !          2459: 
        !          2460: 
        !          2461: File: mach.info,  Node: Ports and other Tasks,  Next: Receive Rights,  Prev: Port Rights,  Up: Port Manipulation Interface
        !          2462: 
        !          2463: 4.3.5 Ports and other Tasks
        !          2464: ---------------------------
        !          2465: 
        !          2466:  -- Function: kern_return_t mach_port_insert_right (ipc_space_t TASK,
        !          2467:           mach_port_t NAME, mach_port_t RIGHT,
        !          2468:           mach_msg_type_name_t RIGHT_TYPE)
        !          2469:      The function MACH_PORT_INSERT_RIGHT inserts into TASK the caller's
        !          2470:      right for a port, using a specified name for the right in the
        !          2471:      target task.
        !          2472: 
        !          2473:      The specified NAME can't be one of the reserved values
        !          2474:      'MACH_PORT_NULL' or 'MACH_PORT_DEAD'.  The RIGHT can't be
        !          2475:      'MACH_PORT_NULL' or 'MACH_PORT_DEAD'.
        !          2476: 
        !          2477:      The argument RIGHT_TYPE specifies a right to be inserted and how
        !          2478:      that right should be extracted from the caller.  It should be a
        !          2479:      value appropriate for MSGT_NAME; see 'mach_msg'.
        !          2480: 
        !          2481:      If RIGHT_TYPE is 'MACH_MSG_TYPE_MAKE_SEND',
        !          2482:      'MACH_MSG_TYPE_MOVE_SEND', or 'MACH_MSG_TYPE_COPY_SEND', then a
        !          2483:      send right is inserted.  If the target already holds send or
        !          2484:      receive rights for the port, then NAME should denote those rights
        !          2485:      in the target.  Otherwise, NAME should be unused in the target.  If
        !          2486:      the target already has send rights, then those send rights gain an
        !          2487:      additional user reference.  Otherwise, the target gains a send
        !          2488:      right, with a user reference count of one.
        !          2489: 
        !          2490:      If RIGHT_TYPE is 'MACH_MSG_TYPE_MAKE_SEND_ONCE' or
        !          2491:      'MACH_MSG_TYPE_MOVE_SEND_ONCE', then a send-once right is inserted.
        !          2492:      The name should be unused in the target.  The target gains a
        !          2493:      send-once right.
        !          2494: 
        !          2495:      If RIGHT_TYPE is 'MACH_MSG_TYPE_MOVE_RECEIVE', then a receive right
        !          2496:      is inserted.  If the target already holds send rights for the port,
        !          2497:      then name should denote those rights in the target.  Otherwise,
        !          2498:      name should be unused in the target.  The receive right is moved
        !          2499:      into the target task.
        !          2500: 
        !          2501:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2502:      'KERN_INVALID_TASK' if TASK was invalid, 'KERN_INVALID_VALUE' if
        !          2503:      RIGHT was not a port right or NAME was 'MACH_PORT_NULL' or
        !          2504:      'MACH_PORT_DEAD', 'KERN_NAME_EXISTS' if NAME already denoted a
        !          2505:      right, 'KERN_INVALID_CAPABILITY' if RIGHT was 'MACH_PORT_NULL' or
        !          2506:      'MACH_PORT_DEAD' 'KERN_RIGHT_EXISTS' if TASK already had rights for
        !          2507:      the port, with a different name, 'KERN_UREFS_OVERFLOW' if the
        !          2508:      user-reference count would overflow and 'KERN_RESOURCE_SHORTAGE' if
        !          2509:      the kernel ran out of memory.
        !          2510: 
        !          2511:      The 'mach_port_insert_right' call is actually an RPC to TASK,
        !          2512:      normally a send right for a task port, but potentially any send
        !          2513:      right.  In addition to the normal diagnostic return codes from the
        !          2514:      call's server (normally the kernel), the call may return 'mach_msg'
        !          2515:      return codes.
        !          2516: 
        !          2517:  -- Function: kern_return_t mach_port_extract_right (ipc_space_t TASK,
        !          2518:           mach_port_t NAME, mach_msg_type_name_t DESIRED_TYPE,
        !          2519:           mach_port_t *RIGHT, mach_msg_type_name_t *ACQUIRED_TYPE)
        !          2520:      The function MACH_PORT_EXTRACT_RIGHT extracts a port right from the
        !          2521:      target TASK and returns it to the caller as if the task sent the
        !          2522:      right voluntarily, using DESIRED_TYPE as the value of MSGT_NAME.
        !          2523:      *Note Mach Message Call::.
        !          2524: 
        !          2525:      The returned value of ACQUIRED_TYPE will be
        !          2526:      'MACH_MSG_TYPE_PORT_SEND' if a send right is extracted,
        !          2527:      'MACH_MSG_TYPE_PORT_RECEIVE' if a receive right is extracted, and
        !          2528:      'MACH_MSG_TYPE_PORT_SEND_ONCE' if a send-once right is extracted.
        !          2529: 
        !          2530:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2531:      'KERN_INVALID_TASK' if TASK was invalid, 'KERN_INVALID_NAME' if
        !          2532:      NAME did not denote a right, 'KERN_INVALID_RIGHT' if NAME denoted a
        !          2533:      right, but an invalid one, 'KERN_INVALID_VALUE' if DESIRED_TYPE was
        !          2534:      invalid.
        !          2535: 
        !          2536:      The 'mach_port_extract_right' call is actually an RPC to TASK,
        !          2537:      normally a send right for a task port, but potentially any send
        !          2538:      right.  In addition to the normal diagnostic return codes from the
        !          2539:      call's server (normally the kernel), the call may return 'mach_msg'
        !          2540:      return codes.
        !          2541: 
        !          2542: 
        !          2543: File: mach.info,  Node: Receive Rights,  Next: Port Sets,  Prev: Ports and other Tasks,  Up: Port Manipulation Interface
        !          2544: 
        !          2545: 4.3.6 Receive Rights
        !          2546: --------------------
        !          2547: 
        !          2548:  -- Data type: mach_port_seqno_t
        !          2549:      The 'mach_port_seqno_t' data type is an 'unsigned int' which
        !          2550:      contains the sequence number of a port.
        !          2551: 
        !          2552:  -- Data type: mach_port_mscount_t
        !          2553:      The 'mach_port_mscount_t' data type is an 'unsigned int' which
        !          2554:      contains the make-send count for a port.
        !          2555: 
        !          2556:  -- Data type: mach_port_msgcount_t
        !          2557:      The 'mach_port_msgcount_t' data type is an 'unsigned int' which
        !          2558:      contains a number of messages.
        !          2559: 
        !          2560:  -- Data type: mach_port_rights_t
        !          2561:      The 'mach_port_rights_t' data type is an 'unsigned int' which
        !          2562:      contains a number of rights for a port.
        !          2563: 
        !          2564:  -- Data type: mach_port_status_t
        !          2565:      This structure contains some status information about a port, which
        !          2566:      can be queried with 'mach_port_get_receive_status'.  It has the
        !          2567:      following members:
        !          2568: 
        !          2569:      'mach_port_t mps_pset'
        !          2570:           The containing port set.
        !          2571: 
        !          2572:      'mach_port_seqno_t mps_seqno'
        !          2573:           The sequence number.
        !          2574: 
        !          2575:      'mach_port_mscount_t mps_mscount'
        !          2576:           The make-send count.
        !          2577: 
        !          2578:      'mach_port_msgcount_t mps_qlimit'
        !          2579:           The maximum number of messages in the queue.
        !          2580: 
        !          2581:      'mach_port_msgcount_t mps_msgcount'
        !          2582:           The current number of messages in the queue.
        !          2583: 
        !          2584:      'mach_port_rights_t mps_sorights'
        !          2585:           The number of send-once rights that exist.
        !          2586: 
        !          2587:      'boolean_t mps_srights'
        !          2588:           'TRUE' if send rights exist.
        !          2589: 
        !          2590:      'boolean_t mps_pdrequest'
        !          2591:           'TRUE' if port-deleted notification is requested.
        !          2592: 
        !          2593:      'boolean_t mps_nsrequest'
        !          2594:           'TRUE' if no-senders notification is requested.
        !          2595: 
        !          2596:  -- Function: kern_return_t mach_port_get_receive_status
        !          2597:           (ipc_space_t TASK, mach_port_t NAME,
        !          2598:           mach_port_status_t *STATUS)
        !          2599:      The function 'mach_port_get_receive_status' returns the current
        !          2600:      status of the specified receive right.
        !          2601: 
        !          2602:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2603:      'KERN_INVALID_TASK' if TASK was invalid, 'KERN_INVALID_NAME' if
        !          2604:      NAME did not denote a right and 'KERN_INVALID_RIGHT' if NAME
        !          2605:      denoted a right, but not a receive right.
        !          2606: 
        !          2607:      The 'mach_port_get_receive_status' call is actually an RPC to TASK,
        !          2608:      normally a send right for a task port, but potentially any send
        !          2609:      right.  In addition to the normal diagnostic return codes from the
        !          2610:      call's server (normally the kernel), the call may return 'mach_msg'
        !          2611:      return codes.
        !          2612: 
        !          2613:  -- Function: kern_return_t mach_port_set_mscount (ipc_space_t TASK,
        !          2614:           mach_port_t NAME, mach_port_mscount_t MSCOUNT)
        !          2615:      The function 'mach_port_set_mscount' changes the make-send count of
        !          2616:      TASK's receive right named NAME to MSCOUNT.  All values for MSCOUNT
        !          2617:      are valid.
        !          2618: 
        !          2619:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2620:      'KERN_INVALID_TASK' if TASK was invalid, 'KERN_INVALID_NAME' if
        !          2621:      NAME did not denote a right and 'KERN_INVALID_RIGHT' if NAME
        !          2622:      denoted a right, but not a receive right.
        !          2623: 
        !          2624:      The 'mach_port_set_mscount' call is actually an RPC to TASK,
        !          2625:      normally a send right for a task port, but potentially any send
        !          2626:      right.  In addition to the normal diagnostic return codes from the
        !          2627:      call's server (normally the kernel), the call may return 'mach_msg'
        !          2628:      return codes.
        !          2629: 
        !          2630:  -- Function: kern_return_t mach_port_set_qlimit (ipc_space_t TASK,
        !          2631:           mach_port_t NAME, mach_port_msgcount_t QLIMIT)
        !          2632:      The function 'mach_port_set_qlimit' changes the queue limit TASK's
        !          2633:      receive right named NAME to QLIMIT.  Valid values for QLIMIT are
        !          2634:      between zero and 'MACH_PORT_QLIMIT_MAX', inclusive.
        !          2635: 
        !          2636:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2637:      'KERN_INVALID_TASK' if TASK was invalid, 'KERN_INVALID_NAME' if
        !          2638:      NAME did not denote a right, 'KERN_INVALID_RIGHT' if NAME denoted a
        !          2639:      right, but not a receive right and 'KERN_INVALID_VALUE' if QLIMIT
        !          2640:      was invalid.
        !          2641: 
        !          2642:      The 'mach_port_set_qlimit' call is actually an RPC to TASK,
        !          2643:      normally a send right for a task port, but potentially any send
        !          2644:      right.  In addition to the normal diagnostic return codes from the
        !          2645:      call's server (normally the kernel), the call may return 'mach_msg'
        !          2646:      return codes.
        !          2647: 
        !          2648:  -- Function: kern_return_t mach_port_set_seqno (ipc_space_t TASK,
        !          2649:           mach_port_t NAME, mach_port_seqno_t SEQNO)
        !          2650:      The function 'mach_port_set_seqno' changes the sequence number
        !          2651:      TASK's receive right named NAME to SEQNO.  All sequence number
        !          2652:      values are valid.  The next message received from the port will be
        !          2653:      stamped with the specified sequence number.
        !          2654: 
        !          2655:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2656:      'KERN_INVALID_TASK' if TASK was invalid, 'KERN_INVALID_NAME' if
        !          2657:      NAME did not denote a right and 'KERN_INVALID_RIGHT' if NAME
        !          2658:      denoted a right, but not a receive right.
        !          2659: 
        !          2660:      The 'mach_port_set_seqno' call is actually an RPC to TASK, normally
        !          2661:      a send right for a task port, but potentially any send right.  In
        !          2662:      addition to the normal diagnostic return codes from the call's
        !          2663:      server (normally the kernel), the call may return 'mach_msg' return
        !          2664:      codes.
        !          2665: 
        !          2666: 
        !          2667: File: mach.info,  Node: Port Sets,  Next: Request Notifications,  Prev: Receive Rights,  Up: Port Manipulation Interface
        !          2668: 
        !          2669: 4.3.7 Port Sets
        !          2670: ---------------
        !          2671: 
        !          2672:  -- Function: kern_return_t mach_port_get_set_status (ipc_space_t TASK,
        !          2673:           mach_port_t NAME, mach_port_array_t *MEMBERS,
        !          2674:           mach_msg_type_number_t *COUNT)
        !          2675:      The function 'mach_port_get_set_status' returns the members of a
        !          2676:      port set.  MEMBERS is an array that is automatically allocated when
        !          2677:      the reply message is received.  The user should 'vm_deallocate' it
        !          2678:      when the data is no longer needed.
        !          2679: 
        !          2680:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2681:      'KERN_INVALID_TASK' if TASK was invalid, 'KERN_INVALID_NAME' if
        !          2682:      NAME did not denote a right, 'KERN_INVALID_RIGHT' if NAME denoted a
        !          2683:      right, but not a receive right and 'KERN_RESOURCE_SHORTAGE' if the
        !          2684:      kernel ran out of memory.
        !          2685: 
        !          2686:      The 'mach_port_get_set_status' call is actually an RPC to TASK,
        !          2687:      normally a send right for a task port, but potentially any send
        !          2688:      right.  In addition to the normal diagnostic return codes from the
        !          2689:      call's server (normally the kernel), the call may return 'mach_msg'
        !          2690:      return codes.
        !          2691: 
        !          2692:  -- Function: kern_return_t mach_port_move_member (ipc_space_t TASK,
        !          2693:           mach_port_t MEMBER, mach_port_t AFTER)
        !          2694:      The function MACH_PORT_MOVE_MEMBER moves the receive right MEMBER
        !          2695:      into the port set AFTER.  If the receive right is already a member
        !          2696:      of another port set, it is removed from that set first (the whole
        !          2697:      operation is atomic).  If the port set is 'MACH_PORT_NULL', then
        !          2698:      the receive right is not put into a port set, but removed from its
        !          2699:      current port set.
        !          2700: 
        !          2701:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2702:      'KERN_INVALID_TASK' if TASK was invalid, 'KERN_INVALID_NAME' if
        !          2703:      MEMBER or AFTER did not denote a right, 'KERN_INVALID_RIGHT' if
        !          2704:      MEMBER denoted a right, but not a receive right or AFTER denoted a
        !          2705:      right, but not a port set, and 'KERN_NOT_IN_SET' if AFTER was
        !          2706:      'MACH_PORT_NULL', but 'member' wasn't currently in a port set.
        !          2707: 
        !          2708:      The 'mach_port_move_member' call is actually an RPC to TASK,
        !          2709:      normally a send right for a task port, but potentially any send
        !          2710:      right.  In addition to the normal diagnostic return codes from the
        !          2711:      call's server (normally the kernel), the call may return 'mach_msg'
        !          2712:      return codes.
        !          2713: 
        !          2714: 
        !          2715: File: mach.info,  Node: Request Notifications,  Prev: Port Sets,  Up: Port Manipulation Interface
        !          2716: 
        !          2717: 4.3.8 Request Notifications
        !          2718: ---------------------------
        !          2719: 
        !          2720:  -- Function: kern_return_t mach_port_request_notification
        !          2721:           (ipc_space_t TASK, mach_port_t NAME, mach_msg_id_t VARIANT,
        !          2722:           mach_port_mscount_t SYNC, mach_port_t NOTIFY,
        !          2723:           mach_msg_type_name_t NOTIFY_TYPE, mach_port_t *PREVIOUS)
        !          2724:      The function 'mach_port_request_notification' registers a request
        !          2725:      for a notification and supplies the send-once right NOTIFY to which
        !          2726:      the notification will be sent.  The NOTIFY_TYPE denotes the IPC
        !          2727:      type for the send-once right, which can be
        !          2728:      'MACH_MSG_TYPE_MAKE_SEND_ONCE' or 'MACH_MSG_TYPE_MOVE_SEND_ONCE'.
        !          2729:      It is an atomic swap, returning the previously registered send-once
        !          2730:      right (or 'MACH_PORT_NULL' for none) in PREVIOUS.  A previous
        !          2731:      notification request may be cancelled by providing 'MACH_PORT_NULL'
        !          2732:      for NOTIFY.
        !          2733: 
        !          2734:      The VARIANT argument takes the following values:
        !          2735: 
        !          2736:      'MACH_NOTIFY_PORT_DESTROYED'
        !          2737:           SYNC must be zero.  The NAME must specify a receive right, and
        !          2738:           the call requests a port-destroyed notification for the
        !          2739:           receive right.  If the receive right were to have been
        !          2740:           destroyed, say by 'mach_port_destroy', then instead the
        !          2741:           receive right will be sent in a port-destroyed notification to
        !          2742:           the registered send-once right.
        !          2743: 
        !          2744:      'MACH_NOTIFY_DEAD_NAME'
        !          2745:           The call requests a dead-name notification.  NAME specifies
        !          2746:           send, receive, or send-once rights for a port.  If the port is
        !          2747:           destroyed (and the right remains, becoming a dead name), then
        !          2748:           a dead-name notification which carries the name of the right
        !          2749:           will be sent to the registered send-once right.  If NOTIFY is
        !          2750:           not null and sync is non-zero, the name may specify a dead
        !          2751:           name, and a dead-name notification is immediately generated.
        !          2752: 
        !          2753:           Whenever a dead-name notification is generated, the user
        !          2754:           reference count of the dead name is incremented.  For example,
        !          2755:           a send right with two user refs has a registered dead-name
        !          2756:           request.  If the port is destroyed, the send right turns into
        !          2757:           a dead name with three user refs (instead of two), and a
        !          2758:           dead-name notification is generated.
        !          2759: 
        !          2760:           If the name is made available for reuse, perhaps because of
        !          2761:           'mach_port_destroy' or 'mach_port_mod_refs', or the name
        !          2762:           denotes a send-once right which has a message sent to it, then
        !          2763:           the registered send-once right is used to generate a
        !          2764:           port-deleted notification.
        !          2765: 
        !          2766:      'MACH_NOTIFY_NO_SENDERS'
        !          2767:           The call requests a no-senders notification.  NAME must
        !          2768:           specify a receive right.  If NOTIFY is not null, and the
        !          2769:           receive right's make-send count is greater than or equal to
        !          2770:           the sync value, and it has no extant send rights, than an
        !          2771:           immediate no-senders notification is generated.  Otherwise the
        !          2772:           notification is generated when the receive right next loses
        !          2773:           its last extant send right.  In either case, any previously
        !          2774:           registered send-once right is returned.
        !          2775: 
        !          2776:           The no-senders notification carries the value the port's
        !          2777:           make-send count had when it was generated.  The make-send
        !          2778:           count is incremented whenever 'MACH_MSG_TYPE_MAKE_SEND' is
        !          2779:           used to create a new send right from the receive right.  The
        !          2780:           make-send count is reset to zero when the receive right is
        !          2781:           carried in a message.
        !          2782: 
        !          2783:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          2784:      'KERN_INVALID_TASK' if TASK was invalid, 'KERN_INVALID_VALUE' if
        !          2785:      VARIANT was invalid, 'KERN_INVALID_NAME' if NAME did not denote a
        !          2786:      right, 'KERN_INVALID_RIGHT' if NAME denoted an invalid right and
        !          2787:      'KERN_INVALID_CAPABILITY' if NOTIFY was invalid.
        !          2788: 
        !          2789:      When using 'MACH_NOTIFY_PORT_DESTROYED', the function returns
        !          2790:      'KERN_INVALID_VALUE' if SYNC wasn't zero.
        !          2791: 
        !          2792:      When using 'MACH_NOTIFY_DEAD_NAME', the function returns
        !          2793:      'KERN_RESOURCE_SHORTAGE' if the kernel ran out of memory,
        !          2794:      'KERN_INVALID_ARGUMENT' if NAME denotes a dead name, but SYNC is
        !          2795:      zero or NOTIFY is 'MACH_PORT_NULL', and 'KERN_UREFS_OVERFLOW' if
        !          2796:      NAME denotes a dead name, but generating an immediate dead-name
        !          2797:      notification would overflow the name's user-reference count.
        !          2798: 
        !          2799:      The 'mach_port_request_notification' call is actually an RPC to
        !          2800:      TASK, normally a send right for a task port, but potentially any
        !          2801:      send right.  In addition to the normal diagnostic return codes from
        !          2802:      the call's server (normally the kernel), the call may return
        !          2803:      'mach_msg' return codes.
        !          2804: 
        !          2805: 
        !          2806: File: mach.info,  Node: Virtual Memory Interface,  Next: External Memory Management,  Prev: Inter Process Communication,  Up: Top
        !          2807: 
        !          2808: 5 Virtual Memory Interface
        !          2809: **************************
        !          2810: 
        !          2811:  -- Data type: vm_task_t
        !          2812:      This is a 'task_t' (and as such a 'mach_port_t'), which holds a
        !          2813:      port name associated with a port that represents a virtual memory
        !          2814:      map in the kernel.  An virtual memory map is used by the kernel to
        !          2815:      manage the address space of a task.  The virtual memory map doesn't
        !          2816:      get a port name of its own.  Instead the port name of the task
        !          2817:      provided with the virtual memory is used to name the virtual memory
        !          2818:      map of the task (as is indicated by the fact that the type of
        !          2819:      'vm_task_t' is actually 'task_t').
        !          2820: 
        !          2821:      The virtual memory maps of tasks are the only ones accessible
        !          2822:      outside of the kernel.
        !          2823: 
        !          2824: * Menu:
        !          2825: 
        !          2826: * Memory Allocation::             Allocation of new virtual memory.
        !          2827: * Memory Deallocation::           Freeing unused virtual memory.
        !          2828: * Data Transfer::                 Reading, writing and copying memory.
        !          2829: * Memory Attributes::             Tweaking memory regions.
        !          2830: * Mapping Memory Objects::        How to map memory objects.
        !          2831: * Memory Statistics::             How to get statistics about memory usage.
        !          2832: 
        !          2833: 
        !          2834: File: mach.info,  Node: Memory Allocation,  Next: Memory Deallocation,  Up: Virtual Memory Interface
        !          2835: 
        !          2836: 5.1 Memory Allocation
        !          2837: =====================
        !          2838: 
        !          2839:  -- Function: kern_return_t vm_allocate (vm_task_t TARGET_TASK,
        !          2840:           vm_address_t *ADDRESS, vm_size_t SIZE, boolean_t ANYWHERE)
        !          2841:      The function 'vm_allocate' allocates a region of virtual memory,
        !          2842:      placing it in the specified TASK's address space.
        !          2843: 
        !          2844:      The starting address is ADDRESS.  If the ANYWHERE option is false,
        !          2845:      an attempt is made to allocate virtual memory starting at this
        !          2846:      virtual address.  If this address is not at the beginning of a
        !          2847:      virtual page, it will be rounded down to one.  If there is not
        !          2848:      enough space at this address, no memory will be allocated.  If the
        !          2849:      ANYWHERE option is true, the input value of this address will be
        !          2850:      ignored, and the space will be allocated wherever it is available.
        !          2851:      In either case, the address at which memory was actually allocated
        !          2852:      will be returned in ADDRESS.
        !          2853: 
        !          2854:      SIZE is the number of bytes to allocate (rounded by the system in a
        !          2855:      machine dependent way to an integral number of virtual pages).
        !          2856: 
        !          2857:      If ANYWHERE is true, the kernel should find and allocate any region
        !          2858:      of the specified size, and return the address of the resulting
        !          2859:      region in address address, rounded to a virtual page boundary if
        !          2860:      there is sufficient space.
        !          2861: 
        !          2862:      The physical memory is not actually allocated until the new virtual
        !          2863:      memory is referenced.  By default, the kernel rounds all addresses
        !          2864:      down to the nearest page boundary and all memory sizes up to the
        !          2865:      nearest page size.  The global variable 'vm_page_size' contains the
        !          2866:      page size.  'mach_task_self' returns the value of the current task
        !          2867:      port which should be used as the TARGET_TASK argument in order to
        !          2868:      allocate memory in the caller's address space.  For languages other
        !          2869:      than C, these values can be obtained by the calls 'vm_statistics'
        !          2870:      and 'mach_task_self'.  Initially, the pages of allocated memory
        !          2871:      will be protected to allow all forms of access, and will be
        !          2872:      inherited in child tasks as a copy.  Subsequent calls to
        !          2873:      'vm_protect' and 'vm_inherit' may be used to change these
        !          2874:      properties.  The allocated region is always zero-filled.
        !          2875: 
        !          2876:      The function returns 'KERN_SUCCESS' if the memory was successfully
        !          2877:      allocated, 'KERN_INVALID_ADDRESS' if an invalid address was
        !          2878:      specified and 'KERN_NO_SPACE' if there was not enough space left to
        !          2879:      satisfy the request.
        !          2880: 
        !          2881: 
        !          2882: File: mach.info,  Node: Memory Deallocation,  Next: Data Transfer,  Prev: Memory Allocation,  Up: Virtual Memory Interface
        !          2883: 
        !          2884: 5.2 Memory Deallocation
        !          2885: =======================
        !          2886: 
        !          2887:  -- Function: kern_return_t vm_deallocate (vm_task_t TARGET_TASK,
        !          2888:           vm_address_t ADDRESS, vm_size_t SIZE)
        !          2889:      'vm_deallocate' relinquishes access to a region of a TASK's address
        !          2890:      space, causing further access to that memory to fail.  This address
        !          2891:      range will be available for reallocation.  ADDRESS is the starting
        !          2892:      address, which will be rounded down to a page boundary.  SIZE is
        !          2893:      the number of bytes to deallocate, which will be rounded up to give
        !          2894:      a page boundary.  Note, that because of the rounding to virtual
        !          2895:      page boundaries, more than SIZE bytes may be deallocated.  Use
        !          2896:      'vm_page_size' or 'vm_statistics' to find out the current virtual
        !          2897:      page size.
        !          2898: 
        !          2899:      This call may be used to deallocate memory that was passed to a
        !          2900:      task in a message (via out of line data).  In that case, the
        !          2901:      rounding should cause no trouble, since the region of memory was
        !          2902:      allocated as a set of pages.
        !          2903: 
        !          2904:      The 'vm_deallocate' call affects only the task specified by the
        !          2905:      TARGET_TASK.  Other tasks which may have access to this memory may
        !          2906:      continue to reference it.
        !          2907: 
        !          2908:      The function returns 'KERN_SUCCESS' if the memory was successfully
        !          2909:      deallocated and 'KERN_INVALID_ADDRESS' if an invalid or
        !          2910:      non-allocated address was specified.
        !          2911: 
        !          2912: 
        !          2913: File: mach.info,  Node: Data Transfer,  Next: Memory Attributes,  Prev: Memory Deallocation,  Up: Virtual Memory Interface
        !          2914: 
        !          2915: 5.3 Data Transfer
        !          2916: =================
        !          2917: 
        !          2918:  -- Function: kern_return_t vm_read (vm_task_t TARGET_TASK,
        !          2919:           vm_address_t ADDRESS, vm_size_t SIZE, vm_offset_t *DATA,
        !          2920:           mach_msg_type_number_t *DATA_COUNT)
        !          2921:      The function 'vm_read' allows one task's virtual memory to be read
        !          2922:      by another task.  The TARGET_TASK is the task whose memory is to be
        !          2923:      read.  ADDRESS is the first address to be read and must be on a
        !          2924:      page boundary.  SIZE is the number of bytes of data to be read and
        !          2925:      must be an integral number of pages.  DATA is the array of data
        !          2926:      copied from the given task, and DATA_COUNT is the size of the data
        !          2927:      array in bytes (will be an integral number of pages).
        !          2928: 
        !          2929:      Note that the data array is returned in a newly allocated region;
        !          2930:      the task reading the data should 'vm_deallocate' this region when
        !          2931:      it is done with the data.
        !          2932: 
        !          2933:      The function returns 'KERN_SUCCESS' if the memory was successfully
        !          2934:      read, 'KERN_INVALID_ADDRESS' if an invalid or non-allocated address
        !          2935:      was specified or there was not SIZE bytes of data following the
        !          2936:      address, 'KERN_INVALID_ARGUMENT' if the address does not start on a
        !          2937:      page boundary or the size is not an integral number of pages,
        !          2938:      'KERN_PROTECTION_FAILURE' if the address region in the target task
        !          2939:      is protected against reading and 'KERN_NO_SPACE' if there was not
        !          2940:      enough room in the callers virtual memory to allocate space for the
        !          2941:      data to be returned.
        !          2942: 
        !          2943:  -- Function: kern_return_t vm_write (vm_task_t TARGET_TASK,
        !          2944:           vm_address_t ADDRESS, vm_offset_t DATA,
        !          2945:           mach_msg_type_number_t DATA_COUNT)
        !          2946:      The function 'vm_write' allows a task to write to the virtual
        !          2947:      memory of TARGET_TASK.  ADDRESS is the starting address in task to
        !          2948:      be affected.  DATA is an array of bytes to be written, and
        !          2949:      DATA_COUNT the size of the DATA array.
        !          2950: 
        !          2951:      The current implementation requires that ADDRESS, DATA and
        !          2952:      DATA_COUNT all be page-aligned.  Otherwise, 'KERN_INVALID_ARGUMENT'
        !          2953:      is returned.
        !          2954: 
        !          2955:      The function returns 'KERN_SUCCESS' if the memory was successfully
        !          2956:      written, 'KERN_INVALID_ADDRESS' if an invalid or non-allocated
        !          2957:      address was specified or there was not DATA_COUNT bytes of
        !          2958:      allocated memory starting at ADDRESS and 'KERN_PROTECTION_FAILURE'
        !          2959:      if the address region in the target task is protected against
        !          2960:      writing.
        !          2961: 
        !          2962:  -- Function: kern_return_t vm_copy (vm_task_t TARGET_TASK,
        !          2963:           vm_address_t SOURCE_ADDRESS, vm_size_t COUNT,
        !          2964:           vm_offset_t DEST_ADDRESS)
        !          2965:      The function 'vm_copy' causes the source memory range to be copied
        !          2966:      to the destination address.  The source and destination memory
        !          2967:      ranges may overlap.  The destination address range must already be
        !          2968:      allocated and writable; the source range must be readable.
        !          2969: 
        !          2970:      'vm_copy' is equivalent to 'vm_read' followed by 'vm_write'.
        !          2971: 
        !          2972:      The current implementation requires that ADDRESS, DATA and
        !          2973:      DATA_COUNT all be page-aligned.  Otherwise, 'KERN_INVALID_ARGUMENT'
        !          2974:      is returned.
        !          2975: 
        !          2976:      The function returns 'KERN_SUCCESS' if the memory was successfully
        !          2977:      written, 'KERN_INVALID_ADDRESS' if an invalid or non-allocated
        !          2978:      address was specified or there was insufficient memory allocated at
        !          2979:      one of the addresses and 'KERN_PROTECTION_FAILURE' if the
        !          2980:      destination region was not writable or the source region was not
        !          2981:      readable.
        !          2982: 
        !          2983: 
        !          2984: File: mach.info,  Node: Memory Attributes,  Next: Mapping Memory Objects,  Prev: Data Transfer,  Up: Virtual Memory Interface
        !          2985: 
        !          2986: 5.4 Memory Attributes
        !          2987: =====================
        !          2988: 
        !          2989:  -- Function: kern_return_t vm_region (vm_task_t TARGET_TASK,
        !          2990:           vm_address_t *ADDRESS, vm_size_t *SIZE, vm_prot_t *PROTECTION,
        !          2991:           vm_prot_t *MAX_PROTECTION, vm_inherit_t *INHERITANCE,
        !          2992:           boolean_t *SHARED, memory_object_name_t *OBJECT_NAME,
        !          2993:           vm_offset_t *OFFSET)
        !          2994:      The function 'vm_region' returns a description of the specified
        !          2995:      region of TARGET_TASK's virtual address space.  'vm_region' begins
        !          2996:      at ADDRESS and looks forward through memory until it comes to an
        !          2997:      allocated region.  If address is within a region, then that region
        !          2998:      is used.  Various bits of information about the region are
        !          2999:      returned.  If ADDRESS was not within a region, then ADDRESS is set
        !          3000:      to the start of the first region which follows the incoming value.
        !          3001:      In this way an entire address space can be scanned.
        !          3002: 
        !          3003:      The SIZE returned is the size of the located region in bytes.
        !          3004:      PROTECTION is the current protection of the region, MAX_PROTECTION
        !          3005:      is the maximum allowable protection for this region.  INHERITANCE
        !          3006:      is the inheritance attribute for this region.  SHARED tells if the
        !          3007:      region is shared or not.  The port OBJECT_NAME identifies the
        !          3008:      memory object associated with this region, and OFFSET is the offset
        !          3009:      into the pager object that this region begins at.
        !          3010: 
        !          3011:      The function returns 'KERN_SUCCESS' if the memory region was
        !          3012:      successfully located and the information returned and
        !          3013:      'KERN_NO_SPACE' if there is no region at or above ADDRESS in the
        !          3014:      specified task.
        !          3015: 
        !          3016:  -- Function: kern_return_t vm_protect (vm_task_t TARGET_TASK,
        !          3017:           vm_address_t ADDRESS, vm_size_t SIZE, boolean_t SET_MAXIMUM,
        !          3018:           vm_prot_t NEW_PROTECTION)
        !          3019:      The function 'vm_protect' sets the virtual memory access privileges
        !          3020:      for a range of allocated addresses in TARGET_TASK's virtual address
        !          3021:      space.  The protection argument describes a combination of read,
        !          3022:      write, and execute accesses that should be _permitted_.
        !          3023: 
        !          3024:      ADDRESS is the starting address, which will be rounded down to a
        !          3025:      page boundary.  SIZE is the size in bytes of the region for which
        !          3026:      protection is to change, and will be rounded up to give a page
        !          3027:      boundary.  If SET_MAXIMUM is set, make the protection change apply
        !          3028:      to the maximum protection associated with this address range;
        !          3029:      otherwise, the current protection on this range is changed.  If the
        !          3030:      maximum protection is reduced below the current protection, both
        !          3031:      will be changed to reflect the new maximum.  NEW_PROTECTION is the
        !          3032:      new protection value for this region; a set of: 'VM_PROT_READ',
        !          3033:      'VM_PROT_WRITE', 'VM_PROT_EXECUTE'.
        !          3034: 
        !          3035:      The enforcement of virtual memory protection is machine-dependent.
        !          3036:      Nominally read access requires 'VM_PROT_READ' permission, write
        !          3037:      access requires 'VM_PROT_WRITE' permission, and execute access
        !          3038:      requires 'VM_PROT_EXECUTE' permission.  However, some combinations
        !          3039:      of access rights may not be supported.  In particular, the kernel
        !          3040:      interface allows write access to require 'VM_PROT_READ' and
        !          3041:      'VM_PROT_WRITE' permission and execute access to require
        !          3042:      'VM_PROT_READ' permission.
        !          3043: 
        !          3044:      The function returns 'KERN_SUCCESS' if the memory was successfully
        !          3045:      protected, 'KERN_INVALID_ADDRESS' if an invalid or non-allocated
        !          3046:      address was specified and 'KERN_PROTECTION_FAILURE' if an attempt
        !          3047:      was made to increase the current or maximum protection beyond the
        !          3048:      existing maximum protection value.
        !          3049: 
        !          3050:  -- Function: kern_return_t vm_inherit (vm_task_t TARGET_TASK,
        !          3051:           vm_address_t ADDRESS, vm_size_t SIZE,
        !          3052:           vm_inherit_t NEW_INHERITANCE)
        !          3053:      The function 'vm_inherit' specifies how a region of TARGET_TASK's
        !          3054:      address space is to be passed to child tasks at the time of task
        !          3055:      creation.  Inheritance is an attribute of virtual pages, so ADDRESS
        !          3056:      to start from will be rounded down to a page boundary and SIZE, the
        !          3057:      size in bytes of the region for which inheritance is to change,
        !          3058:      will be rounded up to give a page boundary.  How this memory is to
        !          3059:      be inherited in child tasks is specified by NEW_INHERITANCE.
        !          3060:      Inheritance is specified by using one of these following three
        !          3061:      values:
        !          3062: 
        !          3063:      'VM_INHERIT_SHARE'
        !          3064:           Child tasks will share this memory with this task.
        !          3065: 
        !          3066:      'VM_INHERIT_COPY'
        !          3067:           Child tasks will receive a copy of this region.
        !          3068: 
        !          3069:      'VM_INHERIT_NONE'
        !          3070:           This region will be absent from child tasks.
        !          3071: 
        !          3072:      Setting 'vm_inherit' to 'VM_INHERIT_SHARE' and forking a child task
        !          3073:      is the only way two Mach tasks can share physical memory.  Remember
        !          3074:      that all the threads of a given task share all the same memory.
        !          3075: 
        !          3076:      The function returns 'KERN_SUCCESS' if the memory inheritance was
        !          3077:      successfully set and 'KERN_INVALID_ADDRESS' if an invalid or
        !          3078:      non-allocated address was specified.
        !          3079: 
        !          3080:  -- Function: kern_return_t vm_wire (host_priv_t HOST_PRIV,
        !          3081:           vm_task_t TARGET_TASK, vm_address_t ADDRESS, vm_size_t SIZE,
        !          3082:           vm_prot_t ACCESS)
        !          3083:      The function 'vm_wire' allows privileged applications to control
        !          3084:      memory pageability.  HOST_PRIV is the privileged host port for the
        !          3085:      host on which TARGET_TASK resides.  ADDRESS is the starting
        !          3086:      address, which will be rounded down to a page boundary.  SIZE is
        !          3087:      the size in bytes of the region for which protection is to change,
        !          3088:      and will be rounded up to give a page boundary.  ACCESS specifies
        !          3089:      the types of accesses that must not cause page faults.
        !          3090: 
        !          3091:      The semantics of a successful 'vm_wire' operation are that memory
        !          3092:      in the specified range will not cause page faults for any accesses
        !          3093:      included in access.  Data memory can be made non-pageable (wired)
        !          3094:      with a access argument of 'VM_PROT_READ | VM_PROT_WRITE'.  A
        !          3095:      special case is that 'VM_PROT_NONE' makes the memory pageable.
        !          3096: 
        !          3097:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          3098:      'KERN_INVALID_HOST' if HOST_PRIV was not the privileged host port,
        !          3099:      'KERN_INVALID_TASK' if TASK was not a valid task,
        !          3100:      'KERN_INVALID_VALUE' if ACCESS specified an invalid access mode,
        !          3101:      'KERN_FAILURE' if some memory in the specified range is not present
        !          3102:      or has an inappropriate protection value, and
        !          3103:      'KERN_INVALID_ARGUMENT' if unwiring (ACCESS is 'VM_PROT_NONE') and
        !          3104:      the memory is not already wired.
        !          3105: 
        !          3106:      The 'vm_wire' call is actually an RPC to HOST_PRIV, normally a send
        !          3107:      right for a privileged host port, but potentially any send right.
        !          3108:      In addition to the normal diagnostic return codes from the call's
        !          3109:      server (normally the kernel), the call may return 'mach_msg' return
        !          3110:      codes.
        !          3111: 
        !          3112:  -- Function: kern_return_t vm_machine_attribute (vm_task_t TASK,
        !          3113:           vm_address_t ADDRESS, vm_size_t SIZE, vm_prot_t ACCESS,
        !          3114:           vm_machine_attribute_t ATTRIBUTE,
        !          3115:           vm_machine_attribute_val_t VALUE)
        !          3116:      The function 'vm_machine_attribute' specifies machine-specific
        !          3117:      attributes for a VM mapping, such as cachability, migrability,
        !          3118:      replicability.  This is used on machines that allow the user
        !          3119:      control over the cache (this is the case for MIPS architectures) or
        !          3120:      placement of memory pages as in NUMA architectures (Non-Uniform
        !          3121:      Memory Access time) such as the IBM ACE multiprocessor.
        !          3122: 
        !          3123:      Machine-specific attributes can be consider additions to the
        !          3124:      machine-independent ones such as protection and inheritance, but
        !          3125:      they are not guaranteed to be supported by any given machine.
        !          3126:      Moreover, implementations of Mach on new architectures might find
        !          3127:      the need for new attribute types and or values besides the ones
        !          3128:      defined in the initial implementation.
        !          3129: 
        !          3130:      The types currently defined are
        !          3131:      'MATTR_CACHE'
        !          3132:           Controls caching of memory pages
        !          3133: 
        !          3134:      'MATTR_MIGRATE'
        !          3135:           Controls migrability of memory pages
        !          3136: 
        !          3137:      'MATTR_REPLICATE'
        !          3138:           Controls replication of memory pages
        !          3139: 
        !          3140:      Corresponding values, and meaning of a specific call to
        !          3141:      'vm_machine_attribute'
        !          3142:      'MATTR_VAL_ON'
        !          3143:           Enables the attribute.  Being enabled is the default value for
        !          3144:           any applicable attribute.
        !          3145: 
        !          3146:      'MATTR_VAL_OFF'
        !          3147:           Disables the attribute, making memory non-cached, or
        !          3148:           non-migratable, or non-replicatable.
        !          3149: 
        !          3150:      'MATTR_VAL_GET'
        !          3151:           Returns the current value of the attribute for the memory
        !          3152:           segment.  If the attribute does not apply uniformly to the
        !          3153:           given range the value returned applies to the initial portion
        !          3154:           of the segment only.
        !          3155: 
        !          3156:      'MATTR_VAL_CACHE_FLUSH'
        !          3157:           Flush the memory pages from the Cache.  The size value in this
        !          3158:           case might be meaningful even if not a multiple of the page
        !          3159:           size, depending on the implementation.
        !          3160: 
        !          3161:      'MATTR_VAL_ICACHE_FLUSH'
        !          3162:           Same as above, applied to the Instruction Cache alone.
        !          3163: 
        !          3164:      'MATTR_VAL_DCACHE_FLUSH'
        !          3165:           Same as above, applied to the Data Cache alone.
        !          3166: 
        !          3167:      The function returns 'KERN_SUCCESS' if call succeeded, and
        !          3168:      'KERN_INVALID_ARGUMENT' if TASK is not a task, or ADDRESS and SIZE
        !          3169:      do not define a valid address range in task, or ATTRIBUTE is not a
        !          3170:      valid attribute type, or it is not implemented, or VALUE is not a
        !          3171:      permissible value for attribute.
        !          3172: 
        !          3173: 
        !          3174: File: mach.info,  Node: Mapping Memory Objects,  Next: Memory Statistics,  Prev: Memory Attributes,  Up: Virtual Memory Interface
        !          3175: 
        !          3176: 5.5 Mapping Memory Objects
        !          3177: ==========================
        !          3178: 
        !          3179:  -- Function: kern_return_t vm_map (vm_task_t TARGET_TASK,
        !          3180:           vm_address_t *ADDRESS, vm_size_t SIZE, vm_address_t MASK,
        !          3181:           boolean_t ANYWHERE, memory_object_t MEMORY_OBJECT,
        !          3182:           vm_offset_t OFFSET, boolean_t COPY, vm_prot_t CUR_PROTECTION,
        !          3183:           vm_prot_t MAX_PROTECTION, vm_inherit_t INHERITANCE)
        !          3184:      The function 'vm_map' maps a region of virtual memory at the
        !          3185:      specified address, for which data is to be supplied by the given
        !          3186:      memory object, starting at the given offset within that object.  In
        !          3187:      addition to the arguments used in 'vm_allocate', the 'vm_map' call
        !          3188:      allows the specification of an address alignment parameter, and of
        !          3189:      the initial protection and inheritance values.
        !          3190: 
        !          3191:      If the memory object in question is not currently in use, the
        !          3192:      kernel will perform a 'memory_object_init' call at this time.  If
        !          3193:      the copy parameter is asserted, the specified region of the memory
        !          3194:      object will be copied to this address space; changes made to this
        !          3195:      object by other tasks will not be visible in this mapping, and
        !          3196:      changes made in this mapping will not be visible to others (or
        !          3197:      returned to the memory object).
        !          3198: 
        !          3199:      The 'vm_map' call returns once the mapping is established.
        !          3200:      Completion of the call does not require any action on the part of
        !          3201:      the memory manager.
        !          3202: 
        !          3203:      Warning: Only memory objects that are provided by bona fide memory
        !          3204:      managers should be used in the 'vm_map' call.  A memory manager
        !          3205:      must implement the memory object interface described elsewhere in
        !          3206:      this manual.  If other ports are used, a thread that accesses the
        !          3207:      mapped virtual memory may become permanently hung or may receive a
        !          3208:      memory exception.
        !          3209: 
        !          3210:      TARGET_TASK is the task to be affected.  The starting address is
        !          3211:      ADDRESS.  If the ANYWHERE option is used, this address is ignored.
        !          3212:      The address actually allocated will be returned in ADDRESS.  SIZE
        !          3213:      is the number of bytes to allocate (rounded by the system in a
        !          3214:      machine dependent way).  The alignment restriction is specified by
        !          3215:      MASK.  Bits asserted in this mask must not be asserted in the
        !          3216:      address returned.  If ANYWHERE is set, the kernel should find and
        !          3217:      allocate any region of the specified size, and return the address
        !          3218:      of the resulting region in ADDRESS.
        !          3219: 
        !          3220:      MEMORY_OBJECT is the port that represents the memory object: used
        !          3221:      by user tasks in 'vm_map'; used by the make requests for data or
        !          3222:      other management actions.  If this port is 'MEMORY_OBJECT_NULL',
        !          3223:      then zero-filled memory is allocated instead.  Within a memory
        !          3224:      object, OFFSET specifies an offset in bytes.  This must be page
        !          3225:      aligned.  If COPY is set, the range of the memory object should be
        !          3226:      copied to the target task, rather than mapped read-write.
        !          3227: 
        !          3228:      The function returns 'KERN_SUCCESS' if the object is mapped,
        !          3229:      'KERN_NO_SPACE' if no unused region of the task's virtual address
        !          3230:      space that meets the address, size, and alignment criteria could be
        !          3231:      found, and 'KERN_INVALID_ARGUMENT' if an invalid argument was
        !          3232:      provided.
        !          3233: 
        !          3234: 
        !          3235: File: mach.info,  Node: Memory Statistics,  Prev: Mapping Memory Objects,  Up: Virtual Memory Interface
        !          3236: 
        !          3237: 5.6 Memory Statistics
        !          3238: =====================
        !          3239: 
        !          3240:  -- Data type: vm_statistics_data_t
        !          3241:      This structure is returned in VM_STATS by the 'vm_statistics'
        !          3242:      function and provides virtual memory statistics for the system.  It
        !          3243:      has the following members:
        !          3244: 
        !          3245:      'long pagesize'
        !          3246:           The page size in bytes.
        !          3247: 
        !          3248:      'long free_count'
        !          3249:           The number of free pages.
        !          3250: 
        !          3251:      'long active_count'
        !          3252:           The umber of active pages.
        !          3253: 
        !          3254:      'long inactive_count'
        !          3255:           The number of inactive pages.
        !          3256: 
        !          3257:      'long wire_count'
        !          3258:           The number of pages wired down.
        !          3259: 
        !          3260:      'long zero_fill_count'
        !          3261:           The number of zero filled pages.
        !          3262: 
        !          3263:      'long reactivations'
        !          3264:           The number of reactivated pages.
        !          3265: 
        !          3266:      'long pageins'
        !          3267:           The number of pageins.
        !          3268: 
        !          3269:      'long pageouts'
        !          3270:           The number of pageouts.
        !          3271: 
        !          3272:      'long faults'
        !          3273:           The number of faults.
        !          3274: 
        !          3275:      'long cow_faults'
        !          3276:           The number of copy-on-writes.
        !          3277: 
        !          3278:      'long lookups'
        !          3279:           The number of object cache lookups.
        !          3280: 
        !          3281:      'long hits'
        !          3282:           The number of object cache hits.
        !          3283: 
        !          3284:  -- Function: kern_return_t vm_statistics (vm_task_t TARGET_TASK,
        !          3285:           vm_statistics_data_t *VM_STATS)
        !          3286:      The function 'vm_statistics' returns the statistics about the
        !          3287:      kernel's use of virtual memory since the kernel was booted.
        !          3288:      'pagesize' can also be found as a global variable 'vm_page_size'
        !          3289:      which is set at task initialization and remains constant for the
        !          3290:      life of the task.
        !          3291: 
        !          3292: 
        !          3293: File: mach.info,  Node: External Memory Management,  Next: Threads and Tasks,  Prev: Virtual Memory Interface,  Up: Top
        !          3294: 
        !          3295: 6 External Memory Management
        !          3296: ****************************
        !          3297: 
        !          3298: * Menu:
        !          3299: 
        !          3300: * Memory Object Server::          The basics of external memory management.
        !          3301: * Memory Object Creation::        How new memory objects are created.
        !          3302: * Memory Object Termination::     How memory objects are terminated.
        !          3303: * Memory Objects and Data::       Data transfer to and from memory objects.
        !          3304: * Memory Object Locking::         How memory objects are locked.
        !          3305: * Memory Object Attributes::      Manipulating attributes of memory objects.
        !          3306: * Default Memory Manager::        Setting and using the default memory manager.
        !          3307: 
        !          3308: 
        !          3309: File: mach.info,  Node: Memory Object Server,  Next: Memory Object Creation,  Up: External Memory Management
        !          3310: 
        !          3311: 6.1 Memory Object Server
        !          3312: ========================
        !          3313: 
        !          3314:  -- Function: boolean_t memory_object_server (msg_header_t *IN_MSG,
        !          3315:           msg_header_t *OUT_MSG)
        !          3316:  -- Function: boolean_t memory_object_default_server
        !          3317:           (msg_header_t *IN_MSG, msg_header_t *OUT_MSG)
        !          3318:  -- Function: boolean_t seqnos_memory_object_server
        !          3319:           (msg_header_t *IN_MSG, msg_header_t *OUT_MSG)
        !          3320:  -- Function: boolean_t seqnos_memory_object_default_server
        !          3321:           (msg_header_t *IN_MSG, msg_header_t *OUT_MSG)
        !          3322:      A memory manager is a server task that responds to specific
        !          3323:      messages from the kernel in order to handle memory management
        !          3324:      functions for the kernel.
        !          3325: 
        !          3326:      In order to isolate the memory manager from the specifics of
        !          3327:      message formatting, the remote procedure call generator produces a
        !          3328:      procedure, 'memory_object_server', to handle a received message.
        !          3329:      This function does all necessary argument handling, and actually
        !          3330:      calls one of the following functions: 'memory_object_init',
        !          3331:      'memory_object_data_write', 'memory_object_data_return',
        !          3332:      'memory_object_data_request', 'memory_object_data_unlock',
        !          3333:      'memory_object_lock_completed', 'memory_object_copy',
        !          3334:      'memory_object_terminate'.  The *default memory manager* may get
        !          3335:      two additional requests from the kernel: 'memory_object_create' and
        !          3336:      'memory_object_data_initialize'.  The remote procedure call
        !          3337:      generator produces a procedure 'memory_object_default_server' to
        !          3338:      handle those functions specific to the default memory manager.
        !          3339: 
        !          3340:      The 'seqnos_memory_object_server' and
        !          3341:      'seqnos_memory_object_default_server' differ from
        !          3342:      'memory_object_server' and 'memory_object_default_server' in that
        !          3343:      they supply message sequence numbers to the server interfaces.
        !          3344:      They call the 'seqnos_memory_object_*' functions, which complement
        !          3345:      the 'memory_object_*' set of functions.
        !          3346: 
        !          3347:      The return value from the 'memory_object_server' function indicates
        !          3348:      that the message was appropriate to the memory management interface
        !          3349:      (returning 'TRUE'), or that it could not handle this message
        !          3350:      (returning 'FALSE').
        !          3351: 
        !          3352:      The IN_MSG argument is the message that has been received from the
        !          3353:      kernel.  The OUT_MSG is a reply message, but this is not used for
        !          3354:      this server.
        !          3355: 
        !          3356:      The function returns 'TRUE' to indicate that the message in
        !          3357:      question was applicable to this interface, and that the appropriate
        !          3358:      routine was called to interpret the message.  It returns 'FALSE' to
        !          3359:      indicate that the message did not apply to this interface, and that
        !          3360:      no other action was taken.
        !          3361: 
        !          3362: 
        !          3363: File: mach.info,  Node: Memory Object Creation,  Next: Memory Object Termination,  Prev: Memory Object Server,  Up: External Memory Management
        !          3364: 
        !          3365: 6.2 Memory Object Creation
        !          3366: ==========================
        !          3367: 
        !          3368:  -- Function: kern_return_t memory_object_init
        !          3369:           (memory_object_t MEMORY_OBJECT,
        !          3370:           memory_object_control_t MEMORY_CONTROL,
        !          3371:           memory_object_name_t MEMORY_OBJECT_NAME,
        !          3372:           vm_size_t MEMORY_OBJECT_PAGE_SIZE)
        !          3373:  -- Function: kern_return_t seqnos_memory_object_init
        !          3374:           (memory_object_t MEMORY_OBJECT, mach_port_seqno_t SEQNO,
        !          3375:           memory_object_control_t MEMORY_CONTROL,
        !          3376:           memory_object_name_t MEMORY_OBJECT_NAME,
        !          3377:           vm_size_t MEMORY_OBJECT_PAGE_SIZE)
        !          3378:      The function 'memory_object_init' serves as a notification that the
        !          3379:      kernel has been asked to map the given memory object into a task's
        !          3380:      virtual address space.  Additionally, it provides a port on which
        !          3381:      the memory manager may issue cache management requests, and a port
        !          3382:      which the kernel will use to name this data region.  In the event
        !          3383:      that different each will perform a 'memory_object_init' call with
        !          3384:      new request and name ports.  The virtual page size that is used by
        !          3385:      the calling kernel is included for planning purposes.
        !          3386: 
        !          3387:      When the memory manager is prepared to accept requests for data for
        !          3388:      this object, it must call 'memory_object_ready' with the attribute.
        !          3389:      Otherwise the kernel will not process requests on this object.  To
        !          3390:      reject all mappings of this object, the memory manager may use
        !          3391:      'memory_object_destroy'.
        !          3392: 
        !          3393:      The argument MEMORY_OBJECT is the port that represents the memory
        !          3394:      object data, as supplied to the kernel in a 'vm_map' call.
        !          3395:      MEMORY_CONTROL is the request port to which a response is
        !          3396:      requested.  (In the event that a memory object has been supplied to
        !          3397:      more than one the kernel that has made the request.)
        !          3398:      MEMORY_OBJECT_NAME is a port used by the kernel to refer to the
        !          3399:      memory object data in response to 'vm_region' calls.
        !          3400:      'memory_object_page_size' is the page size to be used by this
        !          3401:      kernel.  All data sizes in calls involving this kernel must be an
        !          3402:      integral multiple of the page size.  Note that different kernels,
        !          3403:      indicated by a different 'memory_control', may have different page
        !          3404:      sizes.
        !          3405: 
        !          3406:      The function should return 'KERN_SUCCESS', but since this routine
        !          3407:      is called by the kernel, which does not wait for a reply message,
        !          3408:      this value is ignored.
        !          3409: 
        !          3410:  -- Function: kern_return_t memory_object_ready
        !          3411:           (memory_object_control_t MEMORY_CONTROL,
        !          3412:           boolean_t MAY_CACHE_OBJECT,
        !          3413:           memory_object_copy_strategy_t COPY_STRATEGY)
        !          3414:      The function 'memory_object_ready' informs the kernel that the
        !          3415:      memory manager is ready to receive data or unlock requests on
        !          3416:      behalf of the clients.  The argument MEMORY_CONTROL is the port,
        !          3417:      provided by the kernel in a 'memory_object_init' call, to which
        !          3418:      cache management requests may be issued.  If MAY_CACHE_OBJECT is
        !          3419:      set, the kernel may keep data associated with this memory object,
        !          3420:      even after virtual memory references to it are gone.
        !          3421: 
        !          3422:      COPY_STRATEGY tells how the kernel should copy regions of the
        !          3423:      associated memory object.  There are three possible caching
        !          3424:      strategies: 'MEMORY_OBJECT_COPY_NONE' which specifies that nothing
        !          3425:      special should be done when data in the object is copied;
        !          3426:      'MEMORY_OBJECT_COPY_CALL' which specifies that the memory manager
        !          3427:      should be notified via a 'memory_object_copy' call before any part
        !          3428:      of the object is copied; and 'MEMORY_OBJECT_COPY_DELAY' which
        !          3429:      guarantees that the memory manager does not externally modify the
        !          3430:      data so that the kernel can use its normal copy-on-write
        !          3431:      algorithms.  'MEMORY_OBJECT_COPY_DELAY' is the strategy most
        !          3432:      commonly used.
        !          3433: 
        !          3434:      This routine does not receive a reply message (and consequently has
        !          3435:      no return value), so only message transmission errors apply.
        !          3436: 
        !          3437: 
        !          3438: File: mach.info,  Node: Memory Object Termination,  Next: Memory Objects and Data,  Prev: Memory Object Creation,  Up: External Memory Management
        !          3439: 
        !          3440: 6.3 Memory Object Termination
        !          3441: =============================
        !          3442: 
        !          3443:  -- Function: kern_return_t memory_object_terminate
        !          3444:           (memory_object_t MEMORY_OBJECT,
        !          3445:           memory_object_control_t MEMORY_CONTROL,
        !          3446:           memory_object_name_t MEMORY_OBJECT_NAME)
        !          3447:  -- Function: kern_return_t seqnos_memory_object_terminate
        !          3448:           (memory_object_t MEMORY_OBJECT, mach_port_seqno_t SEQNO,
        !          3449:           memory_object_control_t MEMORY_CONTROL,
        !          3450:           memory_object_name_t MEMORY_OBJECT_NAME)
        !          3451:      The function 'memory_object_terminate' indicates that the kernel
        !          3452:      has completed its use of the given memory object.  All rights to
        !          3453:      the memory object control and name ports are included, so that the
        !          3454:      memory manager can destroy them (using 'mach_port_deallocate')
        !          3455:      after doing appropriate bookkeeping.  The kernel will terminate a
        !          3456:      memory object only after all address space mappings of that memory
        !          3457:      object have been deallocated, or upon explicit request by the
        !          3458:      memory manager.
        !          3459: 
        !          3460:      The argument MEMORY_OBJECT is the port that represents the memory
        !          3461:      object data, as supplied to the kernel in a 'vm_map' call.
        !          3462:      MEMORY_CONTROL is the request port to which a response is
        !          3463:      requested.  (In the event that a memory object has been supplied to
        !          3464:      more than one the kernel that has made the request.)
        !          3465:      MEMORY_OBJECT_NAME is a port used by the kernel to refer to the
        !          3466:      memory object data in response to 'vm_region' calls.
        !          3467: 
        !          3468:      The function should return 'KERN_SUCCESS', but since this routine
        !          3469:      is called by the kernel, which does not wait for a reply message,
        !          3470:      this value is ignored.
        !          3471: 
        !          3472:  -- Function: kern_return_t memory_object_destroy
        !          3473:           (memory_object_control_t MEMORY_CONTROL, kern_return_t REASON)
        !          3474:      The function 'memory_object_destroy' tells the kernel to shut down
        !          3475:      the memory object.  As a result of this call the kernel will no
        !          3476:      longer support paging activity or any 'memory_object' calls on this
        !          3477:      object, and all rights to the memory object port, the memory
        !          3478:      control port and the memory name port will be returned to the
        !          3479:      memory manager in a memory_object_terminate call.  If the memory
        !          3480:      manager is concerned that any modified cached data be returned to
        !          3481:      it before the object is terminated, it should call
        !          3482:      'memory_object_lock_request' with SHOULD_FLUSH set and a lock value
        !          3483:      of 'VM_PROT_WRITE' before making this call.
        !          3484: 
        !          3485:      The argument MEMORY_CONTROL is the port, provided by the kernel in
        !          3486:      a 'memory_object_init' call, to which cache management requests may
        !          3487:      be issued.  REASON is an error code indicating why the object must
        !          3488:      be destroyed.
        !          3489: 
        !          3490:      This routine does not receive a reply message (and consequently has
        !          3491:      no return value), so only message transmission errors apply.
        !          3492: 
        !          3493: 
        !          3494: File: mach.info,  Node: Memory Objects and Data,  Next: Memory Object Locking,  Prev: Memory Object Termination,  Up: External Memory Management
        !          3495: 
        !          3496: 6.4 Memory Objects and Data
        !          3497: ===========================
        !          3498: 
        !          3499:  -- Function: kern_return_t memory_object_data_return
        !          3500:           (memory_object_t MEMORY_OBJECT,
        !          3501:           memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          3502:           vm_offset_t DATA, vm_size_t DATA_COUNT, boolean_t DIRTY,
        !          3503:           boolean_t KERNEL_COPY)
        !          3504:  -- Function: kern_return_t seqnos_memory_object_data_return
        !          3505:           (memory_object_t MEMORY_OBJECT, mach_port_seqno_t SEQNO,
        !          3506:           memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          3507:           vm_offset_t DATA, vm_size_t DATA_COUNT, boolean_t DIRTY,
        !          3508:           boolean_t KERNEL_COPY)
        !          3509:      The function 'memory_object_data_return' provides the memory
        !          3510:      manager with data that has been modified while cached in physical
        !          3511:      memory.  Once the memory manager no longer needs this data (e.g.,
        !          3512:      it has been written to another storage medium), it should be
        !          3513:      deallocated using 'vm_deallocate'.
        !          3514: 
        !          3515:      The argument MEMORY_OBJECT is the port that represents the memory
        !          3516:      object data, as supplied to the kernel in a 'vm_map' call.
        !          3517:      MEMORY_CONTROL is the request port to which a response is
        !          3518:      requested.  (In the event that a memory object has been supplied to
        !          3519:      more than one the kernel that has made the request.)  OFFSET is the
        !          3520:      offset within a memory object to which this call refers.  This will
        !          3521:      be page aligned.  DATA is the data which has been modified while
        !          3522:      cached in physical memory.  DATA_COUNT is the amount of data to be
        !          3523:      written, in bytes.  This will be an integral number of memory
        !          3524:      object pages.
        !          3525: 
        !          3526:      The kernel will also use this call to return precious pages.  If an
        !          3527:      unmodified precious age is returned, DIRTY is set to 'FALSE',
        !          3528:      otherwise it is 'TRUE'.  If KERNEL_COPY is 'TRUE', the kernel kept
        !          3529:      a copy of the page.  Precious data remains precious if the kernel
        !          3530:      keeps a copy.  The indication that the kernel kept a copy is only a
        !          3531:      hint if the data is not precious; the cleaned copy may be discarded
        !          3532:      without further notifying the manager.
        !          3533: 
        !          3534:      The function should return 'KERN_SUCCESS', but since this routine
        !          3535:      is called by the kernel, which does not wait for a reply message,
        !          3536:      this value is ignored.
        !          3537: 
        !          3538:  -- Function: kern_return_t memory_object_data_request
        !          3539:           (memory_object_t MEMORY_OBJECT,
        !          3540:           memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          3541:           vm_offset_t LENGTH, vm_prot_t DESIRED_ACCESS)
        !          3542:  -- Function: kern_return_t seqnos_memory_object_data_request
        !          3543:           (memory_object_t MEMORY_OBJECT, mach_port_seqno_t SEQNO,
        !          3544:           memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          3545:           vm_offset_t LENGTH, vm_prot_t DESIRED_ACCESS)
        !          3546:      The function 'memory_object_data_request' is a request for data
        !          3547:      from the specified memory object, for at least the access
        !          3548:      specified.  The memory manager is expected to return at least the
        !          3549:      specified data, with as much access as it can allow, using
        !          3550:      'memory_object_data_supply'.  If the memory manager is unable to
        !          3551:      provide the data (for example, because of a hardware error), it may
        !          3552:      use the 'memory_object_data_error' call.  The
        !          3553:      'memory_object_data_unavailable' call may be used to tell the
        !          3554:      kernel to supply zero-filled memory for this region.
        !          3555: 
        !          3556:      The argument MEMORY_OBJECT is the port that represents the memory
        !          3557:      object data, as supplied to the kernel in a 'vm_map' call.
        !          3558:      MEMORY_CONTROL is the request port to which a response is
        !          3559:      requested.  (In the event that a memory object has been supplied to
        !          3560:      more than one the kernel that has made the request.)  OFFSET is the
        !          3561:      offset within a memory object to which this call refers.  This will
        !          3562:      be page aligned.  LENGTH is the number of bytes of data, starting
        !          3563:      at OFFSET, to which this call refers.  This will be an integral
        !          3564:      number of memory object pages.  DESIRED_ACCESS is a protection
        !          3565:      value describing the memory access modes which must be permitted on
        !          3566:      the specified cached data.  One or more of: 'VM_PROT_READ',
        !          3567:      'VM_PROT_WRITE' or 'VM_PROT_EXECUTE'.
        !          3568: 
        !          3569:      The function should return 'KERN_SUCCESS', but since this routine
        !          3570:      is called by the kernel, which does not wait for a reply message,
        !          3571:      this value is ignored.
        !          3572: 
        !          3573:  -- Function: kern_return_t memory_object_data_supply
        !          3574:           (memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          3575:           vm_offset_t DATA, vm_size_t DATA_COUNT, vm_prot_t LOCK_VALUE,
        !          3576:           boolean_t PRECIOUS, mach_port_t REPLY)
        !          3577:      The function 'memory_object_data_supply' supplies the kernel with
        !          3578:      data for the specified memory object.  Ordinarily, memory managers
        !          3579:      should only provide data in response to
        !          3580:      'memory_object_data_request' calls from the kernel (but they may
        !          3581:      provide data in advance as desired).  When data already held by
        !          3582:      this kernel is provided again, the new data is ignored.  The kernel
        !          3583:      may not provide any data (or protection) consistency among pages
        !          3584:      with different virtual page alignments within the same object.
        !          3585: 
        !          3586:      The argument MEMORY_CONTROL is the port, provided by the kernel in
        !          3587:      a 'memory_object_init' call, to which cache management requests may
        !          3588:      be issued.  OFFSET is an offset within a memory object in bytes.
        !          3589:      This must be page aligned.  DATA is the data that is being provided
        !          3590:      to the kernel.  This is a pointer to the data.  DATA_COUNT is the
        !          3591:      amount of data to be provided.  Only whole virtual pages of data
        !          3592:      can be accepted; partial pages will be discarded.
        !          3593: 
        !          3594:      LOCK_VALUE is a protection value indicating those forms of access
        !          3595:      that should *not* be permitted to the specified cached data.  The
        !          3596:      lock values must be one or more of the set: 'VM_PROT_NONE',
        !          3597:      'VM_PROT_READ', 'VM_PROT_WRITE', 'VM_PROT_EXECUTE' and
        !          3598:      'VM_PROT_ALL' as defined in 'mach/vm_prot.h'.
        !          3599: 
        !          3600:      If PRECIOUS is 'FALSE', the kernel treats the data as a temporary
        !          3601:      and may throw it away if it hasn't been changed.  If the PRECIOUS
        !          3602:      value is 'TRUE', the kernel treats its copy as a data repository
        !          3603:      and promises to return it to the manager; the manager may tell the
        !          3604:      kernel to throw it away instead by flushing and not cleaning the
        !          3605:      data (see 'memory_object_lock_request').
        !          3606: 
        !          3607:      If REPLY_TO is not 'MACH_PORT_NULL', the kernel will send a
        !          3608:      completion message to the provided port (see
        !          3609:      'memory_object_supply_completed').
        !          3610: 
        !          3611:      This routine does not receive a reply message (and consequently has
        !          3612:      no return value), so only message transmission errors apply.
        !          3613: 
        !          3614:  -- Function: kern_return_t memory_object_supply_completed
        !          3615:           (memory_object_t MEMORY_OBJECT,
        !          3616:           memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          3617:           vm_size_t LENGTH, kern_return_t RESULT,
        !          3618:           vm_offset_t ERROR_OFFSET)
        !          3619:  -- Function: kern_return_t seqnos_memory_object_supply_completed
        !          3620:           (memory_object_t MEMORY_OBJECT, mach_port_seqno_t SEQNO,
        !          3621:           memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          3622:           vm_size_t LENGTH, kern_return_t RESULT,
        !          3623:           vm_offset_t ERROR_OFFSET)
        !          3624:      The function 'memory_object_supply_completed' indicates that a
        !          3625:      previous 'memory_object_data_supply' has been completed.  Note that
        !          3626:      this call is made on whatever port was specified in the
        !          3627:      'memory_object_data_supply' call; that port need not be the memory
        !          3628:      object port itself.  No reply is expected after this call.
        !          3629: 
        !          3630:      The argument MEMORY_OBJECT is the port that represents the memory
        !          3631:      object data, as supplied to the kernel in a 'vm_map' call.
        !          3632:      MEMORY_CONTROL is the request port to which a response is
        !          3633:      requested.  (In the event that a memory object has been supplied to
        !          3634:      more than one the kernel that has made the request.)  OFFSET is the
        !          3635:      offset within a memory object to which this call refers.  LENGTH is
        !          3636:      the length of the data covered by the lock request.  The RESULT
        !          3637:      parameter indicates what happened during the supply.  If it is not
        !          3638:      'KERN_SUCCESS', then ERROR_OFFSET identifies the first offset at
        !          3639:      which a problem occurred.  The pagein operation stopped at this
        !          3640:      point.  Note that the only failures reported by this mechanism are
        !          3641:      'KERN_MEMORY_PRESENT'.  All other failures (invalid argument, error
        !          3642:      on pagein of supplied data in manager's address space) cause the
        !          3643:      entire operation to fail.
        !          3644: 
        !          3645:  -- Function: kern_return_t memory_object_data_error
        !          3646:           (memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          3647:           vm_size_t SIZE, kern_return_t REASON)
        !          3648:      The function 'memory_object_data_error' indicates that the memory
        !          3649:      manager cannot return the data requested for the given region,
        !          3650:      specifying a reason for the error.  This is typically used when a
        !          3651:      hardware error is encountered.
        !          3652: 
        !          3653:      The argument MEMORY_CONTROL is the port, provided by the kernel in
        !          3654:      a 'memory_object_init' call, to which cache management requests may
        !          3655:      be issued.  OFFSET is an offset within a memory object in bytes.
        !          3656:      This must be page aligned.  DATA is the data that is being provided
        !          3657:      to the kernel.  This is a pointer to the data.  SIZE is the amount
        !          3658:      of cached data (starting at OFFSET) to be handled.  This must be an
        !          3659:      integral number of the memory object page size.  REASON is an error
        !          3660:      code indicating what type of error occurred.
        !          3661: 
        !          3662:      This routine does not receive a reply message (and consequently has
        !          3663:      no return value), so only message transmission errors apply.
        !          3664: 
        !          3665:  -- Function: kern_return_t memory_object_data_unavailable
        !          3666:           (memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          3667:           vm_size_t SIZE, kern_return_t REASON)
        !          3668:      The function 'memory_object_data_unavailable' indicates that the
        !          3669:      memory object does not have data for the given region and that the
        !          3670:      kernel should provide the data for this range.  The memory manager
        !          3671:      may use this call in three different situations.
        !          3672: 
        !          3673:        1. The object was created by 'memory_object_create' and the
        !          3674:           kernel has not yet provided data for this range (either via a
        !          3675:           'memory_object_data_initialize', 'memory_object_data_write' or
        !          3676:           a 'memory_object_data_return' for the object.
        !          3677: 
        !          3678:        2. The object was created by an 'memory_object_data_copy' and the
        !          3679:           kernel should copy this region from the original memory
        !          3680:           object.
        !          3681: 
        !          3682:        3. The object is a normal user-created memory object and the
        !          3683:           kernel should supply unlocked zero-filled pages for the range.
        !          3684: 
        !          3685:      The argument MEMORY_CONTROL is the port, provided by the kernel in
        !          3686:      a 'memory_object_init' call, to which cache management requests may
        !          3687:      be issued.  OFFSET is an offset within a memory object, in bytes.
        !          3688:      This must be page aligned.  SIZE is the amount of cached data
        !          3689:      (starting at OFFSET) to be handled.  This must be an integral
        !          3690:      number of the memory object page size.
        !          3691: 
        !          3692:      This routine does not receive a reply message (and consequently has
        !          3693:      no return value), so only message transmission errors apply.
        !          3694: 
        !          3695:  -- Function: kern_return_t memory_object_copy
        !          3696:           (memory_object_t OLD_MEMORY_OBJECT,
        !          3697:           memory_object_control_t OLD_MEMORY_CONTROL,
        !          3698:           vm_offset_t OFFSET, vm_size_t LENGTH,
        !          3699:           memory_object_t NEW_MEMORY_OBJECT)
        !          3700:  -- Function: kern_return_t seqnos_memory_object_copy
        !          3701:           (memory_object_t OLD_MEMORY_OBJECT, mach_port_seqno_t SEQNO,
        !          3702:           memory_object_control_t OLD_MEMORY_CONTROL,
        !          3703:           vm_offset_t OFFSET, vm_size_t LENGTH,
        !          3704:           memory_object_t NEW_MEMORY_OBJECT)
        !          3705:      The function 'memory_object_copy' indicates that a copy has been
        !          3706:      made of the specified range of the given original memory object.
        !          3707:      This call includes only the new memory object itself; a
        !          3708:      'memory_object_init' call will be made on the new memory object
        !          3709:      after the currently cached pages of the original object are
        !          3710:      prepared.  After the memory manager receives the init call, it must
        !          3711:      reply with the 'memory_object_ready' call to assert the "ready"
        !          3712:      attribute.  The kernel will use the new memory object, control and
        !          3713:      name ports to refer to the new copy.
        !          3714: 
        !          3715:      This call is made when the original memory object had the caching
        !          3716:      parameter set to 'MEMORY_OBJECT_COPY_CALL' and a user of the object
        !          3717:      has asked the kernel to copy it.
        !          3718: 
        !          3719:      Cached pages from the original memory object at the time of the
        !          3720:      copy operation are handled as follows: Readable pages may be
        !          3721:      silently copied to the new memory object (with all access
        !          3722:      permissions).  Pages not copied are locked to prevent write access.
        !          3723: 
        !          3724:      The new memory object is *temporary*, meaning that the memory
        !          3725:      manager should not change its contents or allow the memory object
        !          3726:      to be mapped in another client.  The memory manager may use the
        !          3727:      'memory_object_data_unavailable' call to indicate that the
        !          3728:      appropriate pages of the original memory object may be used to
        !          3729:      fulfill the data request.
        !          3730: 
        !          3731:      The argument OLD_MEMORY_OBJECT is the port that represents the old
        !          3732:      memory object data.  OLD_MEMORY_CONTROL is the kernel port for the
        !          3733:      old object.  OFFSET is the offset within a memory object to which
        !          3734:      this call refers.  This will be page aligned.  LENGTH is the number
        !          3735:      of bytes of data, starting at OFFSET, to which this call refers.
        !          3736:      This will be an integral number of memory object pages.
        !          3737:      NEW_MEMORY_OBJECT is a new memory object created by the kernel; see
        !          3738:      synopsis for further description.  Note that all port rights
        !          3739:      (including receive rights) are included for the new memory object.
        !          3740: 
        !          3741:      The function should return 'KERN_SUCCESS', but since this routine
        !          3742:      is called by the kernel, which does not wait for a reply message,
        !          3743:      this value is ignored.
        !          3744: 
        !          3745:    The remaining interfaces in this section are obsolete.
        !          3746: 
        !          3747:  -- Function: kern_return_t memory_object_data_write
        !          3748:           (memory_object_t MEMORY_OBJECT,
        !          3749:           memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          3750:           vm_offset_t DATA, vm_size_t DATA_COUNT)
        !          3751:  -- Function: kern_return_t seqnos_memory_object_data_write
        !          3752:           (memory_object_t MEMORY_OBJECT, mach_port_seqno_t SEQNO,
        !          3753:           memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          3754:           vm_offset_t DATA, vm_size_t DATA_COUNT)
        !          3755:      The function 'memory_object_data_write' provides the memory manager
        !          3756:      with data that has been modified while cached in physical memory.
        !          3757:      It is the old form of 'memory_object_data_return'.  Once the memory
        !          3758:      manager no longer needs this data (e.g., it has been written to
        !          3759:      another storage medium), it should be deallocated using
        !          3760:      'vm_deallocate'.
        !          3761: 
        !          3762:      The argument MEMORY_OBJECT is the port that represents the memory
        !          3763:      object data, as supplied to the kernel in a 'vm_map' call.
        !          3764:      MEMORY_CONTROL is the request port to which a response is
        !          3765:      requested.  (In the event that a memory object has been supplied to
        !          3766:      more than one the kernel that has made the request.)  OFFSET is the
        !          3767:      offset within a memory object to which this call refers.  This will
        !          3768:      be page aligned.  DATA is the data which has been modified while
        !          3769:      cached in physical memory.  DATA_COUNT is the amount of data to be
        !          3770:      written, in bytes.  This will be an integral number of memory
        !          3771:      object pages.
        !          3772: 
        !          3773:      The function should return 'KERN_SUCCESS', but since this routine
        !          3774:      is called by the kernel, which does not wait for a reply message,
        !          3775:      this value is ignored.
        !          3776: 
        !          3777:  -- Function: kern_return_t memory_object_data_provided
        !          3778:           (memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          3779:           vm_offset_t DATA, vm_size_t DATA_COUNT, vm_prot_t LOCK_VALUE)
        !          3780:      The function 'memory_object_data_provided' supplies the kernel with
        !          3781:      data for the specified memory object.  It is the old form of
        !          3782:      'memory_object_data_supply'.  Ordinarily, memory managers should
        !          3783:      only provide data in response to 'memory_object_data_request' calls
        !          3784:      from the kernel.  The LOCK_VALUE specifies what type of access will
        !          3785:      not be allowed to the data range.  The lock values must be one or
        !          3786:      more of the set: 'VM_PROT_NONE', 'VM_PROT_READ', 'VM_PROT_WRITE',
        !          3787:      'VM_PROT_EXECUTE' and 'VM_PROT_ALL' as defined in 'mach/vm_prot.h'.
        !          3788: 
        !          3789:      The argument MEMORY_CONTROL is the port, provided by the kernel in
        !          3790:      a 'memory_object_init' call, to which cache management requests may
        !          3791:      be issued.  OFFSET is an offset within a memory object in bytes.
        !          3792:      This must be page aligned.  DATA is the data that is being provided
        !          3793:      to the kernel.  This is a pointer to the data.  DATA_COUNT is the
        !          3794:      amount of data to be provided.  This must be an integral number of
        !          3795:      memory object pages.  LOCK_VALUE is a protection value indicating
        !          3796:      those forms of access that should *not* be permitted to the
        !          3797:      specified cached data.
        !          3798: 
        !          3799:      This routine does not receive a reply message (and consequently has
        !          3800:      no return value), so only message transmission errors apply.
        !          3801: 
        !          3802: 
        !          3803: File: mach.info,  Node: Memory Object Locking,  Next: Memory Object Attributes,  Prev: Memory Objects and Data,  Up: External Memory Management
        !          3804: 
        !          3805: 6.5 Memory Object Locking
        !          3806: =========================
        !          3807: 
        !          3808:  -- Function: kern_return_t memory_object_lock_request
        !          3809:           (memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          3810:           vm_size_t SIZE, memory_object_return_t SHOULD_CLEAN,
        !          3811:           boolean_t SHOULD_FLUSH, vm_prot_t LOCK_VALUE,
        !          3812:           mach_port_t REPLY_TO)
        !          3813:      The function 'memory_object_lock_request' allows a memory manager
        !          3814:      to make cache management requests.  As specified in arguments to
        !          3815:      the call, the kernel will:
        !          3816:         * clean (i.e., write back using 'memory_object_data_supply' or
        !          3817:           'memory_object_data_write') any cached data which has been
        !          3818:           modified since the last time it was written
        !          3819: 
        !          3820:         * flush (i.e., remove any uses of) that data from memory
        !          3821: 
        !          3822:         * lock (i.e., prohibit the specified uses of) the cached data
        !          3823: 
        !          3824:      Locks applied to cached data are not cumulative; new lock values
        !          3825:      override previous ones.  Thus, data may also be unlocked using this
        !          3826:      primitive.  The lock values must be one or more of the following
        !          3827:      values: 'VM_PROT_NONE', 'VM_PROT_READ', 'VM_PROT_WRITE',
        !          3828:      'VM_PROT_EXECUTE' and 'VM_PROT_ALL' as defined in 'mach/vm_prot.h'.
        !          3829: 
        !          3830:      Only data which is cached at the time of this call is affected.
        !          3831:      When a running thread requires a prohibited access to cached data,
        !          3832:      the kernel will issue a 'memory_object_data_unlock' call specifying
        !          3833:      the forms of access required.
        !          3834: 
        !          3835:      Once all of the actions requested by this call have been completed,
        !          3836:      the kernel issues a 'memory_object_lock_completed' call on the
        !          3837:      specified reply port.
        !          3838: 
        !          3839:      The argument MEMORY_CONTROL is the port, provided by the kernel in
        !          3840:      a 'memory_object_init' call, to which cache management requests may
        !          3841:      be issued.  OFFSET is an offset within a memory object, in bytes.
        !          3842:      This must be page aligned.  SIZE is the amount of cached data
        !          3843:      (starting at OFFSET) to be handled.  This must be an integral
        !          3844:      number of the memory object page size.  If SHOULD_CLEAN is set,
        !          3845:      modified data should be written back to the memory manager.  If
        !          3846:      SHOULD_FLUSH is set, the specified cached data should be
        !          3847:      invalidated, and all uses of that data should be revoked.
        !          3848:      LOCK_VALUE is a protection value indicating those forms of access
        !          3849:      that should *not* be permitted to the specified cached data.
        !          3850:      REPLY_TO is a port on which a 'memory_object_lock_completed' call
        !          3851:      should be issued, or 'MACH_PORT_NULL' if no acknowledgement is
        !          3852:      desired.
        !          3853: 
        !          3854:      This routine does not receive a reply message (and consequently has
        !          3855:      no return value), so only message transmission errors apply.
        !          3856: 
        !          3857:  -- Function: kern_return_t memory_object_lock_completed
        !          3858:           (memory_object_t MEMORY_OBJECT,
        !          3859:           memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          3860:           vm_size_t LENGTH)
        !          3861:  -- Function: kern_return_t seqnos_memory_object_lock_completed
        !          3862:           (memory_object_t MEMORY_OBJECT, mach_port_seqno_t SEQNO,
        !          3863:           memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          3864:           vm_size_t LENGTH)
        !          3865:      The function 'memory_object_lock_completed' indicates that a
        !          3866:      previous 'memory_object_lock_request' has been completed.  Note
        !          3867:      that this call is made on whatever port was specified in the
        !          3868:      'memory_object_lock_request' call; that port need not be the memory
        !          3869:      object port itself.  No reply is expected after this call.
        !          3870: 
        !          3871:      The argument MEMORY_OBJECT is the port that represents the memory
        !          3872:      object data, as supplied to the kernel in a 'vm_map' call.
        !          3873:      MEMORY_CONTROL is the request port to which a response is
        !          3874:      requested.  (In the event that a memory object has been supplied to
        !          3875:      more than one the kernel that has made the request.)  OFFSET is the
        !          3876:      offset within a memory object to which this call refers.  LENGTH is
        !          3877:      the length of the data covered by the lock request.
        !          3878: 
        !          3879:      The function should return 'KERN_SUCCESS', but since this routine
        !          3880:      is called by the kernel, which does not wait for a reply message,
        !          3881:      this value is ignored.
        !          3882: 
        !          3883:  -- Function: kern_return_t memory_object_data_unlock
        !          3884:           (memory_object_t MEMORY_OBJECT,
        !          3885:           memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          3886:           vm_size_t LENGTH, vm_prot_t DESIRED_ACCESS)
        !          3887:  -- Function: kern_return_t seqnos_memory_object_data_unlock
        !          3888:           (memory_object_t MEMORY_OBJECT, mach_port_seqno_t SEQNO,
        !          3889:           memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          3890:           vm_size_t LENGTH, vm_prot_t DESIRED_ACCESS)
        !          3891:      The function 'memory_object_data_unlock' is a request that the
        !          3892:      memory manager permit at least the desired access to the specified
        !          3893:      data cached by the kernel.  A call to 'memory_object_lock_request'
        !          3894:      is expected in response.
        !          3895: 
        !          3896:      The argument MEMORY_OBJECT is the port that represents the memory
        !          3897:      object data, as supplied to the kernel in a 'vm_map' call.
        !          3898:      MEMORY_CONTROL is the request port to which a response is
        !          3899:      requested.  (In the event that a memory object has been supplied to
        !          3900:      more than one the kernel that has made the request.)  OFFSET is the
        !          3901:      offset within a memory object to which this call refers.  This will
        !          3902:      be page aligned.  LENGTH is the number of bytes of data, starting
        !          3903:      at OFFSET, to which this call refers.  This will be an integral
        !          3904:      number of memory object pages.  DESIRED_ACCESS a protection value
        !          3905:      describing the memory access modes which must be permitted on the
        !          3906:      specified cached data.  One or more of: 'VM_PROT_READ',
        !          3907:      'VM_PROT_WRITE' or 'VM_PROT_EXECUTE'.
        !          3908: 
        !          3909:      The function should return 'KERN_SUCCESS', but since this routine
        !          3910:      is called by the kernel, which does not wait for a reply message,
        !          3911:      this value is ignored.
        !          3912: 
        !          3913: 
        !          3914: File: mach.info,  Node: Memory Object Attributes,  Next: Default Memory Manager,  Prev: Memory Object Locking,  Up: External Memory Management
        !          3915: 
        !          3916: 6.6 Memory Object Attributes
        !          3917: ============================
        !          3918: 
        !          3919:  -- Function: kern_return_t memory_object_get_attributes
        !          3920:           (memory_object_control_t MEMORY_CONTROL,
        !          3921:           boolean_t *OBJECT_READY, boolean_t *MAY_CACHE_OBJECT,
        !          3922:           memory_object_copy_strategy_t *COPY_STRATEGY)
        !          3923:      The function 'memory_object_get_attribute' retrieves the current
        !          3924:      attributes associated with the memory object.
        !          3925: 
        !          3926:      The argument MEMORY_CONTROL is the port, provided by the kernel in
        !          3927:      a 'memory_object_init' call, to which cache management requests may
        !          3928:      be issued.  If OBJECT_READY is set, the kernel may issue new data
        !          3929:      and unlock requests on the associated memory object.  If
        !          3930:      MAY_CACHE_OBJECT is set, the kernel may keep data associated with
        !          3931:      this memory object, even after virtual memory references to it are
        !          3932:      gone.  COPY_STRATEGY tells how the kernel should copy regions of
        !          3933:      the associated memory object.
        !          3934: 
        !          3935:      This routine does not receive a reply message (and consequently has
        !          3936:      no return value), so only message transmission errors apply.
        !          3937: 
        !          3938:  -- Function: kern_return_t memory_object_change_attributes
        !          3939:           (memory_object_control_t MEMORY_CONTROL,
        !          3940:           boolean_t MAY_CACHE_OBJECT,
        !          3941:           memory_object_copy_strategy_t COPY_STRATEGY,
        !          3942:           mach_port_t REPLY_TO)
        !          3943:      The function 'memory_object_change_attribute' sets
        !          3944:      performance-related attributes for the specified memory object.  If
        !          3945:      the caching attribute is asserted, the kernel is permitted (and
        !          3946:      encouraged) to maintain cached data for this memory object even
        !          3947:      after no virtual address space contains this data.
        !          3948: 
        !          3949:      There are three possible caching strategies:
        !          3950:      'MEMORY_OBJECT_COPY_NONE' which specifies that nothing special
        !          3951:      should be done when data in the object is copied;
        !          3952:      'MEMORY_OBJECT_COPY_CALL' which specifies that the memory manager
        !          3953:      should be notified via a 'memory_object_copy' call before any part
        !          3954:      of the object is copied; and 'MEMORY_OBJECT_COPY_DELAY' which
        !          3955:      guarantees that the memory manager does not externally modify the
        !          3956:      data so that the kernel can use its normal copy-on-write
        !          3957:      algorithms.  'MEMORY_OBJECT_COPY_DELAY' is the strategy most
        !          3958:      commonly used.
        !          3959: 
        !          3960:      The argument MEMORY_CONTROL is the port, provided by the kernel in
        !          3961:      a 'memory_object_init' call, to which cache management requests may
        !          3962:      be issued.  If MAY_CACHE_OBJECT is set, the kernel may keep data
        !          3963:      associated with this memory object, even after virtual memory
        !          3964:      references to it are gone.  COPY_STRATEGY tells how the kernel
        !          3965:      should copy regions of the associated memory object.  REPLY_TO is a
        !          3966:      port on which a 'memory_object_change_completed' call will be
        !          3967:      issued upon completion of the attribute change, or 'MACH_PORT_NULL'
        !          3968:      if no acknowledgement is desired.
        !          3969: 
        !          3970:      This routine does not receive a reply message (and consequently has
        !          3971:      no return value), so only message transmission errors apply.
        !          3972: 
        !          3973:  -- Function: kern_return_t memory_object_change_completed
        !          3974:           (memory_object_t MEMORY_OBJECT, boolean_t MAY_CACHE_OBJECT,
        !          3975:           memory_object_copy_strategy_t COPY_STRATEGY)
        !          3976:  -- Function: kern_return_t seqnos_memory_object_change_completed
        !          3977:           (memory_object_t MEMORY_OBJECT, mach_port_seqno_t SEQNO,
        !          3978:           boolean_t MAY_CACHE_OBJECT,
        !          3979:           memory_object_copy_strategy_t COPY_STRATEGY)
        !          3980:      The function 'memory_object_change_completed' indicates the
        !          3981:      completion of an attribute change call.
        !          3982: 
        !          3983:    The following interface is obsoleted by 'memory_object_ready' and
        !          3984: 'memory_object_change_attributes'.  If the old form
        !          3985: 'memory_object_set_attributes' is used to make a memory object ready,
        !          3986: the kernel will write back data using the old 'memory_object_data_write'
        !          3987: interface rather than 'memory_object_data_return'..
        !          3988: 
        !          3989:  -- Function: kern_return_t memory_object_set_attributes
        !          3990:           (memory_object_control_t MEMORY_CONTROL, boolean OBJECT_READY,
        !          3991:           boolean_t MAY_CACHE_OBJECT,
        !          3992:           memory_object_copy_strategy_t COPY_STRATEGY)
        !          3993:      The function 'memory_object_set_attribute' controls how the memory
        !          3994:      object.  The kernel will only make data or unlock requests when the
        !          3995:      ready attribute is asserted.  If the caching attribute is asserted,
        !          3996:      the kernel is permitted (and encouraged) to maintain cached data
        !          3997:      for this memory object even after no virtual address space contains
        !          3998:      this data.
        !          3999: 
        !          4000:      There are three possible caching strategies:
        !          4001:      'MEMORY_OBJECT_COPY_NONE' which specifies that nothing special
        !          4002:      should be done when data in the object is copied;
        !          4003:      'MEMORY_OBJECT_COPY_CALL' which specifies that the memory manager
        !          4004:      should be notified via a 'memory_object_copy' call before any part
        !          4005:      of the object is copied; and 'MEMORY_OBJECT_COPY_DELAY' which
        !          4006:      guarantees that the memory manager does not externally modify the
        !          4007:      data so that the kernel can use its normal copy-on-write
        !          4008:      algorithms.  'MEMORY_OBJECT_COPY_DELAY' is the strategy most
        !          4009:      commonly used.
        !          4010: 
        !          4011:      The argument MEMORY_CONTROL is the port, provided by the kernel in
        !          4012:      a 'memory_object_init' call, to which cache management requests may
        !          4013:      be issued.  If OBJECT_READY is set, the kernel may issue new data
        !          4014:      and unlock requests on the associated memory object.  If
        !          4015:      MAY_CACHE_OBJECT is set, the kernel may keep data associated with
        !          4016:      this memory object, even after virtual memory references to it are
        !          4017:      gone.  COPY_STRATEGY tells how the kernel should copy regions of
        !          4018:      the associated memory object.
        !          4019: 
        !          4020:      This routine does not receive a reply message (and consequently has
        !          4021:      no return value), so only message transmission errors apply.
        !          4022: 
        !          4023: 
        !          4024: File: mach.info,  Node: Default Memory Manager,  Prev: Memory Object Attributes,  Up: External Memory Management
        !          4025: 
        !          4026: 6.7 Default Memory Manager
        !          4027: ==========================
        !          4028: 
        !          4029:  -- Function: kern_return_t vm_set_default_memory_manager (host_t HOST,
        !          4030:           mach_port_t *DEFAULT_MANAGER)
        !          4031:      The function 'vm_set_default_memory_manager' sets the kernel's
        !          4032:      default memory manager.  It sets the port to which newly-created
        !          4033:      temporary memory objects are delivered by 'memory_object_create' to
        !          4034:      the host.  The old memory manager port is returned.  If
        !          4035:      DEFAULT_MANAGER is 'MACH_PORT_NULL' then this routine just returns
        !          4036:      the current default manager port without changing it.
        !          4037: 
        !          4038:      The argument HOST is a task port to the kernel whose default memory
        !          4039:      manager is to be changed.  DEFAULT_MANAGER is an in/out parameter.
        !          4040:      As input, DEFAULT_MANAGER is the port that the new memory manager
        !          4041:      is listening on for 'memory_object_create' calls.  As output, it is
        !          4042:      the old default memory manager's port.
        !          4043: 
        !          4044:      The function returns 'KERN_SUCCESS' if the new memory manager is
        !          4045:      installed, and 'KERN_INVALID_ARGUMENT' if this task does not have
        !          4046:      the privileges required for this call.
        !          4047: 
        !          4048:  -- Function: kern_return_t memory_object_create
        !          4049:           (memory_object_t OLD_MEMORY_OBJECT,
        !          4050:           memory_object_t NEW_MEMORY_OBJECT, vm_size_t NEW_OBJECT_SIZE,
        !          4051:           memory_object_control_t NEW_CONTROL,
        !          4052:           memory_object_name_t NEW_NAME, vm_size_t NEW_PAGE_SIZE)
        !          4053:  -- Function: kern_return_t seqnos_memory_object_create
        !          4054:           (memory_object_t OLD_MEMORY_OBJECT, mach_port_seqno_t SEQNO,
        !          4055:           memory_object_t NEW_MEMORY_OBJECT, vm_size_t NEW_OBJECT_SIZE,
        !          4056:           memory_object_control_t NEW_CONTROL,
        !          4057:           memory_object_name_t NEW_NAME, vm_size_t NEW_PAGE_SIZE)
        !          4058:      The function 'memory_object_create' is a request that the given
        !          4059:      memory manager accept responsibility for the given memory object
        !          4060:      created by the kernel.  This call will only be made to the system
        !          4061:      *default memory manager*.  The memory object in question initially
        !          4062:      consists of zero-filled memory; only memory pages that are actually
        !          4063:      written will ever be provided to 'memory_object_data_request'
        !          4064:      calls, the default memory manager must use
        !          4065:      'memory_object_data_unavailable' for any pages that have not
        !          4066:      previously been written.
        !          4067: 
        !          4068:      No reply is expected after this call.  Since this call is directed
        !          4069:      to the default memory manager, the kernel assumes that it will be
        !          4070:      ready to handle data requests to this object and does not need the
        !          4071:      confirmation of a 'memory_object_set_attributes' call.
        !          4072: 
        !          4073:      The argument OLD_MEMORY_OBJECT is a memory object provided by the
        !          4074:      default memory manager on which the kernel can make
        !          4075:      'memory_object_create' calls.  NEW_MEMORY_OBJECT is a new memory
        !          4076:      object created by the kernel; see synopsis for further description.
        !          4077:      Note that all port rights (including receive rights) are included
        !          4078:      for the new memory object.  NEW_OBJECT_SIZE is the maximum size of
        !          4079:      the new object.  NEW_CONTROL is a port, created by the kernel, on
        !          4080:      which a memory manager may issue cache management requests for the
        !          4081:      new object.  NEW_NAME a port used by the kernel to refer to the new
        !          4082:      memory object data in response to 'vm_region' calls.  NEW_PAGE_SIZE
        !          4083:      is the page size to be used by this kernel.  All data sizes in
        !          4084:      calls involving this kernel must be an integral multiple of the
        !          4085:      page size.  Note that different kernels, indicated by different a
        !          4086:      'memory_control', may have different page sizes.
        !          4087: 
        !          4088:      The function should return 'KERN_SUCCESS', but since this routine
        !          4089:      is called by the kernel, which does not wait for a reply message,
        !          4090:      this value is ignored.
        !          4091: 
        !          4092:  -- Function: kern_return_t memory_object_data_initialize
        !          4093:           (memory_object_t MEMORY_OBJECT,
        !          4094:           memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          4095:           vm_offset_t DATA, vm_size_t DATA_COUNT)
        !          4096:  -- Function: kern_return_t seqnos_memory_object_data_initialize
        !          4097:           (memory_object_t MEMORY_OBJECT, mach_port_seqno_t SEQNO,
        !          4098:           memory_object_control_t MEMORY_CONTROL, vm_offset_t OFFSET,
        !          4099:           vm_offset_t DATA, vm_size_t DATA_COUNT)
        !          4100:      The function 'memory_object_data_initialize' provides the memory
        !          4101:      manager with initial data for a kernel-created memory object.  If
        !          4102:      the memory manager already has been supplied data (by a previous
        !          4103:      'memory_object_data_initialize', 'memory_object_data_write' or
        !          4104:      'memory_object_data_return'), then this data should be ignored.
        !          4105:      Otherwise, this call behaves exactly as does
        !          4106:      'memory_object_data_return' on memory objects created by the kernel
        !          4107:      via 'memory_object_create' and thus will only be made to default
        !          4108:      memory managers.  This call will not be made on objects created via
        !          4109:      'memory_object_copy'.
        !          4110: 
        !          4111:      The argument MEMORY_OBJECT the port that represents the memory
        !          4112:      object data, as supplied by the kernel in a 'memory_object_create'
        !          4113:      call.  MEMORY_CONTROL is the request port to which a response is
        !          4114:      requested.  (In the event that a memory object has been supplied to
        !          4115:      more than one the kernel that has made the request.)  OFFSET is the
        !          4116:      offset within a memory object to which this call refers.  This will
        !          4117:      be page aligned.  DATA is the data which has been modified while
        !          4118:      cached in physical memory.  DATA_COUNT is the amount of data to be
        !          4119:      written, in bytes.  This will be an integral number of memory
        !          4120:      object pages.
        !          4121: 
        !          4122:      The function should return 'KERN_SUCCESS', but since this routine
        !          4123:      is called by the kernel, which does not wait for a reply message,
        !          4124:      this value is ignored.
        !          4125: 
        !          4126: 
        !          4127: File: mach.info,  Node: Threads and Tasks,  Next: Host Interface,  Prev: External Memory Management,  Up: Top
        !          4128: 
        !          4129: 7 Threads and Tasks
        !          4130: *******************
        !          4131: 
        !          4132: * Menu:
        !          4133: 
        !          4134: * Thread Interface::              Manipulating threads.
        !          4135: * Task Interface::                Manipulating tasks.
        !          4136: * Profiling::                     Profiling threads and tasks.
        !          4137: 
        !          4138: 
        !          4139: File: mach.info,  Node: Thread Interface,  Next: Task Interface,  Up: Threads and Tasks
        !          4140: 
        !          4141: 7.1 Thread Interface
        !          4142: ====================
        !          4143: 
        !          4144:  -- Data type: thread_t
        !          4145:      This is a 'mach_port_t' and used to hold the port name of a thread
        !          4146:      port that represents the thread.  Manipulations of the thread are
        !          4147:      implemented as remote procedure calls to the thread port.  A thread
        !          4148:      can get a port to itself with the 'mach_thread_self' system call.
        !          4149: 
        !          4150: * Menu:
        !          4151: 
        !          4152: * Thread Creation::               Creating new threads.
        !          4153: * Thread Termination::            Terminating existing threads.
        !          4154: * Thread Information::            How to get informations on threads.
        !          4155: * Thread Settings::               How to set threads related informations.
        !          4156: * Thread Execution::              How to control the thread's machine state.
        !          4157: * Scheduling::                    Operations on thread scheduling.
        !          4158: * Thread Special Ports::          How to handle the thread's special ports.
        !          4159: * Exceptions::                    Managing exceptions.
        !          4160: 
        !          4161: 
        !          4162: File: mach.info,  Node: Thread Creation,  Next: Thread Termination,  Up: Thread Interface
        !          4163: 
        !          4164: 7.1.1 Thread Creation
        !          4165: ---------------------
        !          4166: 
        !          4167:  -- Function: kern_return_t thread_create (task_t PARENT_TASK,
        !          4168:           thread_t *CHILD_THREAD)
        !          4169:      The function 'thread_create' creates a new thread within the task
        !          4170:      specified by PARENT_TASK.  The new thread has no processor state,
        !          4171:      and has a suspend count of 1.  To get a new thread to run, first
        !          4172:      'thread_create' is called to get the new thread's identifier,
        !          4173:      (CHILD_THREAD).  Then 'thread_set_state' is called to set a
        !          4174:      processor state, and finally 'thread_resume' is called to get the
        !          4175:      thread scheduled to execute.
        !          4176: 
        !          4177:      When the thread is created send rights to its thread kernel port
        !          4178:      are given to it and returned to the caller in CHILD_THREAD.  The
        !          4179:      new thread's exception port is set to 'MACH_PORT_NULL'.
        !          4180: 
        !          4181:      The function returns 'KERN_SUCCESS' if a new thread has been
        !          4182:      created, 'KERN_INVALID_ARGUMENT' if PARENT_TASK is not a valid task
        !          4183:      and 'KERN_RESOURCE_SHORTAGE' if some critical kernel resource is
        !          4184:      not available.
        !          4185: 
        !          4186: 
        !          4187: File: mach.info,  Node: Thread Termination,  Next: Thread Information,  Prev: Thread Creation,  Up: Thread Interface
        !          4188: 
        !          4189: 7.1.2 Thread Termination
        !          4190: ------------------------
        !          4191: 
        !          4192:  -- Function: kern_return_t thread_terminate (thread_t TARGET_THREAD)
        !          4193:      The function 'thread_terminate' destroys the thread specified by
        !          4194:      TARGET_THREAD.
        !          4195: 
        !          4196:      The function returns 'KERN_SUCCESS' if the thread has been killed
        !          4197:      and 'KERN_INVALID_ARGUMENT' if TARGET_THREAD is not a thread.
        !          4198: 
        !          4199: 
        !          4200: File: mach.info,  Node: Thread Information,  Next: Thread Settings,  Prev: Thread Termination,  Up: Thread Interface
        !          4201: 
        !          4202: 7.1.3 Thread Information
        !          4203: ------------------------
        !          4204: 
        !          4205:  -- Function: thread_t mach_thread_self ()
        !          4206:      The 'mach_thread_self' system call returns the calling thread's
        !          4207:      thread port.
        !          4208: 
        !          4209:      'mach_thread_self' has an effect equivalent to receiving a send
        !          4210:      right for the thread port.  'mach_thread_self' returns the name of
        !          4211:      the send right.  In particular, successive calls will increase the
        !          4212:      calling task's user-reference count for the send right.
        !          4213: 
        !          4214:      As a special exception, the kernel will overrun the user reference
        !          4215:      count of the thread name port, so that this function can not fail
        !          4216:      for that reason.  Because of this, the user should not deallocate
        !          4217:      the port right if an overrun might have happened.  Otherwise the
        !          4218:      reference count could drop to zero and the send right be destroyed
        !          4219:      while the user still expects to be able to use it.  As the kernel
        !          4220:      does not make use of the number of extant send rights anyway, this
        !          4221:      is safe to do (the thread port itself is not destroyed, even when
        !          4222:      there are no send rights anymore).
        !          4223: 
        !          4224:      The function returns 'MACH_PORT_NULL' if a resource shortage
        !          4225:      prevented the reception of the send right or if the thread port is
        !          4226:      currently null and 'MACH_PORT_DEAD' if the thread port is currently
        !          4227:      dead.
        !          4228: 
        !          4229:  -- Function: kern_return_t thread_info (thread_t TARGET_THREAD,
        !          4230:           int FLAVOR, thread_info_t THREAD_INFO,
        !          4231:           mach_msg_type_number_t *THREAD_INFOCNT)
        !          4232:      The function 'thread_info' returns the selected information array
        !          4233:      for a thread, as specified by FLAVOR.
        !          4234: 
        !          4235:      THREAD_INFO is an array of integers that is supplied by the caller
        !          4236:      and returned filled with specified information.  THREAD_INFOCNT is
        !          4237:      supplied as the maximum number of integers in THREAD_INFO.  On
        !          4238:      return, it contains the actual number of integers in THREAD_INFO.
        !          4239:      The maximum number of integers returned by any flavor is
        !          4240:      'THREAD_INFO_MAX'.
        !          4241: 
        !          4242:      The type of information returned is defined by FLAVOR, which can be
        !          4243:      one of the following:
        !          4244: 
        !          4245:      'THREAD_BASIC_INFO'
        !          4246:           The function returns basic information about the thread, as
        !          4247:           defined by 'thread_basic_info_t'.  This includes the user and
        !          4248:           system time, the run state, and scheduling priority.  The
        !          4249:           number of integers returned is 'THREAD_BASIC_INFO_COUNT'.
        !          4250: 
        !          4251:      'THREAD_SCHED_INFO'
        !          4252:           The function returns information about the scheduling policy
        !          4253:           for the thread as defined by 'thread_sched_info_t'.  The
        !          4254:           number of integers returned is 'THREAD_SCHED_INFO_COUNT'.
        !          4255: 
        !          4256:      The function returns 'KERN_SUCCESS' if the call succeeded and
        !          4257:      'KERN_INVALID_ARGUMENT' if TARGET_THREAD is not a thread or FLAVOR
        !          4258:      is not recognized.  The function returns 'MIG_ARRAY_TOO_LARGE' if
        !          4259:      the returned info array is too large for THREAD_INFO.  In this
        !          4260:      case, THREAD_INFO is filled as much as possible and THREAD_INFOCNT
        !          4261:      is set to the number of elements that would have been returned if
        !          4262:      there were enough room.
        !          4263: 
        !          4264:  -- Data type: struct thread_basic_info
        !          4265:      This structure is returned in THREAD_INFO by the 'thread_info'
        !          4266:      function and provides basic information about the thread.  You can
        !          4267:      cast a variable of type 'thread_info_t' to a pointer of this type
        !          4268:      if you provided it as the THREAD_INFO parameter for the
        !          4269:      'THREAD_BASIC_INFO' flavor of 'thread_info'.  It has the following
        !          4270:      members:
        !          4271: 
        !          4272:      'time_value_t user_time'
        !          4273:           user run time
        !          4274: 
        !          4275:      'time_value_t system_time'
        !          4276:           system run time
        !          4277:      'int cpu_usage'
        !          4278:           Scaled cpu usage percentage.  The scale factor is
        !          4279:           'TH_USAGE_SCALE'.
        !          4280: 
        !          4281:      'int base_priority'
        !          4282:           The base scheduling priority of the thread.
        !          4283: 
        !          4284:      'int cur_priority'
        !          4285:           The current scheduling priority of the thread.
        !          4286: 
        !          4287:      'integer_t run_state'
        !          4288:           The run state of the thread.  The possible values of this
        !          4289:           field are:
        !          4290:           'TH_STATE_RUNNING'
        !          4291:                The thread is running normally.
        !          4292: 
        !          4293:           'TH_STATE_STOPPED'
        !          4294:                The thread is suspended.
        !          4295: 
        !          4296:           'TH_STATE_WAITING'
        !          4297:                The thread is waiting normally.
        !          4298: 
        !          4299:           'TH_STATE_UNINTERRUPTIBLE'
        !          4300:                The thread is in an uninterruptible wait.
        !          4301: 
        !          4302:           'TH_STATE_HALTED'
        !          4303:                The thread is halted at a clean point.
        !          4304: 
        !          4305:      'flags'
        !          4306:           Various flags.  The possible values of this field are:
        !          4307:           'TH_FLAGS_SWAPPED'
        !          4308:                The thread is swapped out.
        !          4309: 
        !          4310:           'TH_FLAGS_IDLE'
        !          4311:                The thread is an idle thread.
        !          4312: 
        !          4313:      'int suspend_count'
        !          4314:           The suspend count for the thread.
        !          4315: 
        !          4316:      'int sleep_time'
        !          4317:           The number of seconds that the thread has been sleeping.
        !          4318: 
        !          4319:      'time_value_t creation_time'
        !          4320:           The time stamp of creation.
        !          4321: 
        !          4322:  -- Data type: thread_basic_info_t
        !          4323:      This is a pointer to a 'struct thread_basic_info'.
        !          4324: 
        !          4325:  -- Data type: struct thread_sched_info
        !          4326:      This structure is returned in THREAD_INFO by the 'thread_info'
        !          4327:      function and provides schedule information about the thread.  You
        !          4328:      can cast a variable of type 'thread_info_t' to a pointer of this
        !          4329:      type if you provided it as the THREAD_INFO parameter for the
        !          4330:      'THREAD_SCHED_INFO' flavor of 'thread_info'.  It has the following
        !          4331:      members:
        !          4332: 
        !          4333:      'int policy'
        !          4334:           The scheduling policy of the thread, *note Scheduling
        !          4335:           Policy::.
        !          4336: 
        !          4337:      'integer_t data'
        !          4338:           Policy-dependent scheduling information, *note Scheduling
        !          4339:           Policy::.
        !          4340: 
        !          4341:      'int base_priority'
        !          4342:           The base scheduling priority of the thread.
        !          4343: 
        !          4344:      'int max_priority'
        !          4345:           The maximum scheduling priority of the thread.
        !          4346: 
        !          4347:      'int cur_priority'
        !          4348:           The current scheduling priority of the thread.
        !          4349: 
        !          4350:      'int depressed'
        !          4351:           'TRUE' if the thread is depressed.
        !          4352: 
        !          4353:      'int depress_priority'
        !          4354:           The priority the thread was depressed from.
        !          4355: 
        !          4356:  -- Data type: thread_sched_info_t
        !          4357:      This is a pointer to a 'struct thread_sched_info'.
        !          4358: 
        !          4359: 
        !          4360: File: mach.info,  Node: Thread Settings,  Next: Thread Execution,  Prev: Thread Information,  Up: Thread Interface
        !          4361: 
        !          4362: 7.1.4 Thread Settings
        !          4363: ---------------------
        !          4364: 
        !          4365:  -- Function: kern_return_t thread_wire (host_priv_t HOST_PRIV,
        !          4366:           thread_t THREAD, boolean_t WIRED)
        !          4367:      The function 'thread_wire' controls the VM privilege level of the
        !          4368:      thread THREAD.  A VM-privileged thread never waits inside the
        !          4369:      kernel for memory allocation from the kernel's free list of pages
        !          4370:      or for allocation of a kernel stack.
        !          4371: 
        !          4372:      Threads that are part of the default pageout path should be
        !          4373:      VM-privileged, to prevent system deadlocks.  Threads that are not
        !          4374:      part of the default pageout path should not be VM-privileged, to
        !          4375:      prevent the kernel's free list of pages from being exhausted.
        !          4376: 
        !          4377:      The functions returns 'KERN_SUCCESS' if the call succeeded,
        !          4378:      'KERN_INVALID_ARGUMENT' if HOST_PRIV or THREAD was invalid.
        !          4379: 
        !          4380:      The 'thread_wire' call is actually an RPC to HOST_PRIV, normally a
        !          4381:      send right for a privileged host port, but potentially any send
        !          4382:      right.  In addition to the normal diagnostic return codes from the
        !          4383:      call's server (normally the kernel), the call may return 'mach_msg'
        !          4384:      return codes.
        !          4385: 
        !          4386: 
        !          4387: File: mach.info,  Node: Thread Execution,  Next: Scheduling,  Prev: Thread Settings,  Up: Thread Interface
        !          4388: 
        !          4389: 7.1.5 Thread Execution
        !          4390: ----------------------
        !          4391: 
        !          4392:  -- Function: kern_return_t thread_suspend (thread_t TARGET_THREAD)
        !          4393:      Increments the thread's suspend count and prevents the thread from
        !          4394:      executing any more user level instructions.  In this context a user
        !          4395:      level instruction is either a machine instruction executed in user
        !          4396:      mode or a system trap instruction including page faults.  Thus if a
        !          4397:      thread is currently executing within a system trap the kernel code
        !          4398:      may continue to execute until it reaches the system return code or
        !          4399:      it may suspend within the kernel code.  In either case, when the
        !          4400:      thread is resumed the system trap will return.  This could cause
        !          4401:      unpredictable results if the user did a suspend and then altered
        !          4402:      the user state of the thread in order to change its direction upon
        !          4403:      a resume.  The call 'thread_abort' is provided to allow the user to
        !          4404:      abort any system call that is in progress in a predictable way.
        !          4405: 
        !          4406:      The suspend count may become greater than one with the effect that
        !          4407:      it will take more than one resume call to restart the thread.
        !          4408: 
        !          4409:      The function returns 'KERN_SUCCESS' if the thread has been
        !          4410:      suspended and 'KERN_INVALID_ARGUMENT' if TARGET_THREAD is not a
        !          4411:      thread.
        !          4412: 
        !          4413:  -- Function: kern_return_t thread_resume (thread_t TARGET_THREAD)
        !          4414:      Decrements the thread's suspend count.  If the count becomes zero
        !          4415:      the thread is resumed.  If it is still positive, the thread is left
        !          4416:      suspended.  The suspend count may not become negative.
        !          4417: 
        !          4418:      The function returns 'KERN_SUCCESS' if the thread has been resumed,
        !          4419:      'KERN_FAILURE' if the suspend count is already zero and
        !          4420:      'KERN_INVALID_ARGUMENT' if TARGET_THREAD is not a thread.
        !          4421: 
        !          4422:  -- Function: kern_return_t thread_abort (thread_t TARGET_THREAD)
        !          4423:      The function 'thread_abort' aborts the kernel primitives:
        !          4424:      'mach_msg', 'msg_send', 'msg_receive' and 'msg_rpc' and
        !          4425:      page-faults, making the call return a code indicating that it was
        !          4426:      interrupted.  The call is interrupted whether or not the thread (or
        !          4427:      task containing it) is currently suspended.  If it is suspended,
        !          4428:      the thread receives the interrupt when it is resumed.
        !          4429: 
        !          4430:      A thread will retry an aborted page-fault if its state is not
        !          4431:      modified before it is resumed.  'msg_send' returns
        !          4432:      'SEND_INTERRUPTED'; 'msg_receive' returns 'RCV_INTERRUPTED';
        !          4433:      'msg_rpc' returns either 'SEND_INTERRUPTED' or 'RCV_INTERRUPTED',
        !          4434:      depending on which half of the RPC was interrupted.
        !          4435: 
        !          4436:      The main reason for this primitive is to allow one thread to
        !          4437:      cleanly stop another thread in a manner that will allow the future
        !          4438:      execution of the target thread to be controlled in a predictable
        !          4439:      way.  'thread_suspend' keeps the target thread from executing any
        !          4440:      further instructions at the user level, including the return from a
        !          4441:      system call.  'thread_get_state'/'thread_set_state' allows the
        !          4442:      examination or modification of the user state of a target thread.
        !          4443:      However, if a suspended thread was executing within a system call,
        !          4444:      it also has associated with it a kernel state.  This kernel state
        !          4445:      can not be modified by 'thread_set_state' with the result that when
        !          4446:      the thread is resumed the system call may return changing the user
        !          4447:      state and possibly user memory.  'thread_abort' aborts the kernel
        !          4448:      call from the target thread's point of view by resetting the kernel
        !          4449:      state so that the thread will resume execution at the system call
        !          4450:      return with the return code value set to one of the interrupted
        !          4451:      codes.  The system call itself will either be entirely completed or
        !          4452:      entirely aborted, depending on the precise moment at which the
        !          4453:      abort was received.  Thus if the thread's user state has been
        !          4454:      changed by 'thread_set_state', it will not be modified by any
        !          4455:      unexpected system call side effects.
        !          4456: 
        !          4457:      For example to simulate a Unix signal, the following sequence of
        !          4458:      calls may be used:
        !          4459: 
        !          4460:        1. 'thread_suspend': Stops the thread.
        !          4461: 
        !          4462:        2. 'thread_abort': Interrupts any system call in progress,
        !          4463:           setting the return value to 'interrupted'.  Since the thread
        !          4464:           is stopped, it will not return to user code.
        !          4465: 
        !          4466:        3. 'thread_set_state': Alters thread's state to simulate a
        !          4467:           procedure call to the signal handler
        !          4468: 
        !          4469:        4. 'thread_resume': Resumes execution at the signal handler.  If
        !          4470:           the thread's stack has been correctly set up, the thread may
        !          4471:           return to the interrupted system call.  (Of course, the code
        !          4472:           to push an extra stack frame and change the registers is VERY
        !          4473:           machine-dependent.)
        !          4474: 
        !          4475:      Calling 'thread_abort' on a non-suspended thread is pretty risky,
        !          4476:      since it is very difficult to know exactly what system trap, if
        !          4477:      any, the thread might be executing and whether an interrupt return
        !          4478:      would cause the thread to do something useful.
        !          4479: 
        !          4480:      The function returns 'KERN_SUCCESS' if the thread received an
        !          4481:      interrupt and 'KERN_INVALID_ARGUMENT' if TARGET_THREAD is not a
        !          4482:      thread.
        !          4483: 
        !          4484:  -- Function: kern_return_t thread_get_state (thread_t TARGET_THREAD,
        !          4485:           int FLAVOR, thread_state_t OLD_STATE,
        !          4486:           mach_msg_type_number_t *OLD_STATECNT)
        !          4487:      The function 'thread_get_state' returns the execution state (e.g.
        !          4488:      the machine registers) of TARGET_THREAD as specified by FLAVOR.
        !          4489:      The OLD_STATE is an array of integers that is provided by the
        !          4490:      caller and returned filled with the specified information.
        !          4491:      OLD_STATECNT is input set to the maximum number of integers in
        !          4492:      OLD_STATE and returned equal to the actual number of integers in
        !          4493:      OLD_STATE.
        !          4494: 
        !          4495:      TARGET_THREAD may not be 'mach_thread_self()'.
        !          4496: 
        !          4497:      The definition of the state structures can be found in
        !          4498:      'machine/thread_status.h'.
        !          4499: 
        !          4500:      The function returns 'KERN_SUCCESS' if the state has been returned,
        !          4501:      'KERN_INVALID_ARGUMENT' if TARGET_THREAD is not a thread or is
        !          4502:      'mach_thread_self' or FLAVOR is unrecognized for this machine.  The
        !          4503:      function returns 'MIG_ARRAY_TOO_LARGE' if the returned state is too
        !          4504:      large for OLD_STATE.  In this case, OLD_STATE is filled as much as
        !          4505:      possible and OLD_STATECNT is set to the number of elements that
        !          4506:      would have been returned if there were enough room.
        !          4507: 
        !          4508:  -- Function: kern_return_t thread_set_state (thread_t TARGET_THREAD,
        !          4509:           int FLAVOR, thread_state_t NEW_STATE,
        !          4510:           mach_msg_type_number_t NEW_STATE_COUNT)
        !          4511:      The function 'thread_set_state' sets the execution state (e.g.  the
        !          4512:      machine registers) of TARGET_THREAD as specified by FLAVOR.  The
        !          4513:      NEW_STATE is an array of integers.  NEW_STATE_COUNT is the number
        !          4514:      of elements in NEW_STATE.  The entire set of registers is reset.
        !          4515:      This will do unpredictable things if TARGET_THREAD is not
        !          4516:      suspended.
        !          4517: 
        !          4518:      TARGET_THREAD may not be 'mach_thread_self'.
        !          4519: 
        !          4520:      The definition of the state structures can be found in
        !          4521:      'machine/thread_status.h'.
        !          4522: 
        !          4523:      The function returns 'KERN_SUCCESS' if the state has been set and
        !          4524:      'KERN_INVALID_ARGUMENT' if TARGET_THREAD is not a thread or is
        !          4525:      'mach_thread_self' or FLAVOR is unrecognized for this machine.
        !          4526: 
        !          4527: 
        !          4528: File: mach.info,  Node: Scheduling,  Next: Thread Special Ports,  Prev: Thread Execution,  Up: Thread Interface
        !          4529: 
        !          4530: 7.1.6 Scheduling
        !          4531: ----------------
        !          4532: 
        !          4533: * Menu:
        !          4534: 
        !          4535: * Thread Priority::               Changing the priority of a thread.
        !          4536: * Hand-Off Scheduling::           Switching to a new thread.
        !          4537: * Scheduling Policy::             Setting the scheduling policy.
        !          4538: 
        !          4539: 
        !          4540: File: mach.info,  Node: Thread Priority,  Next: Hand-Off Scheduling,  Up: Scheduling
        !          4541: 
        !          4542: 7.1.6.1 Thread Priority
        !          4543: .......................
        !          4544: 
        !          4545: Threads have three priorities associated with them by the system, a
        !          4546: priority, a maximum priority, and a scheduled priority.  The scheduled
        !          4547: priority is used to make scheduling decisions about the thread.  It is
        !          4548: determined from the priority by the policy (for timesharing, this means
        !          4549: adding an increment derived from cpu usage).  The priority can be set
        !          4550: under user control, but may never exceed the maximum priority.  Changing
        !          4551: the maximum priority requires presentation of the control port for the
        !          4552: thread's processor set; since the control port for the default processor
        !          4553: set is privileged, users cannot raise their maximum priority to unfairly
        !          4554: compete with other users on that set.  Newly created threads obtain
        !          4555: their priority from their task and their max priority from the thread.
        !          4556: 
        !          4557:  -- Function: kern_return_t thread_priority (thread_t THREAD,
        !          4558:           int PRORITY, boolean_t SET_MAX)
        !          4559:      The function 'thread_priority' changes the priority and optionally
        !          4560:      the maximum priority of THREAD.  Priorities range from 0 to 31,
        !          4561:      where lower numbers denote higher priorities.  If the new priority
        !          4562:      is higher than the priority of the current thread, preemption may
        !          4563:      occur as a result of this call.  The maximum priority of the thread
        !          4564:      is also set if SET_MAX is 'TRUE'.  This call will fail if PRIORITY
        !          4565:      is greater than the current maximum priority of the thread.  As a
        !          4566:      result, this call can only lower the value of a thread's maximum
        !          4567:      priority.
        !          4568: 
        !          4569:      The functions returns 'KERN_SUCCESS' if the operation completed
        !          4570:      successfully, 'KERN_INVALID_ARGUMENT' if THREAD is not a thread or
        !          4571:      PRIORITY is out of range (not in 0..31), and 'KERN_FAILURE' if the
        !          4572:      requested operation would violate the thread's maximum priority
        !          4573:      (thread_priority).
        !          4574: 
        !          4575:  -- Function: kern_return_t thread_max_priority (thread_t THREAD,
        !          4576:           processor_set_t PROCESSOR_SET, int PRIORITY)
        !          4577:      The function 'thread_max_priority' changes the maximum priority of
        !          4578:      the thread.  Because it requires presentation of the corresponding
        !          4579:      processor set port, this call can reset the maximum priority to any
        !          4580:      legal value.
        !          4581: 
        !          4582:      The functions returns 'KERN_SUCCESS' if the operation completed
        !          4583:      successfully, 'KERN_INVALID_ARGUMENT' if THREAD is not a thread or
        !          4584:      PROCESSOR_SET is not a control port for a processor set or PRIORITY
        !          4585:      is out of range (not in 0..31), and 'KERN_FAILURE' if the thread is
        !          4586:      not assigned to the processor set whose control port was presented.
        !          4587: 
        !          4588: 
        !          4589: File: mach.info,  Node: Hand-Off Scheduling,  Next: Scheduling Policy,  Prev: Thread Priority,  Up: Scheduling
        !          4590: 
        !          4591: 7.1.6.2 Hand-Off Scheduling
        !          4592: ...........................
        !          4593: 
        !          4594:  -- Function: kern_return_t thread_switch (thread_t NEW_THREAD,
        !          4595:           int OPTION, int TIME)
        !          4596:      The function 'thread_switch' provides low-level access to the
        !          4597:      scheduler's context switching code.  NEW_THREAD is a hint that
        !          4598:      implements hand-off scheduling.  The operating system will attempt
        !          4599:      to switch directly to the new thread (bypassing the normal logic
        !          4600:      that selects the next thread to run) if possible.  Since this is a
        !          4601:      hint, it may be incorrect; it is ignored if it doesn't specify a
        !          4602:      thread on the same host as the current thread or if that thread
        !          4603:      can't be switched to (i.e., not runnable or already running on
        !          4604:      another processor or giving a plainly invalid hint, such as
        !          4605:      'MACH_PORT_NULL').  In this case, the normal logic to select the
        !          4606:      next thread to run is used; the current thread may continue running
        !          4607:      if there is no other appropriate thread to run.
        !          4608: 
        !          4609:      Options for OPTION are defined in 'mach/thread_switch.h' and
        !          4610:      specify the interpretation of TIME.  The possible values for OPTION
        !          4611:      are:
        !          4612: 
        !          4613:      'SWITCH_OPTION_NONE'
        !          4614:           No options, the time argument is ignored.
        !          4615: 
        !          4616:      'SWITCH_OPTION_WAIT'
        !          4617:           The thread is blocked for the specified time (in milliseconds;
        !          4618:           specifying '0' will wait for the next tick).  This can be
        !          4619:           aborted by 'thread_abort'.
        !          4620: 
        !          4621:      'SWITCH_OPTION_DEPRESS'
        !          4622:           The thread's priority is depressed to the lowest possible
        !          4623:           value for the specified time.  This can be aborted by
        !          4624:           'thread_depress_abort'.  This depression is independent of
        !          4625:           operations that change the thread's priority (e.g.
        !          4626:           'thread_priority' will not abort the depression).  The minimum
        !          4627:           time and units of time can be obtained as the 'min_timeout'
        !          4628:           value from 'host_info'.  The depression is also aborted when
        !          4629:           the current thread is next run (either via hand-off scheduling
        !          4630:           or because the processor set has nothing better to do).
        !          4631: 
        !          4632:      'thread_switch' is often called when the current thread can proceed
        !          4633:      no further for some reason; the various options and arguments allow
        !          4634:      information about this reason to be transmitted to the kernel.  The
        !          4635:      NEW_THREAD argument (handoff scheduling) is useful when the
        !          4636:      identity of the thread that must make progress before the current
        !          4637:      thread runs again is known.  The 'WAIT' option is used when the
        !          4638:      amount of time that the current thread must wait before it can do
        !          4639:      anything useful can be estimated and is fairly long.  The 'DEPRESS'
        !          4640:      option is used when the amount of time that must be waited is
        !          4641:      fairly short, especially when the identity of the thread that is
        !          4642:      being waited for is not known.
        !          4643: 
        !          4644:      Users should beware of calling 'thread_switch' with an invalid hint
        !          4645:      (e.g.  'MACH_PORT_NULL') and no option.  Because the time-sharing
        !          4646:      scheduler varies the priority of threads based on usage, this may
        !          4647:      result in a waste of cpu time if the thread that must be run is of
        !          4648:      lower priority.  The use of the 'DEPRESS' option in this situation
        !          4649:      is highly recommended.
        !          4650: 
        !          4651:      'thread_switch' ignores policies.  Users relying on the preemption
        !          4652:      semantics of a fixed time policy should be aware that
        !          4653:      'thread_switch' ignores these semantics; it will run the specified
        !          4654:      NEW_THREAD independent of its priority and the priority of any
        !          4655:      other threads that could be run instead.
        !          4656: 
        !          4657:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          4658:      'KERN_INVALID_ARGUMENT' if THREAD is not a thread or OPTION is not
        !          4659:      a recognized option, and 'KERN_FAILURE' if 'kern_depress_abort'
        !          4660:      failed because the thread was not depressed.
        !          4661: 
        !          4662:  -- Function: kern_return_t thread_depress_abort (thread_t THREAD)
        !          4663:      The function 'thread_depress_abort' cancels any priority depression
        !          4664:      for THREAD caused by a 'swtch_pri' or 'thread_switch' call.
        !          4665: 
        !          4666:      The function returns 'KERN_SUCCESS' if the call succeeded and
        !          4667:      'KERN_INVALID_ARGUMENT' if THREAD is not a valid thread.
        !          4668: 
        !          4669:  -- Function: boolean_t swtch ()
        !          4670:      The system trap 'swtch' attempts to switch the current thread off
        !          4671:      the processor.  The return value indicates if more than the current
        !          4672:      thread is running in the processor set.  This is useful for lock
        !          4673:      management routines.
        !          4674: 
        !          4675:      The call returns 'FALSE' if the thread is justified in becoming a
        !          4676:      resource hog by continuing to spin because there's nothing else
        !          4677:      useful that the processor could do.  'TRUE' is returned if the
        !          4678:      thread should make one more check on the lock and then be a good
        !          4679:      citizen and really suspend.
        !          4680: 
        !          4681:  -- Function: boolean_t swtch_pri (int PRIORITY)
        !          4682:      The system trap 'swtch_pri' attempts to switch the current thread
        !          4683:      off the processor as 'swtch' does, but depressing the priority of
        !          4684:      the thread to the minimum possible value during the time.  PRIORITY
        !          4685:      is not used currently.
        !          4686: 
        !          4687:      The return value is as for 'swtch'.
        !          4688: 
        !          4689: 
        !          4690: File: mach.info,  Node: Scheduling Policy,  Prev: Hand-Off Scheduling,  Up: Scheduling
        !          4691: 
        !          4692: 7.1.6.3 Scheduling Policy
        !          4693: .........................
        !          4694: 
        !          4695:  -- Function: kern_return_t thread_policy (thread_t THREAD, int POLICY,
        !          4696:           int DATA)
        !          4697:      The function 'thread_policy' changes the scheduling policy for
        !          4698:      THREAD to POLICY.
        !          4699: 
        !          4700:      DATA is policy-dependent scheduling information.  There are
        !          4701:      currently two supported policies: 'POLICY_TIMESHARE' and
        !          4702:      'POLICY_FIXEDPRI' defined in 'mach/policy.h'; this file is included
        !          4703:      by 'mach.h'.  DATA is meaningless for timesharing, but is the
        !          4704:      quantum to be used (in milliseconds) for the fixed priority policy.
        !          4705:      To be meaningful, this quantum must be a multiple of the basic
        !          4706:      system quantum (min_quantum) which can be obtained from
        !          4707:      'host_info'.  The system will always round up to the next multiple
        !          4708:      of the quantum.
        !          4709: 
        !          4710:      Processor sets may restrict the allowed policies, so this call will
        !          4711:      fail if the processor set to which THREAD is currently assigned
        !          4712:      does not permit POLICY.
        !          4713: 
        !          4714:      The function returns 'KERN_SUCCESS' if the call succeeded.
        !          4715:      'KERN_INVALID_ARGUMENT' if THREAD is not a thread or POLICY is not
        !          4716:      a recognized policy, and 'KERN_FAILURE' if the processor set to
        !          4717:      which THREAD is currently assigned does not permit POLICY.
        !          4718: 
        !          4719: 
        !          4720: File: mach.info,  Node: Thread Special Ports,  Next: Exceptions,  Prev: Scheduling,  Up: Thread Interface
        !          4721: 
        !          4722: 7.1.7 Thread Special Ports
        !          4723: --------------------------
        !          4724: 
        !          4725:  -- Function: kern_return_t thread_get_special_port (thread_t THREAD,
        !          4726:           int WHICH_PORT, mach_port_t *SPECIAL_PORT)
        !          4727:      The function 'thread_get_special_port' returns send rights to one
        !          4728:      of a set of special ports for the thread specified by THREAD.
        !          4729: 
        !          4730:      The possible values for WHICH_PORT are 'THREAD_KERNEL_PORT' and
        !          4731:      'THREAD_EXCEPTION_PORT'.  A thread also has access to its task's
        !          4732:      special ports.
        !          4733: 
        !          4734:      The function returns 'KERN_SUCCESS' if the port was returned and
        !          4735:      'KERN_INVALID_ARGUMENT' if THREAD is not a thread or WHICH_PORT is
        !          4736:      an invalid port selector.
        !          4737: 
        !          4738:  -- Function: kern_return_t thread_get_kernel_port (thread_t THREAD,
        !          4739:           mach_port_t *KERNEL_PORT)
        !          4740:      The function 'thread_get_kernel_port' is equivalent to the function
        !          4741:      'thread_get_special_port' with the WHICH_PORT argument set to
        !          4742:      'THREAD_KERNEL_PORT'.
        !          4743: 
        !          4744:  -- Function: kern_return_t thread_get_exception_port (thread_t THREAD,
        !          4745:           mach_port_t *EXCEPTION_PORT)
        !          4746:      The function 'thread_get_exception_port' is equivalent to the
        !          4747:      function 'thread_get_special_port' with the WHICH_PORT argument set
        !          4748:      to 'THREAD_EXCEPTION_PORT'.
        !          4749: 
        !          4750:  -- Function: kern_return_t thread_set_special_port (thread_t THREAD,
        !          4751:           int WHICH_PORT, mach_port_t SPECIAL_PORT)
        !          4752:      The function 'thread_set_special_port' sets one of a set of special
        !          4753:      ports for the thread specified by THREAD.
        !          4754: 
        !          4755:      The possible values for WHICH_PORT are 'THREAD_KERNEL_PORT' and
        !          4756:      'THREAD_EXCEPTION_PORT'.  A thread also has access to its task's
        !          4757:      special ports.
        !          4758: 
        !          4759:      The function returns 'KERN_SUCCESS' if the port was set and
        !          4760:      'KERN_INVALID_ARGUMENT' if THREAD is not a thread or WHICH_PORT is
        !          4761:      an invalid port selector.
        !          4762: 
        !          4763:  -- Function: kern_return_t thread_set_kernel_port (thread_t THREAD,
        !          4764:           mach_port_t KERNEL_PORT)
        !          4765:      The function 'thread_set_kernel_port' is equivalent to the function
        !          4766:      'thread_set_special_port' with the WHICH_PORT argument set to
        !          4767:      'THREAD_KERNEL_PORT'.
        !          4768: 
        !          4769:  -- Function: kern_return_t thread_set_exception_port (thread_t THREAD,
        !          4770:           mach_port_t EXCEPTION_PORT)
        !          4771:      The function 'thread_set_exception_port' is equivalent to the
        !          4772:      function 'thread_set_special_port' with the WHICH_PORT argument set
        !          4773:      to 'THREAD_EXCEPTION_PORT'.
        !          4774: 
        !          4775: 
        !          4776: File: mach.info,  Node: Exceptions,  Prev: Thread Special Ports,  Up: Thread Interface
        !          4777: 
        !          4778: 7.1.8 Exceptions
        !          4779: ----------------
        !          4780: 
        !          4781:  -- Function: kern_return_t catch_exception_raise
        !          4782:           (mach_port_t EXCEPTION_PORT, thread_t THREAD, task_t TASK,
        !          4783:           int EXCEPTION, int CODE, int SUBCODE)
        !          4784:      XXX Fixme
        !          4785: 
        !          4786:  -- Function: kern_return_t exception_raise (mach_port_t EXCEPTION_PORT,
        !          4787:           mach_port_t THREAD, mach_port_t TASK, integer_t EXCEPTION,
        !          4788:           integer_t CODE, integer_t SUBCODE)
        !          4789:      XXX Fixme
        !          4790: 
        !          4791:  -- Function: kern_return_t evc_wait (unsigned int EVENT)
        !          4792:      The system trap 'evc_wait' makes the calling thread wait for the
        !          4793:      event specified by EVENT.
        !          4794: 
        !          4795:      The call returns 'KERN_SUCCESS' if the event has occurred,
        !          4796:      'KERN_NO_SPACE' if another thread is waiting for the same event and
        !          4797:      'KERN_INVALID_ARGUMENT' if the event object is invalid.
        !          4798: 
        !          4799: 
        !          4800: File: mach.info,  Node: Task Interface,  Next: Profiling,  Prev: Thread Interface,  Up: Threads and Tasks
        !          4801: 
        !          4802: 7.2 Task Interface
        !          4803: ==================
        !          4804: 
        !          4805:  -- Data type: task_t
        !          4806:      This is a 'mach_port_t' and used to hold the port name of a task
        !          4807:      port that represents the thread.  Manipulations of the task are
        !          4808:      implemented as remote procedure calls to the task port.  A task can
        !          4809:      get a port to itself with the 'mach_task_self' system call.
        !          4810: 
        !          4811:      The task port name is also used to identify the task's IPC space
        !          4812:      (*note Port Manipulation Interface::) and the task's virtual memory
        !          4813:      map (*note Virtual Memory Interface::).
        !          4814: 
        !          4815: * Menu:
        !          4816: 
        !          4817: * Task Creation::                 Creating tasks.
        !          4818: * Task Termination::              Terminating tasks.
        !          4819: * Task Information::              Informations on tasks.
        !          4820: * Task Execution::                Thread scheduling in a task.
        !          4821: * Task Special Ports::            How to get and set the task's special ports.
        !          4822: * Syscall Emulation::             How to emulate system calls.
        !          4823: 
        !          4824: 
        !          4825: File: mach.info,  Node: Task Creation,  Next: Task Termination,  Up: Task Interface
        !          4826: 
        !          4827: 7.2.1 Task Creation
        !          4828: -------------------
        !          4829: 
        !          4830:  -- Function: kern_return_t task_create (task_t PARENT_TASK,
        !          4831:           boolean_t INHERIT_MEMORY, task_t *CHILD_TASK)
        !          4832:      The function 'task_create' creates a new task from PARENT_TASK; the
        !          4833:      resulting task (CHILD_TASK) acquires shared or copied parts of the
        !          4834:      parent's address space (see 'vm_inherit').  The child task
        !          4835:      initially contains no threads.
        !          4836: 
        !          4837:      If INHERIT_MEMORY is set, the child task's address space is built
        !          4838:      from the parent task according to its memory inheritance values;
        !          4839:      otherwise, the child task is given an empty address space.
        !          4840: 
        !          4841:      The child task gets the three special ports created or copied for
        !          4842:      it at task creation.  The 'TASK_KERNEL_PORT' is created and send
        !          4843:      rights for it are given to the child and returned to the caller.
        !          4844:      The 'TASK_BOOTSTRAP_PORT' and the 'TASK_EXCEPTION_PORT' are
        !          4845:      inherited from the parent task.  The new task can get send rights
        !          4846:      to these ports with the call 'task_get_special_port'.
        !          4847: 
        !          4848:      The function returns 'KERN_SUCCESS' if a new task has been created,
        !          4849:      'KERN_INVALID_ARGUMENT' if PARENT_TASK is not a valid task port and
        !          4850:      'KERN_RESOURCE_SHORTAGE' if some critical kernel resource is
        !          4851:      unavailable.
        !          4852: 
        !          4853: 
        !          4854: File: mach.info,  Node: Task Termination,  Next: Task Information,  Prev: Task Creation,  Up: Task Interface
        !          4855: 
        !          4856: 7.2.2 Task Termination
        !          4857: ----------------------
        !          4858: 
        !          4859:  -- Function: kern_return_t task_terminate (task_t TARGET_TASK)
        !          4860:      The function 'task_terminate' destroys the task specified by
        !          4861:      TARGET_TASK and all its threads.  All resources that are used only
        !          4862:      by this task are freed.  Any port to which this task has receive
        !          4863:      and ownership rights is destroyed.
        !          4864: 
        !          4865:      The function returns 'KERN_SUCCESS' if the task has been killed,
        !          4866:      'KERN_INVALID_ARGUMENT' if TARGET_TASK is not a task.
        !          4867: 
        !          4868: 
        !          4869: File: mach.info,  Node: Task Information,  Next: Task Execution,  Prev: Task Termination,  Up: Task Interface
        !          4870: 
        !          4871: 7.2.3 Task Information
        !          4872: ----------------------
        !          4873: 
        !          4874:  -- Function: task_t mach_task_self ()
        !          4875:      The 'mach_task_self' system call returns the calling thread's task
        !          4876:      port.
        !          4877: 
        !          4878:      'mach_task_self' has an effect equivalent to receiving a send right
        !          4879:      for the task port.  'mach_task_self' returns the name of the send
        !          4880:      right.  In particular, successive calls will increase the calling
        !          4881:      task's user-reference count for the send right.
        !          4882: 
        !          4883:      As a special exception, the kernel will overrun the user reference
        !          4884:      count of the task name port, so that this function can not fail for
        !          4885:      that reason.  Because of this, the user should not deallocate the
        !          4886:      port right if an overrun might have happened.  Otherwise the
        !          4887:      reference count could drop to zero and the send right be destroyed
        !          4888:      while the user still expects to be able to use it.  As the kernel
        !          4889:      does not make use of the number of extant send rights anyway, this
        !          4890:      is safe to do (the task port itself is not destroyed, even when
        !          4891:      there are no send rights anymore).
        !          4892: 
        !          4893:      The function returns 'MACH_PORT_NULL' if a resource shortage
        !          4894:      prevented the reception of the send right, 'MACH_PORT_NULL' if the
        !          4895:      task port is currently null, 'MACH_PORT_DEAD' if the task port is
        !          4896:      currently dead.
        !          4897: 
        !          4898:  -- Function: kern_return_t task_threads (task_t TARGET_TASK,
        !          4899:           thread_array_t *THREAD_LIST,
        !          4900:           mach_msg_type_number_t *THREAD_COUNT)
        !          4901:      The function 'task_threads' gets send rights to the kernel port for
        !          4902:      each thread contained in TARGET_TASK.  THREAD_LIST is an array that
        !          4903:      is created as a result of this call.  The caller may wish to
        !          4904:      'vm_deallocate' this array when the data is no longer needed.
        !          4905: 
        !          4906:      The function returns 'KERN_SUCCESS' if the call succeeded and
        !          4907:      'KERN_INVALID_ARGUMENT' if TARGET_TASK is not a task.
        !          4908: 
        !          4909:  -- Function: kern_return_t task_info (task_t TARGET_TASK, int FLAVOR,
        !          4910:           task_info_t TASK_INFO,
        !          4911:           mach_msg_type_number_t *TASK_INFO_COUNT)
        !          4912:      The function 'task_info' returns the selected information array for
        !          4913:      a task, as specified by FLAVOR.  TASK_INFO is an array of integers
        !          4914:      that is supplied by the caller, and filled with specified
        !          4915:      information.  TASK_INFO_COUNT is supplied as the maximum number of
        !          4916:      integers in TASK_INFO.  On return, it contains the actual number of
        !          4917:      integers in TASK_INFO.  The maximum number of integers returned by
        !          4918:      any flavor is 'TASK_INFO_MAX'.
        !          4919: 
        !          4920:      The type of information returned is defined by FLAVOR, which can be
        !          4921:      one of the following:
        !          4922: 
        !          4923:      'TASK_BASIC_INFO'
        !          4924:           The function returns basic information about the task, as
        !          4925:           defined by 'task_basic_info_t'.  This includes the user and
        !          4926:           system time and memory consumption.  The number of integers
        !          4927:           returned is 'TASK_BASIC_INFO_COUNT'.
        !          4928: 
        !          4929:      'TASK_EVENTS_INFO'
        !          4930:           The function returns information about events for the task as
        !          4931:           defined by 'thread_sched_info_t'.  This includes statistics
        !          4932:           about virtual memory and IPC events like pageouts, pageins and
        !          4933:           messages sent and received.  The number of integers returned
        !          4934:           is 'TASK_EVENTS_INFO_COUNT'.
        !          4935: 
        !          4936:      'TASK_THREAD_TIMES_INFO'
        !          4937:           The function returns information about the total time for live
        !          4938:           threads as defined by 'task_thread_times_info_t'.  The number
        !          4939:           of integers returned is 'TASK_THREAD_TIMES_INFO_COUNT'.
        !          4940: 
        !          4941:      The function returns 'KERN_SUCCESS' if the call succeeded and
        !          4942:      'KERN_INVALID_ARGUMENT' if TARGET_TASK is not a thread or FLAVOR is
        !          4943:      not recognized.  The function returns 'MIG_ARRAY_TOO_LARGE' if the
        !          4944:      returned info array is too large for TASK_INFO.  In this case,
        !          4945:      TASK_INFO is filled as much as possible and TASK_INFOCNT is set to
        !          4946:      the number of elements that would have been returned if there were
        !          4947:      enough room.
        !          4948: 
        !          4949:  -- Data type: struct task_basic_info
        !          4950:      This structure is returned in TASK_INFO by the 'task_info' function
        !          4951:      and provides basic information about the task.  You can cast a
        !          4952:      variable of type 'task_info_t' to a pointer of this type if you
        !          4953:      provided it as the TASK_INFO parameter for the 'TASK_BASIC_INFO'
        !          4954:      flavor of 'task_info'.  It has the following members:
        !          4955: 
        !          4956:      'integer_t suspend_count'
        !          4957:           suspend count for task
        !          4958: 
        !          4959:      'integer_t base_priority'
        !          4960:           base scheduling priority
        !          4961: 
        !          4962:      'vm_size_t virtual_size'
        !          4963:           number of virtual pages
        !          4964: 
        !          4965:      'vm_size_t resident_size'
        !          4966:           number of resident pages
        !          4967: 
        !          4968:      'time_value_t user_time'
        !          4969:           total user run time for terminated threads
        !          4970: 
        !          4971:      'time_value_t system_time'
        !          4972:           total system run time for terminated threads
        !          4973: 
        !          4974:      'time_value_t creation_time'
        !          4975:           creation time stamp
        !          4976: 
        !          4977:  -- Data type: task_basic_info_t
        !          4978:      This is a pointer to a 'struct task_basic_info'.
        !          4979: 
        !          4980:  -- Data type: struct task_events_info
        !          4981:      This structure is returned in TASK_INFO by the 'task_info' function
        !          4982:      and provides event statistics for the task.  You can cast a
        !          4983:      variable of type 'task_info_t' to a pointer of this type if you
        !          4984:      provided it as the TASK_INFO parameter for the 'TASK_EVENTS_INFO'
        !          4985:      flavor of 'task_info'.  It has the following members:
        !          4986: 
        !          4987:      'natural_t faults'
        !          4988:           number of page faults
        !          4989: 
        !          4990:      'natural_t zero_fills'
        !          4991:           number of zero fill pages
        !          4992: 
        !          4993:      'natural_t reactivations'
        !          4994:           number of reactivated pages
        !          4995: 
        !          4996:      'natural_t pageins'
        !          4997:           number of actual pageins
        !          4998: 
        !          4999:      'natural_t cow_faults'
        !          5000:           number of copy-on-write faults
        !          5001: 
        !          5002:      'natural_t messages_sent'
        !          5003:           number of messages sent
        !          5004: 
        !          5005:      'natural_t messages_received'
        !          5006:           number of messages received
        !          5007: 
        !          5008:  -- Data type: task_events_info_t
        !          5009:      This is a pointer to a 'struct task_events_info'.
        !          5010: 
        !          5011:  -- Data type: struct task_thread_times_info
        !          5012:      This structure is returned in TASK_INFO by the 'task_info' function
        !          5013:      and provides event statistics for the task.  You can cast a
        !          5014:      variable of type 'task_info_t' to a pointer of this type if you
        !          5015:      provided it as the TASK_INFO parameter for the
        !          5016:      'TASK_THREAD_TIMES_INFO' flavor of 'task_info'.  It has the
        !          5017:      following members:
        !          5018: 
        !          5019:      'time_value_t user_time'
        !          5020:           total user run time for live threads
        !          5021: 
        !          5022:      'time_value_t system_time'
        !          5023:           total system run time for live threads
        !          5024: 
        !          5025:  -- Data type: task_thread_times_info_t
        !          5026:      This is a pointer to a 'struct task_thread_times_info'.
        !          5027: 
        !          5028: 
        !          5029: File: mach.info,  Node: Task Execution,  Next: Task Special Ports,  Prev: Task Information,  Up: Task Interface
        !          5030: 
        !          5031: 7.2.4 Task Execution
        !          5032: --------------------
        !          5033: 
        !          5034:  -- Function: kern_return_t task_suspend (task_t TARGET_TASK)
        !          5035:      The function 'task_suspend' increments the task's suspend count and
        !          5036:      stops all threads in the task.  As long as the suspend count is
        !          5037:      positive newly created threads will not run.  This call does not
        !          5038:      return until all threads are suspended.
        !          5039: 
        !          5040:      The count may become greater than one, with the effect that it will
        !          5041:      take more than one resume call to restart the task.
        !          5042: 
        !          5043:      The function returns 'KERN_SUCCESS' if the task has been suspended
        !          5044:      and 'KERN_INVALID_ARGUMENT' if TARGET_TASK is not a task.
        !          5045: 
        !          5046:  -- Function: kern_return_t task_resume (task_t TARGET_TASK)
        !          5047:      The function 'task_resume' decrements the task's suspend count.  If
        !          5048:      it becomes zero, all threads with zero suspend counts in the task
        !          5049:      are resumed.  The count may not become negative.
        !          5050: 
        !          5051:      The function returns 'KERN_SUCCESS' if the task has been resumed,
        !          5052:      'KERN_FAILURE' if the suspend count is already at zero and
        !          5053:      'KERN_INVALID_ARGUMENT' if TARGET_TASK is not a task.
        !          5054: 
        !          5055:  -- Function: kern_return_t task_priority (task_t TASK, int PRIORITY,
        !          5056:           boolean_t CHANGE_THREADS)
        !          5057:      The priority of a task is used only for creation of new threads; a
        !          5058:      new thread's priority is set to the enclosing task's priority.
        !          5059:      'task_priority' changes this task priority.  It also sets the
        !          5060:      priorities of all threads in the task to this new priority if
        !          5061:      CHANGE_THREADS is 'TRUE'.  Existing threads are not affected
        !          5062:      otherwise.  If this priority change violates the maximum priority
        !          5063:      of some threads, as many threads as possible will be changed and an
        !          5064:      error code will be returned.
        !          5065: 
        !          5066:      The function returns 'KERN_SUCCESS' if the call succeeded,
        !          5067:      'KERN_INVALID_ARGUMENT' if TASK is not a task, or PRIORITY is not a
        !          5068:      valid priority and 'KERN_FAILURE' if CHANGE_THREADS was 'TRUE' and
        !          5069:      the attempt to change the priority of at least one existing thread
        !          5070:      failed because the new priority would have exceeded that thread's
        !          5071:      maximum priority.
        !          5072: 
        !          5073:  -- Function: kern_return_t task_ras_control (task_t TARGET_TASK,
        !          5074:           vm_address_t START_PC, vm_address_t END_PC, int FLAVOR)
        !          5075:      The function 'task_ras_control' manipulates a task's set of
        !          5076:      restartable atomic sequences.  If a sequence is installed, and any
        !          5077:      thread in the task is preempted within the range [START_PC,END_PC],
        !          5078:      then the thread is resumed at START_PC.  This enables applications
        !          5079:      to build atomic sequences which, when executed to completion, will
        !          5080:      have executed atomically.  Restartable atomic sequences are
        !          5081:      intended to be used on systems that do not have hardware support
        !          5082:      for low-overhead atomic primitives.
        !          5083: 
        !          5084:      As a thread can be rolled-back, the code in the sequence should
        !          5085:      have no side effects other than a final store at END_PC.  The
        !          5086:      kernel does not guarantee that the sequence is restartable.  It
        !          5087:      assumes the application knows what it's doing.
        !          5088: 
        !          5089:      A task may have a finite number of atomic sequences that is defined
        !          5090:      at compile time.
        !          5091: 
        !          5092:      The flavor specifies the particular operation that should be
        !          5093:      applied to this restartable atomic sequence.  Possible values for
        !          5094:      flavor can be:
        !          5095: 
        !          5096:      'TASK_RAS_CONTROL_PURGE_ALL'
        !          5097:           Remove all registered sequences for this task.
        !          5098: 
        !          5099:      'TASK_RAS_CONTROL_PURGE_ONE'
        !          5100:           Remove the named registered sequence for this task.
        !          5101: 
        !          5102:      'TASK_RAS_CONTROL_PURGE_ALL_AND_INSTALL_ONE'
        !          5103:           Atomically remove all registered sequences and install the
        !          5104:           named sequence.
        !          5105: 
        !          5106:      'TASK_RAS_CONTROL_INSTALL_ONE'
        !          5107:           Install this sequence.
        !          5108: 
        !          5109:      The function returns 'KERN_SUCCESS' if the operation has been
        !          5110:      performed, 'KERN_INVALID_ADDRESS' if the START_PC or END_PC values
        !          5111:      are not a valid address for the requested operation (for example,
        !          5112:      it is invalid to purge a sequence that has not been registered),
        !          5113:      'KERN_RESOURCE_SHORTAGE' if an attempt was made to install more
        !          5114:      restartable atomic sequences for a task than can be supported by
        !          5115:      the kernel, 'KERN_INVALID_VALUE' if a bad flavor was specified,
        !          5116:      'KERN_INVALID_ARGUMENT' if TARGET_TASK is not a task and
        !          5117:      'KERN_FAILURE' if the call is not not supported on this
        !          5118:      configuration.
        !          5119: 
        !          5120: 
        !          5121: File: mach.info,  Node: Task Special Ports,  Next: Syscall Emulation,  Prev: Task Execution,  Up: Task Interface
        !          5122: 
        !          5123: 7.2.5 Task Special Ports
        !          5124: ------------------------
        !          5125: 
        !          5126:  -- Function: kern_return_t task_get_special_port (task_t TASK,
        !          5127:           int WHICH_PORT, mach_port_t *SPECIAL_PORT)
        !          5128:      The function 'task_get_special_port' returns send rights to one of
        !          5129:      a set of special ports for the task specified by TASK.
        !          5130: 
        !          5131:      The special ports associated with a task are the kernel port
        !          5132:      ('TASK_KERNEL_PORT'), the bootstrap port ('TASK_BOOTSTRAP_PORT')
        !          5133:      and the exception port ('TASK_EXCEPTION_PORT').  The bootstrap port
        !          5134:      is a port to which a task may send a message requesting other
        !          5135:      system service ports.  This port is not used by the kernel.  The
        !          5136:      task's exception port is the port to which messages are sent by the
        !          5137:      kernel when an exception occurs and the thread causing the
        !          5138:      exception has no exception port of its own.
        !          5139: 
        !          5140:      The following macros to call 'task_get_special_port' for a specific
        !          5141:      port are defined in 'mach/task_special_ports.h':
        !          5142:      'task_get_exception_port' and 'task_get_bootstrap_port'.
        !          5143: 
        !          5144:      The function returns 'KERN_SUCCESS' if the port was returned and
        !          5145:      'KERN_INVALID_ARGUMENT' if TASK is not a task or WHICH_PORT is an
        !          5146:      invalid port selector.
        !          5147: 
        !          5148:  -- Function: kern_return_t task_get_kernel_port (task_t TASK,
        !          5149:           mach_port_t *KERNEL_PORT)
        !          5150:      The function 'task_get_kernel_port' is equivalent to the function
        !          5151:      'task_get_special_port' with the WHICH_PORT argument set to
        !          5152:      'TASK_KERNEL_PORT'.
        !          5153: 
        !          5154:  -- Function: kern_return_t task_get_exception_port (task_t TASK,
        !          5155:           mach_port_t *EXCEPTION_PORT)
        !          5156:      The function 'task_get_exception_port' is equivalent to the
        !          5157:      function 'task_get_special_port' with the WHICH_PORT argument set
        !          5158:      to 'TASK_EXCEPTION_PORT'.
        !          5159: 
        !          5160:  -- Function: kern_return_t task_get_bootstrap_port (task_t TASK,
        !          5161:           mach_port_t *BOOTSTRAP_PORT)
        !          5162:      The function 'task_get_bootstrap_port' is equivalent to the
        !          5163:      function 'task_get_special_port' with the WHICH_PORT argument set
        !          5164:      to 'TASK_BOOTSTRAP_PORT'.
        !          5165: 
        !          5166:  -- Function: kern_return_t task_set_special_port (task_t TASK,
        !          5167:           int WHICH_PORT, mach_port_t SPECIAL_PORT)
        !          5168:      The function 'thread_set_special_port' sets one of a set of special
        !          5169:      ports for the task specified by TASK.
        !          5170: 
        !          5171:      The special ports associated with a task are the kernel port
        !          5172:      ('TASK_KERNEL_PORT'), the bootstrap port ('TASK_BOOTSTRAP_PORT')
        !          5173:      and the exception port ('TASK_EXCEPTION_PORT').  The bootstrap port
        !          5174:      is a port to which a thread may send a message requesting other
        !          5175:      system service ports.  This port is not used by the kernel.  The
        !          5176:      task's exception port is the port to which messages are sent by the
        !          5177:      kernel when an exception occurs and the thread causing the
        !          5178:      exception has no exception port of its own.
        !          5179: 
        !          5180:      The function returns 'KERN_SUCCESS' if the port was set and
        !          5181:      'KERN_INVALID_ARGUMENT' if TASK is not a task or WHICH_PORT is an
        !          5182:      invalid port selector.
        !          5183: 
        !          5184:  -- Function: kern_return_t task_set_kernel_port (task_t TASK,
        !          5185:           mach_port_t KERNEL_PORT)
        !          5186:      The function 'task_set_kernel_port' is equivalent to the function
        !          5187:      'task_set_special_port' with the WHICH_PORT argument set to
        !          5188:      'TASK_KERNEL_PORT'.
        !          5189: 
        !          5190:  -- Function: kern_return_t task_set_exception_port (task_t TASK,
        !          5191:           mach_port_t EXCEPTION_PORT)
        !          5192:      The function 'task_set_exception_port' is equivalent to the
        !          5193:      function 'task_set_special_port' with the WHICH_PORT argument set
        !          5194:      to 'TASK_EXCEPTION_PORT'.
        !          5195: 
        !          5196:  -- Function: kern_return_t task_set_bootstrap_port (task_t TASK,
        !          5197:           mach_port_t BOOTSTRAP_PORT)
        !          5198:      The function 'task_set_bootstrap_port' is equivalent to the
        !          5199:      function 'task_set_special_port' with the WHICH_PORT argument set
        !          5200:      to 'TASK_BOOTSTRAP_PORT'.
        !          5201: 
        !          5202: 
        !          5203: File: mach.info,  Node: Syscall Emulation,  Prev: Task Special Ports,  Up: Task Interface
        !          5204: 
        !          5205: 7.2.6 Syscall Emulation
        !          5206: -----------------------
        !          5207: 
        !          5208:  -- Function: kern_return_t task_get_emulation_vector (task_t TASK,
        !          5209:           int *VECTOR_START, emulation_vector_t *EMULATION_VECTOR,
        !          5210:           mach_msg_type_number_t *EMULATION_VECTOR_COUNT)
        !          5211:      The function 'task_get_emulation_vector' gets the user-level
        !          5212:      handler entry points for all emulated system calls.
        !          5213: 
        !          5214:  -- Function: kern_return_t task_set_emulation_vector (task_t TASK,
        !          5215:           int VECTOR_START, emulation_vector_t EMULATION_VECTOR,
        !          5216:           mach_msg_type_number_t EMULATION_VECTOR_COUNT)
        !          5217:      The function 'task_set_emulation_vector' establishes user-level
        !          5218:      handlers for the specified system calls.  Non-emulated system calls
        !          5219:      are specified with an entry of 'EML_ROUTINE_NULL'.  System call
        !          5220:      emulation handlers are inherited by the children of TASK.
        !          5221: 
        !          5222:  -- Function: kern_return_t task_set_emulation (task_t TASK,
        !          5223:           vm_address_t ROUTINE_ENTRY_PT, int ROUTINE_NUMBER)
        !          5224:      The function 'task_set_emulation' establishes a user-level handler
        !          5225:      for the specified system call.  System call emulation handlers are
        !          5226:      inherited by the children of TASK.
        !          5227: 
        !          5228: 
        !          5229: File: mach.info,  Node: Profiling,  Prev: Task Interface,  Up: Threads and Tasks
        !          5230: 
        !          5231: 7.3 Profiling
        !          5232: =============
        !          5233: 
        !          5234:  -- Function: kern_return_t task_enable_pc_sampling (task_t TASK,
        !          5235:           int *TICKS, sampled_pc_flavor_t FLAVOR)
        !          5236:  -- Function: kern_return_t thread_enable_pc_sampling (thread_t THREAD,
        !          5237:           int *TICKS, sampled_pc_flavor_t FLAVOR)
        !          5238:      The function 'task_enable_pc_sampling' enables PC sampling for
        !          5239:      TASK, the function 'thread_enable_pc_sampling' enables PC sampling
        !          5240:      for THREAD.  The kernel's idea of clock granularity is returned in
        !          5241:      TICKS in usecs.  (this value should not be trusted).  The sampling
        !          5242:      flavor is specified by FLAVOR.
        !          5243: 
        !          5244:      The function returns 'KERN_SUCCESS' if the operation is completed
        !          5245:      successfully and 'KERN_INVALID_ARGUMENT' if THREAD is not a valid
        !          5246:      thread.
        !          5247: 
        !          5248:  -- Function: kern_return_t task_disable_pc_sampling (task_t TASK,
        !          5249:           int *SAMPLE_COUNT)
        !          5250:  -- Function: kern_return_t thread_disable_pc_sampling (thread_t THREAD,
        !          5251:           int *SAMPLE_COUNT)
        !          5252:      The function 'task_disable_pc_sampling' disables PC sampling for
        !          5253:      TASK, the function 'thread_disable_pc_sampling' disables PC
        !          5254:      sampling for THREAD.  The number of sample elements in the kernel
        !          5255:      for the thread is returned in SAMPLE_COUNT.
        !          5256: 
        !          5257:      The function returns 'KERN_SUCCESS' if the operation is completed
        !          5258:      successfully and 'KERN_INVALID_ARGUMENT' if THREAD is not a valid
        !          5259:      thread.
        !          5260: 
        !          5261:  -- Function: kern_return_t task_get_sampled_pcs (task_t TASK,
        !          5262:           sampled_pc_seqno_t *SEQNO, sampled_pc_array_t SAMPLED_PCS,
        !          5263:           mach_msg_type_number_t *SAMPLE_COUNT)
        !          5264:  -- Function: kern_return_t thread_get_sampled_pcs (thread_t THREAD,
        !          5265:           sampled_pc_seqno_t *SEQNO, sampled_pc_array_t SAMPLED_PCS,
        !          5266:           int *SAMPLE_COUNT)
        !          5267:      The function 'task_get_sampled_pcs' extracts the PC samples for
        !          5268:      TASK, the function 'thread_get_sampled_pcs' extracts the PC samples
        !          5269:      for THREAD.  SEQNO is the sequence number of the sampled PCs.  This
        !          5270:      is useful for determining when a collector thread has missed a
        !          5271:      sample.  The sampled PCs for the thread are returned in
        !          5272:      SAMPLED_PCS.  SAMPLE_COUNT contains the number of sample elements
        !          5273:      returned.
        !          5274: 
        !          5275:      The function returns 'KERN_SUCCESS' if the operation is completed
        !          5276:      successfully, 'KERN_INVALID_ARGUMENT' if THREAD is not a valid
        !          5277:      thread and 'KERN_FAILURE' if THREAD is not sampled.
        !          5278: 
        !          5279:  -- Data type: sampled_pc_t
        !          5280:      This structure is returned in SAMPLED_PCS by the
        !          5281:      'thread_get_sampled_pcs' and 'task_get_sampled_pcs' functions and
        !          5282:      provides pc samples for threads or tasks.  It has the following
        !          5283:      members:
        !          5284: 
        !          5285:      'natural_t id'
        !          5286:           A thread-specific unique identifier.
        !          5287: 
        !          5288:      'vm_offset_t pc'
        !          5289:           A pc value.
        !          5290: 
        !          5291:      'sampled_pc_flavor_t sampletype'
        !          5292:           The type of the sample as per flavor.
        !          5293: 
        !          5294:  -- Data type: sampled_pc_flavor_t
        !          5295:      This data type specifies a pc sample flavor, either as argument
        !          5296:      passed in FLAVOR to the 'thread_enable_pc_sample' and
        !          5297:      'thread_disable_pc_sample' functions, or as member 'sampletype' in
        !          5298:      the 'sample_pc_t' data type.  The flavor is a bitwise-or of the
        !          5299:      possible flavors defined in 'mach/pc_sample.h':
        !          5300: 
        !          5301:      'SAMPLED_PC_PERIODIC'
        !          5302:           default
        !          5303:      'SAMPLED_PC_VM_ZFILL_FAULTS'
        !          5304:           zero filled fault
        !          5305:      'SAMPLED_PC_VM_REACTIVATION_FAULTS'
        !          5306:           reactivation fault
        !          5307:      'SAMPLED_PC_VM_PAGEIN_FAULTS'
        !          5308:           pagein fault
        !          5309:      'SAMPLED_PC_VM_COW_FAULTS'
        !          5310:           copy-on-write fault
        !          5311:      'SAMPLED_PC_VM_FAULTS_ANY'
        !          5312:           any fault
        !          5313:      'SAMPLED_PC_VM_FAULTS'
        !          5314:           the bitwise-or of 'SAMPLED_PC_VM_ZFILL_FAULTS',
        !          5315:           'SAMPLED_PC_VM_REACTIVATION_FAULTS',
        !          5316:           'SAMPLED_PC_VM_PAGEIN_FAULTS' and 'SAMPLED_PC_VM_COW_FAULTS'.
        !          5317: 
        !          5318: 
        !          5319: File: mach.info,  Node: Host Interface,  Next: Processors and Processor Sets,  Prev: Threads and Tasks,  Up: Top
        !          5320: 
        !          5321: 8 Host Interface
        !          5322: ****************
        !          5323: 
        !          5324: This section describes the Mach interface to a host executing a Mach
        !          5325: kernel.  The interface allows to query statistics about a host and
        !          5326: control its behaviour.
        !          5327: 
        !          5328:    A host is represented by two ports, a name port HOST used to query
        !          5329: information about the host accessible to everyone, and a control port
        !          5330: HOST_PRIV used to manipulate it.  For example, you can query the current
        !          5331: time using the name port, but to change the time you need to send a
        !          5332: message to the host control port.
        !          5333: 
        !          5334:    Everything described in this section is declared in the header file
        !          5335: 'mach.h'.
        !          5336: 
        !          5337: * Menu:
        !          5338: 
        !          5339: * Host Ports::                    Ports representing a host.
        !          5340: * Host Information::              Retrieval of information about a host.
        !          5341: * Host Time::                     Operations on the time as seen by a host.
        !          5342: * Host Reboot::                   Rebooting the system.
        !          5343: 
        !          5344: 
        !          5345: File: mach.info,  Node: Host Ports,  Next: Host Information,  Up: Host Interface
        !          5346: 
        !          5347: 8.1 Host Ports
        !          5348: ==============
        !          5349: 
        !          5350:  -- Data type: host_t
        !          5351:      This is a 'mach_port_t' and used to hold the port name of a host
        !          5352:      name port (or short: host port).  Any task can get a send right to
        !          5353:      the name port of the host running the task using the
        !          5354:      'mach_host_self' system call.  The name port can be used query
        !          5355:      information about the host, for example the current time.
        !          5356: 
        !          5357:  -- Function: host_t mach_host_self ()
        !          5358:      The 'mach_host_self' system call returns the calling thread's host
        !          5359:      name port.  It has an effect equivalent to receiving a send right
        !          5360:      for the host port.  'mach_host_self' returns the name of the send
        !          5361:      right.  In particular, successive calls will increase the calling
        !          5362:      task's user-reference count for the send right.
        !          5363: 
        !          5364:      As a special exception, the kernel will overrun the user reference
        !          5365:      count of the host name port, so that this function can not fail for
        !          5366:      that reason.  Because of this, the user should not deallocate the
        !          5367:      port right if an overrun might have happened.  Otherwise the
        !          5368:      reference count could drop to zero and the send right be destroyed
        !          5369:      while the user still expects to be able to use it.  As the kernel
        !          5370:      does not make use of the number of extant send rights anyway, this
        !          5371:      is safe to do (the host port itself is never destroyed).
        !          5372: 
        !          5373:      The function returns 'MACH_PORT_NULL' if a resource shortage
        !          5374:      prevented the reception of the send right.
        !          5375: 
        !          5376:      This function is also available in 'mach/mach_traps.h'.
        !          5377: 
        !          5378:  -- Data type: host_priv_t
        !          5379:      This is a 'mach_port_t' and used to hold the port name of a
        !          5380:      privileged host control port.  A send right to the host control
        !          5381:      port is inserted into the first task at bootstrap (*note
        !          5382:      Modules::).  This is the only way to get access to the host control
        !          5383:      port in Mach, so the initial task has to preserve the send right
        !          5384:      carefully, moving a copy of it to other privileged tasks if
        !          5385:      necessary and denying access to unprivileged tasks.
        !          5386: 
        !          5387: 
        !          5388: File: mach.info,  Node: Host Information,  Next: Host Time,  Prev: Host Ports,  Up: Host Interface
        !          5389: 
        !          5390: 8.2 Host Information
        !          5391: ====================
        !          5392: 
        !          5393:  -- Function: kern_return_t host_info (host_t HOST, int FLAVOR,
        !          5394:           host_info_t HOST_INFO,
        !          5395:           mach_msg_type_number_t *HOST_INFO_COUNT)
        !          5396:      The 'host_info' function returns various information about HOST.
        !          5397:      HOST_INFO is an array of integers that is supplied by the caller.
        !          5398:      It will be filled with the requested information.  HOST_INFO_COUNT
        !          5399:      is supplied as the maximum number of integers in HOST_INFO.  On
        !          5400:      return, it contains the actual number of integers in HOST_INFO.
        !          5401:      The maximum number of integers returned by any flavor is
        !          5402:      'HOST_INFO_MAX'.
        !          5403: 
        !          5404:      The type of information returned is defined by FLAVOR, which can be
        !          5405:      one of the following:
        !          5406: 
        !          5407:      'HOST_BASIC_INFO'
        !          5408:           The function returns basic information about the host, as
        !          5409:           defined by 'host_basic_info_t'.  This includes the number of
        !          5410:           processors, their type, and the amount of memory installed in
        !          5411:           the system.  The number of integers returned is
        !          5412:           'HOST_BASIC_INFO_COUNT'.  For how to get more information
        !          5413:           about the processor, see *note Processor Interface::.
        !          5414: 
        !          5415:      'HOST_PROCESSOR_SLOTS'
        !          5416:           The function returns the numbers of the slots with active
        !          5417:           processors in them.  The number of integers returned can be up
        !          5418:           to 'max_cpus', as returned by the 'HOST_BASIC_INFO' flavor of
        !          5419:           'host_info'.
        !          5420: 
        !          5421:      'HOST_SCHED_INFO'
        !          5422:           The function returns information of interest to schedulers as
        !          5423:           defined by 'host_sched_info_t'.  The number of integers
        !          5424:           returned is 'HOST_SCHED_INFO_COUNT'.
        !          5425: 
        !          5426:      The function returns 'KERN_SUCCESS' if the call succeeded and
        !          5427:      'KERN_INVALID_ARGUMENT' if HOST is not a host or FLAVOR is not
        !          5428:      recognized.  The function returns 'MIG_ARRAY_TOO_LARGE' if the
        !          5429:      returned info array is too large for HOST_INFO.  In this case,
        !          5430:      HOST_INFO is filled as much as possible and HOST_INFO_COUNT is set
        !          5431:      to the number of elements that would be returned if there were
        !          5432:      enough room.
        !          5433: 
        !          5434:  -- Data type: struct host_basic_info
        !          5435:      A pointer to this structure is returned in HOST_INFO by the
        !          5436:      'host_info' function and provides basic information about the host.
        !          5437:      You can cast a variable of type 'host_info_t' to a pointer of this
        !          5438:      type if you provided it as the HOST_INFO parameter for the
        !          5439:      'HOST_BASIC_INFO' flavor of 'host_info'.  It has the following
        !          5440:      members:
        !          5441: 
        !          5442:      'int max_cpus'
        !          5443:           The maximum number of possible processors for which the kernel
        !          5444:           is configured.
        !          5445: 
        !          5446:      'int avail_cpus'
        !          5447:           The number of cpus currently available.
        !          5448: 
        !          5449:      'vm_size_t memory_size'
        !          5450:           The size of physical memory in bytes.
        !          5451: 
        !          5452:      'cpu_type_t cpu_type'
        !          5453:           The type of the master processor.
        !          5454: 
        !          5455:      'cpu_subtype_t cpu_subtype'
        !          5456:           The subtype of the master processor.
        !          5457: 
        !          5458:      The type and subtype of the individual processors are also
        !          5459:      available by 'processor_info', see *note Processor Interface::.
        !          5460: 
        !          5461:  -- Data type: host_basic_info_t
        !          5462:      This is a pointer to a 'struct host_basic_info'.
        !          5463: 
        !          5464:  -- Data type: struct host_sched_info
        !          5465:      A pointer to this structure is returned in HOST_INFO by the
        !          5466:      'host_info' function and provides information of interest to
        !          5467:      schedulers.  You can cast a variable of type 'host_info_t' to a
        !          5468:      pointer of this type if you provided it as the HOST_INFO parameter
        !          5469:      for the 'HOST_SCHED_INFO' flavor of 'host_info'.  It has the
        !          5470:      following members:
        !          5471: 
        !          5472:      'int min_timeout'
        !          5473:           The minimum timeout and unit of time in milliseconds.
        !          5474: 
        !          5475:      'int min_quantum'
        !          5476:           The minimum quantum and unit of quantum in milliseconds.
        !          5477: 
        !          5478:  -- Data type: host_sched_info_t
        !          5479:      This is a pointer to a 'struct host_sched_info'.
        !          5480: 
        !          5481:  -- Function: kern_return_t host_kernel_version (host_t HOST,
        !          5482:           kernel_version_t *VERSION)
        !          5483:      The 'host_kernel_version' function returns the version string
        !          5484:      compiled into the kernel executing on HOST at the time it was built
        !          5485:      in the character string VERSION.  This string describes the version
        !          5486:      of the kernel.  The constant 'KERNEL_VERSION_MAX' should be used to
        !          5487:      dimension storage for the returned string if the 'kernel_version_t'
        !          5488:      declaration is not used.
        !          5489: 
        !          5490:      If the version string compiled into the kernel is longer than
        !          5491:      'KERNEL_VERSION_MAX', the result is truncated and not necessarily
        !          5492:      null-terminated.
        !          5493: 
        !          5494:      If HOST is not a valid send right to a host port, the function
        !          5495:      returns 'KERN_INVALID_ARGUMENT'.  If VERSION points to inaccessible
        !          5496:      memory, it returns 'KERN_INVALID_ADDRESS', and 'KERN_SUCCESS'
        !          5497:      otherwise.
        !          5498: 
        !          5499:  -- Function: kern_return_t host_get_boot_info (host_priv_t HOST_PRIV,
        !          5500:           kernel_boot_info_t BOOT_INFO)
        !          5501:      The 'host_get_boot_info' function returns the boot-time information
        !          5502:      string supplied by the operator to the kernel executing on
        !          5503:      HOST_PRIV in the character string BOOT_INFO.  The constant
        !          5504:      'KERNEL_BOOT_INFO_MAX' should be used to dimension storage for the
        !          5505:      returned string if the 'kernel_boot_info_t' declaration is not
        !          5506:      used.
        !          5507: 
        !          5508:      If the boot-time information string supplied by the operator is
        !          5509:      longer than 'KERNEL_BOOT_INFO_MAX', the result is truncated and not
        !          5510:      necessarily null-terminated.
        !          5511: 
        !          5512: 
        !          5513: File: mach.info,  Node: Host Time,  Next: Host Reboot,  Prev: Host Information,  Up: Host Interface
        !          5514: 
        !          5515: 8.3 Host Time
        !          5516: =============
        !          5517: 
        !          5518:  -- Data type: time_value_t
        !          5519:      This is the representation of a time in Mach.  It is a 'struct
        !          5520:      time_value' and consists of the following members:
        !          5521: 
        !          5522:      'integer_t seconds'
        !          5523:           The number of seconds.
        !          5524:      'integer_t microseconds'
        !          5525:           The number of microseconds.
        !          5526: 
        !          5527:    The number of microseconds should always be smaller than
        !          5528: 'TIME_MICROS_MAX' (100000).  A time with this property is "normalized".
        !          5529: Normalized time values can be manipulated with the following macros:
        !          5530: 
        !          5531:  -- Macro: time_value_add_usec (time_value_t *VAL, integer_t *MICROS)
        !          5532:      Add MICROS microseconds to VAL.  If VAL is normalized and MICROS
        !          5533:      smaller than 'TIME_MICROS_MAX', VAL will be normalized afterwards.
        !          5534: 
        !          5535:  -- Macro: time_value_add (time_value_t *RESULT, time_value_t *ADDEND)
        !          5536:      Add the values in ADDEND to RESULT.  If both are normalized, RESULT
        !          5537:      will be normalized afterwards.
        !          5538: 
        !          5539:    A variable of type 'time_value_t' can either represent a duration or
        !          5540: a fixed point in time.  In the latter case, it shall be interpreted as
        !          5541: the number of seconds and microseconds after the epoch 1.  Jan 1970.
        !          5542: 
        !          5543:  -- Function: kern_return_t host_get_time (host_t HOST,
        !          5544:           time_value_t *CURRENT_TIME)
        !          5545:      Get the current time as seen by HOST.  On success, the time passed
        !          5546:      since the epoch is returned in CURRENT_TIME.
        !          5547: 
        !          5548:  -- Function: kern_return_t host_set_time (host_priv_t HOST_PRIV,
        !          5549:           time_value_t NEW_TIME)
        !          5550:      Set the time of HOST_PRIV to NEW_TIME.
        !          5551: 
        !          5552:  -- Function: kern_return_t host_adjust_time (host_priv_t HOST_PRIV,
        !          5553:           time_value_t NEW_ADJUSTMENT, time_value_t *OLD_ADJUSTMENT)
        !          5554:      Arrange for the current time as seen by HOST_PRIV to be gradually
        !          5555:      changed by the adjustment value NEW_ADJUSTMENT, and return the old
        !          5556:      adjustment value in OLD_ADJUSTMENT.
        !          5557: 
        !          5558:    For efficiency, the current time is available through a mapped-time
        !          5559: interface.
        !          5560: 
        !          5561:  -- Data type: mapped_time_value_t
        !          5562:      This structure defines the mapped-time interface.  It has the
        !          5563:      following members:
        !          5564: 
        !          5565:      'integer_t seconds'
        !          5566:           The number of seconds.
        !          5567: 
        !          5568:      'integer_t microseconds'
        !          5569:           The number of microseconds.
        !          5570: 
        !          5571:      'integer_t check_seconds'
        !          5572:           This is a copy of the seconds value, which must be checked to
        !          5573:           protect against a race condition when reading out the two time
        !          5574:           values.
        !          5575: 
        !          5576:    Here is an example how to read out the current time using the
        !          5577: mapped-time interface:
        !          5578: 
        !          5579:      do
        !          5580:        {
        !          5581:          secs = mtime->seconds;
        !          5582:          usecs = mtime->microseconds;
        !          5583:        }
        !          5584:      while (secs != mtime->check_seconds);
        !          5585: 
        !          5586: 
        !          5587: File: mach.info,  Node: Host Reboot,  Prev: Host Time,  Up: Host Interface
        !          5588: 
        !          5589: 8.4 Host Reboot
        !          5590: ===============
        !          5591: 
        !          5592:  -- Function: kern_return_t host_reboot (host_priv_t HOST_PRIV,
        !          5593:           int OPTIONS)
        !          5594:      Reboot the host specified by HOST_PRIV.  The argument OPTIONS
        !          5595:      specifies the flags.  The available flags are defined in
        !          5596:      'sys/reboot.h':
        !          5597: 
        !          5598:      'RB_HALT'
        !          5599:           Do not reboot, but halt the machine.
        !          5600: 
        !          5601:      'RB_DEBUGGER'
        !          5602:           Do not reboot, but enter kernel debugger from user space.
        !          5603: 
        !          5604:      If successful, the function might not return.
        !          5605: 
        !          5606: 
        !          5607: File: mach.info,  Node: Processors and Processor Sets,  Next: Device Interface,  Prev: Host Interface,  Up: Top
        !          5608: 
        !          5609: 9 Processors and Processor Sets
        !          5610: *******************************
        !          5611: 
        !          5612: This section describes the Mach interface to processor sets and
        !          5613: individual processors.  The interface allows to group processors into
        !          5614: sets and control the processors and processor sets.
        !          5615: 
        !          5616:    A processor is not a central part of the interface.  It is mostly of
        !          5617: relevance as a part of a processor set.  Threads are always assigned to
        !          5618: processor sets, and all processors in a set are equally involved in
        !          5619: executing all threads assigned to that set.
        !          5620: 
        !          5621:    The processor set is represented by two ports, a name port
        !          5622: PROCESSOR_SET_NAME used to query information about the host accessible
        !          5623: to everyone, and a control port PROCESSOR_SET used to manipulate it.
        !          5624: 
        !          5625: * Menu:
        !          5626: 
        !          5627: * Processor Set Interface::       How to work with processor sets.
        !          5628: * Processor Interface::           How to work with individual processors.
        !          5629: 
        !          5630: 
        !          5631: File: mach.info,  Node: Processor Set Interface,  Next: Processor Interface,  Up: Processors and Processor Sets
        !          5632: 
        !          5633: 9.1 Processor Set Interface
        !          5634: ===========================
        !          5635: 
        !          5636: * Menu:
        !          5637: 
        !          5638: * Processor Set Ports::           Ports representing a processor set.
        !          5639: * Processor Set Access::          How the processor sets are accessed.
        !          5640: * Processor Set Creation::        How new processor sets are created.
        !          5641: * Processor Set Destruction::     How processor sets are destroyed.
        !          5642: * Tasks and Threads on Sets::     Assigning tasks, threads to processor sets.
        !          5643: * Processor Set Priority::        Specifying the priority of a processor set.
        !          5644: * Processor Set Policy::          Changing the processor set policies.
        !          5645: * Processor Set Info::            Obtaining information about a processor set.
        !          5646: 
        !          5647: 
        !          5648: File: mach.info,  Node: Processor Set Ports,  Next: Processor Set Access,  Up: Processor Set Interface
        !          5649: 
        !          5650: 9.1.1 Processor Set Ports
        !          5651: -------------------------
        !          5652: 
        !          5653:  -- Data type: processor_set_name_t
        !          5654:      This is a 'mach_port_t' and used to hold the port name of a
        !          5655:      processor set name port that names the processor set.  Any task can
        !          5656:      get a send right to name port of a processor set.  The processor
        !          5657:      set name port allows to get information about the processor set.
        !          5658: 
        !          5659:  -- Data type: processor_set_t
        !          5660:      This is a 'mach_port_t' and used to hold the port name of a
        !          5661:      privileged processor set control port that represents the processor
        !          5662:      set.  Operations on the processor set are implemented as remote
        !          5663:      procedure calls to the processor set port.  The processor set port
        !          5664:      allows to manipulate the processor set.
        !          5665: 
        !          5666: 
        !          5667: File: mach.info,  Node: Processor Set Access,  Next: Processor Set Creation,  Prev: Processor Set Ports,  Up: Processor Set Interface
        !          5668: 
        !          5669: 9.1.2 Processor Set Access
        !          5670: --------------------------
        !          5671: 
        !          5672:  -- Function: kern_return_t host_processor_sets (host_t HOST,
        !          5673:           processor_set_name_array_t *PROCESSOR_SETS,
        !          5674:           mach_msg_type_number_t *PROCESSOR_SETS_COUNT)
        !          5675:      The function 'host_processor_sets' gets send rights to the name
        !          5676:      port for each processor set currently assigned to HOST.
        !          5677: 
        !          5678:      'host_processor_set_priv' can be used to obtain the control ports
        !          5679:      from these if desired.  PROCESSOR_SETS is an array that is created
        !          5680:      as a result of this call.  The caller may wish to 'vm_deallocate'
        !          5681:      this array when the data is no longer needed.  PROCESSOR_SETS_COUNT
        !          5682:      is set to the number of processor sets in the PROCESSOR_SETS.
        !          5683: 
        !          5684:      This function returns 'KERN_SUCCESS' if the call succeeded and
        !          5685:      'KERN_INVALID_ARGUMENT' if HOST is not a host.
        !          5686: 
        !          5687:  -- Function: kern_return_t host_processor_set_priv
        !          5688:           (host_priv_t HOST_PRIV, processor_set_name_t SET_NAME,
        !          5689:           processor_set_t *SET)
        !          5690:      The function 'host_processor_set_priv' allows a privileged
        !          5691:      application to obtain the control port SET for an existing
        !          5692:      processor set from its name port SET_NAME.  The privileged host
        !          5693:      port HOST_PRIV is required.
        !          5694: 
        !          5695:      This function returns 'KERN_SUCCESS' if the call succeeded and
        !          5696:      'KERN_INVALID_ARGUMENT' if HOST_PRIV is not a valid host control
        !          5697:      port.
        !          5698: 
        !          5699:  -- Function: kern_return_t processor_set_default (host_t HOST,
        !          5700:           processor_set_name_t *DEFAULT_SET)
        !          5701:      The function 'processor_set_default' returns the default processor
        !          5702:      set of HOST in DEFAULT_SET.  The default processor set is used by
        !          5703:      all threads, tasks, and processors that are not explicitly assigned
        !          5704:      to other sets.  processor_set_default returns a port that can be
        !          5705:      used to obtain information about this set (e.g.  how many threads
        !          5706:      are assigned to it).  This port cannot be used to perform
        !          5707:      operations on that set.
        !          5708: 
        !          5709:      This function returns 'KERN_SUCCESS' if the call succeeded,
        !          5710:      'KERN_INVALID_ARGUMENT' if HOST is not a host and
        !          5711:      'KERN_INVALID_ADDRESS' if DEFAULT_SET points to inaccessible
        !          5712:      memory.
        !          5713: 
        !          5714: 
        !          5715: File: mach.info,  Node: Processor Set Creation,  Next: Processor Set Destruction,  Prev: Processor Set Access,  Up: Processor Set Interface
        !          5716: 
        !          5717: 9.1.3 Processor Set Creation
        !          5718: ----------------------------
        !          5719: 
        !          5720:  -- Function: kern_return_t processor_set_create (host_t HOST,
        !          5721:           processor_set_t *NEW_SET, processor_set_name_t *NEW_NAME)
        !          5722:      The function 'processor_set_create' creates a new processor set on
        !          5723:      HOST and returns the two ports associated with it.  The port
        !          5724:      returned in NEW_SET is the actual port representing the set.  It is
        !          5725:      used to perform operations such as assigning processors, tasks, or
        !          5726:      threads.  The port returned in NEW_NAME identifies the set, and is
        !          5727:      used to obtain information about the set.
        !          5728: 
        !          5729:      This function returns 'KERN_SUCCESS' if the call succeeded,
        !          5730:      'KERN_INVALID_ARGUMENT' if HOST is not a host,
        !          5731:      'KERN_INVALID_ADDRESS' if NEW_SET or NEW_NAME points to
        !          5732:      inaccessible memory and 'KERN_FAILURE' is the operating system does
        !          5733:      not support processor allocation.
        !          5734: 
        !          5735: 
        !          5736: File: mach.info,  Node: Processor Set Destruction,  Next: Tasks and Threads on Sets,  Prev: Processor Set Creation,  Up: Processor Set Interface
        !          5737: 
        !          5738: 9.1.4 Processor Set Destruction
        !          5739: -------------------------------
        !          5740: 
        !          5741:  -- Function: kern_return_t processor_set_destroy
        !          5742:           (processor_set_t PROCESSOR_SET)
        !          5743:      The function 'processor_set_destroy' destroys the specified
        !          5744:      processor set.  Any assigned processors, tasks, or threads are
        !          5745:      reassigned to the default set.  The object port for the processor
        !          5746:      set is required (not the name port).  The default processor set
        !          5747:      cannot be destroyed.
        !          5748: 
        !          5749:      This function returns 'KERN_SUCCESS' if the set was destroyed,
        !          5750:      'KERN_FAILURE' if an attempt was made to destroy the default
        !          5751:      processor set, or the operating system does not support processor
        !          5752:      allocation, and 'KERN_INVALID_ARGUMENT' if PROCESSOR_SET is not a
        !          5753:      valid processor set control port.
        !          5754: 
        !          5755: 
        !          5756: File: mach.info,  Node: Tasks and Threads on Sets,  Next: Processor Set Priority,  Prev: Processor Set Destruction,  Up: Processor Set Interface
        !          5757: 
        !          5758: 9.1.5 Tasks and Threads on Sets
        !          5759: -------------------------------
        !          5760: 
        !          5761:  -- Function: kern_return_t processor_set_tasks
        !          5762:           (processor_set_t PROCESSOR_SET, task_array_t *TASK_LIST,
        !          5763:           mach_msg_type_number_t *TASK_COUNT)
        !          5764:      The function 'processor_set_tasks' gets send rights to the kernel
        !          5765:      port for each task currently assigned to PROCESSOR_SET.
        !          5766: 
        !          5767:      TASK_LIST is an array that is created as a result of this call.
        !          5768:      The caller may wish to 'vm_deallocate' this array when the data is
        !          5769:      no longer needed.  TASK_COUNT is set to the number of tasks in the
        !          5770:      TASK_LIST.
        !          5771: 
        !          5772:      This function returns 'KERN_SUCCESS' if the call succeeded and
        !          5773:      'KERN_INVALID_ARGUMENT' if PROCESSOR_SET is not a processor set.
        !          5774: 
        !          5775:  -- Function: kern_return_t processor_set_threads
        !          5776:           (processor_set_t PROCESSOR_SET, thread_array_t *THREAD_LIST,
        !          5777:           mach_msg_type_number_t *THREAD_COUNT)
        !          5778:      The function 'processor_set_thread' gets send rights to the kernel
        !          5779:      port for each thread currently assigned to PROCESSOR_SET.
        !          5780: 
        !          5781:      THREAD_LIST is an array that is created as a result of this call.
        !          5782:      The caller may wish to 'vm_deallocate' this array when the data is
        !          5783:      no longer needed.  THREAD_COUNT is set to the number of threads in
        !          5784:      the THREAD_LIST.
        !          5785: 
        !          5786:      This function returns 'KERN_SUCCESS' if the call succeeded and
        !          5787:      'KERN_INVALID_ARGUMENT' if PROCESSOR_SET is not a processor set.
        !          5788: 
        !          5789:  -- Function: kern_return_t task_assign (task_t TASK,
        !          5790:           processor_set_t PROCESSOR_SET, boolean_t ASSIGN_THREADS)
        !          5791:      The function 'task_assign' assigns TASK the set PROCESSOR_SET.
        !          5792:      This assignment is for the purposes of determining the initial
        !          5793:      assignment of newly created threads in task.  Any previous
        !          5794:      assignment of the task is nullified.  Existing threads within the
        !          5795:      task are also reassigned if ASSIGN_THREADS is 'TRUE'.  They are not
        !          5796:      affected if it is 'FALSE'.
        !          5797: 
        !          5798:      This function returns 'KERN_SUCCESS' if the assignment has been
        !          5799:      performed and 'KERN_INVALID_ARGUMENT' if TASK is not a task, or
        !          5800:      PROCESSOR_SET is not a processor set on the same host as TASK.
        !          5801: 
        !          5802:  -- Function: kern_return_t task_assign_default (task_t TASK,
        !          5803:           boolean_t ASSIGN_THREADS)
        !          5804:      The function 'task_assign_default' is a variant of 'task_assign'
        !          5805:      that assigns the task to the default processor set on that task's
        !          5806:      host.  This variant exists because the control port for the default
        !          5807:      processor set is privileged and not usually available to users.
        !          5808: 
        !          5809:      This function returns 'KERN_SUCCESS' if the assignment has been
        !          5810:      performed and 'KERN_INVALID_ARGUMENT' if TASK is not a task.
        !          5811: 
        !          5812:  -- Function: kern_return_t task_get_assignment (task_t TASK,
        !          5813:           processor_set_name_t *ASSIGNED_SET)
        !          5814:      The function 'task_get_assignment' returns the name of the
        !          5815:      processor set to which the thread is currently assigned in
        !          5816:      ASSIGNED_SET.  This port can only be used to obtain information
        !          5817:      about the processor set.
        !          5818: 
        !          5819:      This function returns 'KERN_SUCCESS' if the assignment has been
        !          5820:      performed, 'KERN_INVALID_ADDRESS' if PROCESSOR_SET points to
        !          5821:      inaccessible memory, and 'KERN_INVALID_ARGUMENT' if TASK is not a
        !          5822:      task.
        !          5823: 
        !          5824:  -- Function: kern_return_t thread_assign (thread_t THREAD,
        !          5825:           processor_set_t PROCESSOR_SET)
        !          5826:      The function 'thread_assign' assigns THREAD the set PROCESSOR_SET.
        !          5827:      After the assignment is completed, the thread only executes on
        !          5828:      processors assigned to the designated processor set.  If there are
        !          5829:      no such processors, then the thread is unable to execute.  Any
        !          5830:      previous assignment of the thread is nullified.  Unix system call
        !          5831:      compatibility code may temporarily force threads to execute on the
        !          5832:      master processor.
        !          5833: 
        !          5834:      This function returns 'KERN_SUCCESS' if the assignment has been
        !          5835:      performed and 'KERN_INVALID_ARGUMENT' if THREAD is not a thread, or
        !          5836:      PROCESSOR_SET is not a processor set on the same host as THREAD.
        !          5837: 
        !          5838:  -- Function: kern_return_t thread_assign_default (thread_t THREAD)
        !          5839:      The function 'thread_assign_default' is a variant of
        !          5840:      'thread_assign' that assigns the thread to the default processor
        !          5841:      set on that thread's host.  This variant exists because the control
        !          5842:      port for the default processor set is privileged and not usually
        !          5843:      available to users.
        !          5844: 
        !          5845:      This function returns 'KERN_SUCCESS' if the assignment has been
        !          5846:      performed and 'KERN_INVALID_ARGUMENT' if THREAD is not a thread.
        !          5847: 
        !          5848:  -- Function: kern_return_t thread_get_assignment (thread_t THREAD,
        !          5849:           processor_set_name_t *ASSIGNED_SET)
        !          5850:      The function 'thread_get_assignment' returns the name of the
        !          5851:      processor set to which the thread is currently assigned in
        !          5852:      ASSIGNED_SET.  This port can only be used to obtain information
        !          5853:      about the processor set.
        !          5854: 
        !          5855:      This function returns 'KERN_SUCCESS' if the assignment has been
        !          5856:      performed, 'KERN_INVALID_ADDRESS' if PROCESSOR_SET points to
        !          5857:      inaccessible memory, and 'KERN_INVALID_ARGUMENT' if THREAD is not a
        !          5858:      thread.
        !          5859: 
        !          5860: 
        !          5861: File: mach.info,  Node: Processor Set Priority,  Next: Processor Set Policy,  Prev: Tasks and Threads on Sets,  Up: Processor Set Interface
        !          5862: 
        !          5863: 9.1.6 Processor Set Priority
        !          5864: ----------------------------
        !          5865: 
        !          5866:  -- Function: kern_return_t processor_set_max_priority
        !          5867:           (processor_set_t PROCESSOR_SET, int MAX_PRIORITY,
        !          5868:           boolean_t CHANGE_THREADS)
        !          5869:      The function 'processor_set_max_priority' is used to set the
        !          5870:      maximum priority for a processor set.  The priority of a processor
        !          5871:      set is used only for newly created threads (thread's maximum
        !          5872:      priority is set to processor set's) and the assignment of threads
        !          5873:      to the set (thread's maximum priority is reduced if it exceeds the
        !          5874:      set's maximum priority, thread's priority is similarly reduced).
        !          5875:      'processor_set_max_priority' changes this priority.  It also sets
        !          5876:      the maximum priority of all threads assigned to the processor set
        !          5877:      to this new priority if CHANGE_THREADS is 'TRUE'.  If this maximum
        !          5878:      priority is less than the priorities of any of these threads, their
        !          5879:      priorities will also be set to this new value.
        !          5880: 
        !          5881:      This function returns 'KERN_SUCCESS' if the call succeeded and
        !          5882:      'KERN_INVALID_ARGUMENT' if PROCESSOR_SET is not a processor set or
        !          5883:      PRIORITY is not a valid priority.
        !          5884: 
        !          5885: 
        !          5886: File: mach.info,  Node: Processor Set Policy,  Next: Processor Set Info,  Prev: Processor Set Priority,  Up: Processor Set Interface
        !          5887: 
        !          5888: 9.1.7 Processor Set Policy
        !          5889: --------------------------
        !          5890: 
        !          5891:  -- Function: kern_return_t processor_set_policy_enable
        !          5892:           (processor_set_t PROCESSOR_SET, int POLICY)
        !          5893:  -- Function: kern_return_t processor_set_policy_disable
        !          5894:           (processor_set_t PROCESSOR_SET, int POLICY,
        !          5895:           boolean_t CHANGE_THREADS)
        !          5896:      Processor sets may restrict the scheduling policies to be used for
        !          5897:      threads assigned to them.  These two calls provide the mechanism
        !          5898:      for designating permitted and forbidden policies.  The current set
        !          5899:      of permitted policies can be obtained from 'processor_set_info'.
        !          5900:      Timesharing may not be forbidden by any processor set.  This is a
        !          5901:      compromise to reduce the complexity of the assign operation; any
        !          5902:      thread whose policy is forbidden by the target processor set has
        !          5903:      its policy reset to timesharing.  If the CHANGE_THREADS argument to
        !          5904:      'processor_set_policy_disable' is true, threads currently assigned
        !          5905:      to this processor set and using the newly disabled policy will have
        !          5906:      their policy reset to timesharing.
        !          5907: 
        !          5908:      'mach/policy.h' contains the allowed policies; it is included by
        !          5909:      'mach.h'.  Not all policies (e.g.  fixed priority) are supported by
        !          5910:      all systems.
        !          5911: 
        !          5912:      This function returns 'KERN_SUCCESS' if the operation was completed
        !          5913:      successfully and 'KERN_INVALID_ARGUMENT' if PROCESSOR_SET is not a
        !          5914:      processor set or POLICY is not a valid policy, or an attempt was
        !          5915:      made to disable timesharing.
        !          5916: 
        !          5917: 
        !          5918: File: mach.info,  Node: Processor Set Info,  Prev: Processor Set Policy,  Up: Processor Set Interface
        !          5919: 
        !          5920: 9.1.8 Processor Set Info
        !          5921: ------------------------
        !          5922: 
        !          5923:  -- Function: kern_return_t processor_set_info
        !          5924:           (processor_set_name_t SET_NAME, int FLAVOR, host_t *HOST,
        !          5925:           processor_set_info_t PROCESSOR_SET_INFO,
        !          5926:           mach_msg_type_number_t *PROCESSOR_SET_INFO_COUNT)
        !          5927:      The function 'processor_set_info' returns the selected information
        !          5928:      array for a processor set, as specified by FLAVOR.
        !          5929: 
        !          5930:      HOST is set to the host on which the processor set resides.  This
        !          5931:      is the non-privileged host port.
        !          5932: 
        !          5933:      PROCESSOR_SET_INFO is an array of integers that is supplied by the
        !          5934:      caller and returned filled with specified information.
        !          5935:      PROCESSOR_SET_INFO_COUNT is supplied as the maximum number of
        !          5936:      integers in PROCESSOR_SET_INFO.  On return, it contains the actual
        !          5937:      number of integers in PROCESSOR_SET_INFO.  The maximum number of
        !          5938:      integers returned by any flavor is 'PROCESSOR_SET_INFO_MAX'.
        !          5939: 
        !          5940:      The type of information returned is defined by FLAVOR, which can be
        !          5941:      one of the following:
        !          5942: 
        !          5943:      'PROCESSOR_SET_BASIC_INFO'
        !          5944:           The function returns basic information about the processor
        !          5945:           set, as defined by 'processor_set_basic_info_t'.  This
        !          5946:           includes the number of tasks and threads assigned to the
        !          5947:           processor set.  The number of integers returned is
        !          5948:           'PROCESSOR_SET_BASIC_INFO_COUNT'.
        !          5949: 
        !          5950:      'PROCESSOR_SET_SCHED_INFO'
        !          5951:           The function returns information about the scheduling policy
        !          5952:           for the processor set as defined by
        !          5953:           'processor_set_sched_info_t'.  The number of integers returned
        !          5954:           is 'PROCESSOR_SET_SCHED_INFO_COUNT'.
        !          5955: 
        !          5956:      Some machines may define additional (machine-dependent) flavors.
        !          5957: 
        !          5958:      The function returns 'KERN_SUCCESS' if the call succeeded and
        !          5959:      'KERN_INVALID_ARGUMENT' if PROCESSOR_SET is not a processor set or
        !          5960:      FLAVOR is not recognized.  The function returns
        !          5961:      'MIG_ARRAY_TOO_LARGE' if the returned info array is too large for
        !          5962:      PROCESSOR_SET_INFO.  In this case, PROCESSOR_SET_INFO is filled as
        !          5963:      much as possible and PROCESSOR_SET_INFO_COUNT is set to the number
        !          5964:      of elements that would have been returned if there were enough
        !          5965:      room.
        !          5966: 
        !          5967:  -- Data type: struct processor_set_basic_info
        !          5968:      This structure is returned in PROCESSOR_SET_INFO by the
        !          5969:      'processor_set_info' function and provides basic information about
        !          5970:      the processor set.  You can cast a variable of type
        !          5971:      'processor_set_info_t' to a pointer of this type if you provided it
        !          5972:      as the PROCESSOR_SET_INFO parameter for the
        !          5973:      'PROCESSOR_SET_BASIC_INFO' flavor of 'processor_set_info'.  It has
        !          5974:      the following members:
        !          5975: 
        !          5976:      'int processor_count'
        !          5977:           number of processors
        !          5978: 
        !          5979:      'int task_count'
        !          5980:           number of tasks
        !          5981: 
        !          5982:      'int thread_count'
        !          5983:           number of threads
        !          5984: 
        !          5985:      'int load_average'
        !          5986:           scaled load average
        !          5987: 
        !          5988:      'int mach_factor'
        !          5989:           scaled mach factor
        !          5990: 
        !          5991:  -- Data type: processor_set_basic_info_t
        !          5992:      This is a pointer to a 'struct processor_set_basic_info'.
        !          5993: 
        !          5994:  -- Data type: struct processor_set_sched_info
        !          5995:      This structure is returned in PROCESSOR_SET_INFO by the
        !          5996:      'processor_set_info' function and provides schedule information
        !          5997:      about the processor set.  You can cast a variable of type
        !          5998:      'processor_set_info_t' to a pointer of this type if you provided it
        !          5999:      as the PROCESSOR_SET_INFO parameter for the
        !          6000:      'PROCESSOR_SET_SCHED_INFO' flavor of 'processor_set_info'.  It has
        !          6001:      the following members:
        !          6002: 
        !          6003:      'int policies'
        !          6004:           allowed policies
        !          6005: 
        !          6006:      'int max_priority'
        !          6007:           max priority for new threads
        !          6008: 
        !          6009:  -- Data type: processor_set_sched_info_t
        !          6010:      This is a pointer to a 'struct processor_set_sched_info'.
        !          6011: 
        !          6012: 
        !          6013: File: mach.info,  Node: Processor Interface,  Prev: Processor Set Interface,  Up: Processors and Processor Sets
        !          6014: 
        !          6015: 9.2 Processor Interface
        !          6016: =======================
        !          6017: 
        !          6018:  -- Data type: processor_t
        !          6019:      This is a 'mach_port_t' and used to hold the port name of a
        !          6020:      processor port that represents the processor.  Operations on the
        !          6021:      processor are implemented as remote procedure calls to the
        !          6022:      processor port.
        !          6023: 
        !          6024: * Menu:
        !          6025: 
        !          6026: * Hosted Processors::             Getting a list of all processors on a host.
        !          6027: * Processor Control::             Starting, stopping, controlling processors.
        !          6028: * Processors and Sets::           Combining processors into processor sets.
        !          6029: * Processor Info::                Obtaining information on processors.
        !          6030: 
        !          6031: 
        !          6032: File: mach.info,  Node: Hosted Processors,  Next: Processor Control,  Up: Processor Interface
        !          6033: 
        !          6034: 9.2.1 Hosted Processors
        !          6035: -----------------------
        !          6036: 
        !          6037:  -- Function: kern_return_t host_processors (host_priv_t HOST_PRIV,
        !          6038:           processor_array_t *PROCESSOR_LIST,
        !          6039:           mach_msg_type_number_t *PROCESSOR_COUNT)
        !          6040:      The function 'host_processors' gets send rights to the processor
        !          6041:      port for each processor existing on HOST_PRIV.  This is the
        !          6042:      privileged port that allows its holder to control a processor.
        !          6043: 
        !          6044:      PROCESSOR_LIST is an array that is created as a result of this
        !          6045:      call.  The caller may wish to 'vm_deallocate' this array when the
        !          6046:      data is no longer needed.  PROCESSOR_COUNT is set to the number of
        !          6047:      processors in the PROCESSOR_LIST.
        !          6048: 
        !          6049:      This function returns 'KERN_SUCCESS' if the call succeeded,
        !          6050:      'KERN_INVALID_ARGUMENT' if HOST_PRIV is not a privileged host port,
        !          6051:      and 'KERN_INVALID_ADDRESS' if PROCESSOR_COUNT points to
        !          6052:      inaccessible memory.
        !          6053: 
        !          6054: 
        !          6055: File: mach.info,  Node: Processor Control,  Next: Processors and Sets,  Prev: Hosted Processors,  Up: Processor Interface
        !          6056: 
        !          6057: 9.2.2 Processor Control
        !          6058: -----------------------
        !          6059: 
        !          6060:  -- Function: kern_return_t processor_start (processor_t PROCESSOR)
        !          6061:  -- Function: kern_return_t processor_exit (processor_t PROCESSOR)
        !          6062:  -- Function: kern_return_t processor_control (processor_t PROCESSOR,
        !          6063:           processor_info_t *CMD, mach_msg_type_number_t COUNT)
        !          6064:      Some multiprocessors may allow privileged software to control
        !          6065:      processors.  The 'processor_start', 'processor_exit', and
        !          6066:      'processor_control' operations implement this.  The interpretation
        !          6067:      of the command in CMD is machine dependent.  A newly started
        !          6068:      processor is assigned to the default processor set.  An exited
        !          6069:      processor is removed from the processor set to which it was
        !          6070:      assigned and ceases to be active.
        !          6071: 
        !          6072:      COUNT contains the length of the command CMD as a number of ints.
        !          6073: 
        !          6074:      Availability limited.  All of these operations are
        !          6075:      machine-dependent.  They may do nothing.  The ability to restart an
        !          6076:      exited processor is also machine-dependent.
        !          6077: 
        !          6078:      This function returns 'KERN_SUCCESS' if the operation was
        !          6079:      performed, 'KERN_FAILURE' if the operation was not performed (a
        !          6080:      likely reason is that it is not supported on this processor),
        !          6081:      'KERN_INVALID_ARGUMENT' if PROCESSOR is not a processor, and
        !          6082:      'KERN_INVALID_ADDRESS' if CMD points to inaccessible memory.
        !          6083: 
        !          6084: 
        !          6085: File: mach.info,  Node: Processors and Sets,  Next: Processor Info,  Prev: Processor Control,  Up: Processor Interface
        !          6086: 
        !          6087: 9.2.3 Processors and Sets
        !          6088: -------------------------
        !          6089: 
        !          6090:  -- Function: kern_return_t processor_assign (processor_t PROCESSOR,
        !          6091:           processor_set_t PROCESSOR_SET, boolean_t WAIT)
        !          6092:      The function 'processor_assign' assigns PROCESSOR to the set
        !          6093:      PROCESSOR_SET.  After the assignment is completed, the processor
        !          6094:      only executes threads that are assigned to that processor set.  Any
        !          6095:      previous assignment of the processor is nullified.  The master
        !          6096:      processor cannot be reassigned.  All processors take clock
        !          6097:      interrupts at all times.  The WAIT argument indicates whether the
        !          6098:      caller should wait for the assignment to be completed or should
        !          6099:      return immediately.  Dedicated kernel threads are used to perform
        !          6100:      processor assignment, so setting wait to 'FALSE' allows assignment
        !          6101:      requests to be queued and performed faster, especially if the
        !          6102:      kernel has more than one dedicated internal thread for processor
        !          6103:      assignment.  Redirection of other device interrupts away from
        !          6104:      processors assigned to other than the default processor set is
        !          6105:      machine-dependent.  Intermediaries that interpose on ports must be
        !          6106:      sure to interpose on both ports involved in this call if they
        !          6107:      interpose on either.
        !          6108: 
        !          6109:      This function returns 'KERN_SUCCESS' if the assignment has been
        !          6110:      performed, 'KERN_INVALID_ARGUMENT' if PROCESSOR is not a processor,
        !          6111:      or PROCESSOR_SET is not a processor set on the same host as
        !          6112:      PROCESSOR.
        !          6113: 
        !          6114:  -- Function: kern_return_t processor_get_assignment
        !          6115:           (processor_t PROCESSOR, processor_set_name_t *ASSIGNED_SET)
        !          6116:      The function 'processor_get_assignment' obtains the current
        !          6117:      assignment of a processor.  The name port of the processor set is
        !          6118:      returned in ASSIGNED_SET.
        !          6119: 
        !          6120: 
        !          6121: File: mach.info,  Node: Processor Info,  Prev: Processors and Sets,  Up: Processor Interface
        !          6122: 
        !          6123: 9.2.4 Processor Info
        !          6124: --------------------
        !          6125: 
        !          6126:  -- Function: kern_return_t processor_info (processor_t PROCESSOR,
        !          6127:           int FLAVOR, host_t *HOST, processor_info_t PROCESSOR_INFO,
        !          6128:           mach_msg_type_number_t *PROCESSOR_INFO_COUNT)
        !          6129:      The function 'processor_info' returns the selected information
        !          6130:      array for a processor, as specified by FLAVOR.
        !          6131: 
        !          6132:      HOST is set to the host on which the processor set resides.  This
        !          6133:      is the non-privileged host port.
        !          6134: 
        !          6135:      PROCESSOR_INFO is an array of integers that is supplied by the
        !          6136:      caller and returned filled with specified information.
        !          6137:      PROCESSOR_INFO_COUNT is supplied as the maximum number of integers
        !          6138:      in PROCESSOR_INFO.  On return, it contains the actual number of
        !          6139:      integers in PROCESSOR_INFO.  The maximum number of integers
        !          6140:      returned by any flavor is 'PROCESSOR_INFO_MAX'.
        !          6141: 
        !          6142:      The type of information returned is defined by FLAVOR, which can be
        !          6143:      one of the following:
        !          6144: 
        !          6145:      'PROCESSOR_BASIC_INFO'
        !          6146:           The function returns basic information about the processor, as
        !          6147:           defined by 'processor_basic_info_t'.  This includes the slot
        !          6148:           number of the processor.  The number of integers returned is
        !          6149:           'PROCESSOR_BASIC_INFO_COUNT'.
        !          6150: 
        !          6151:      Machines which require more configuration information beyond the
        !          6152:      slot number are expected to define additional (machine-dependent)
        !          6153:      flavors.
        !          6154: 
        !          6155:      The function returns 'KERN_SUCCESS' if the call succeeded and
        !          6156:      'KERN_INVALID_ARGUMENT' if PROCESSOR is not a processor or FLAVOR
        !          6157:      is not recognized.  The function returns 'MIG_ARRAY_TOO_LARGE' if
        !          6158:      the returned info array is too large for PROCESSOR_INFO.  In this
        !          6159:      case, PROCESSOR_INFO is filled as much as possible and
        !          6160:      PROCESSOR_INFOCNT is set to the number of elements that would have
        !          6161:      been returned if there were enough room.
        !          6162: 
        !          6163:  -- Data type: struct processor_basic_info
        !          6164:      This structure is returned in PROCESSOR_INFO by the
        !          6165:      'processor_info' function and provides basic information about the
        !          6166:      processor.  You can cast a variable of type 'processor_info_t' to a
        !          6167:      pointer of this type if you provided it as the PROCESSOR_INFO
        !          6168:      parameter for the 'PROCESSOR_BASIC_INFO' flavor of
        !          6169:      'processor_info'.  It has the following members:
        !          6170: 
        !          6171:      'cpu_type_t cpu_type'
        !          6172:           cpu type
        !          6173: 
        !          6174:      'cpu_subtype_t cpu_subtype'
        !          6175:           cpu subtype
        !          6176: 
        !          6177:      'boolean_t running'
        !          6178:           is processor running?
        !          6179: 
        !          6180:      'int slot_num'
        !          6181:           slot number
        !          6182: 
        !          6183:      'boolean_t is_master'
        !          6184:           is this the master processor
        !          6185: 
        !          6186:  -- Data type: processor_basic_info_t
        !          6187:      This is a pointer to a 'struct processor_basic_info'.
        !          6188: 
        !          6189: 
        !          6190: File: mach.info,  Node: Device Interface,  Next: Kernel Debugger,  Prev: Processors and Processor Sets,  Up: Top
        !          6191: 
        !          6192: 10 Device Interface
        !          6193: *******************
        !          6194: 
        !          6195: The GNU Mach microkernel provides a simple device interface that allows
        !          6196: the user space programs to access the underlying hardware devices.  Each
        !          6197: device has a unique name, which is a string up to 127 characters long.
        !          6198: To open a device, the device master port has to be supplied.  The device
        !          6199: master port is only available through the bootstrap port.  Anyone who
        !          6200: has control over the device master port can use all hardware devices.
        !          6201: 
        !          6202:  -- Data type: device_t
        !          6203:      This is a 'mach_port_t' and used to hold the port name of a device
        !          6204:      port that represents the device.  Operations on the device are
        !          6205:      implemented as remote procedure calls to the device port.  Each
        !          6206:      device provides a sequence of records.  The length of a record is
        !          6207:      specific to the device.  Data can be transferred "out-of-line" or
        !          6208:      "in-line" (*note Memory::).
        !          6209: 
        !          6210:    All constants and functions in this chapter are defined in
        !          6211: 'device/device.h'.
        !          6212: 
        !          6213: * Menu:
        !          6214: 
        !          6215: * Device Reply Server::           Handling device reply messages.
        !          6216: * Device Open::                   Opening hardware devices.
        !          6217: * Device Close::                  Closing hardware devices.
        !          6218: * Device Read::                   Reading data from the device.
        !          6219: * Device Write::                  Writing data to the device.
        !          6220: * Device Map::                    Mapping devices into virtual memory.
        !          6221: * Device Status::                 Querying and manipulating a device.
        !          6222: * Device Filter::                 Filtering packets arriving on a device.
        !          6223: 
        !          6224: 
        !          6225: File: mach.info,  Node: Device Reply Server,  Next: Device Open,  Up: Device Interface
        !          6226: 
        !          6227: 10.1 Device Reply Server
        !          6228: ========================
        !          6229: 
        !          6230: Beside the usual synchronous interface, an asynchronous interface is
        !          6231: provided.  For this, the caller has to receive and handle the reply
        !          6232: messages separately from the function call.
        !          6233: 
        !          6234:  -- Function: boolean_t device_reply_server (msg_header_t *IN_MSG,
        !          6235:           msg_header_t *OUT_MSG)
        !          6236:      The function 'device_reply_server' is produced by the remote
        !          6237:      procedure call generator to handle a received message.  This
        !          6238:      function does all necessary argument handling, and actually calls
        !          6239:      one of the following functions: 'ds_device_open_reply',
        !          6240:      'ds_device_read_reply', 'ds_device_read_reply_inband',
        !          6241:      'ds_device_write_reply' and 'ds_device_write_reply_inband'.
        !          6242: 
        !          6243:      The IN_MSG argument is the message that has been received from the
        !          6244:      kernel.  The OUT_MSG is a reply message, but this is not used for
        !          6245:      this server.
        !          6246: 
        !          6247:      The function returns 'TRUE' to indicate that the message in
        !          6248:      question was applicable to this interface, and that the appropriate
        !          6249:      routine was called to interpret the message.  It returns 'FALSE' to
        !          6250:      indicate that the message did not apply to this interface, and that
        !          6251:      no other action was taken.
        !          6252: 
        !          6253: 
        !          6254: File: mach.info,  Node: Device Open,  Next: Device Close,  Prev: Device Reply Server,  Up: Device Interface
        !          6255: 
        !          6256: 10.2 Device Open
        !          6257: ================
        !          6258: 
        !          6259:  -- Function: kern_return_t device_open (mach_port_t MASTER_PORT,
        !          6260:           dev_mode_t MODE, dev_name_t NAME, device_t *DEVICE)
        !          6261:      The function 'device_open' opens the device NAME and returns a port
        !          6262:      to it in DEVICE.  The open count for the device is incremented by
        !          6263:      one.  If the open count was 0, the open handler for the device is
        !          6264:      invoked.
        !          6265: 
        !          6266:      MASTER_PORT must hold the master device port.  NAME specifies the
        !          6267:      device to open, and is a string up to 128 characters long.  MODE is
        !          6268:      the open mode.  It is a bitwise-or of the following constants:
        !          6269: 
        !          6270:      'D_READ'
        !          6271:           Request read access for the device.
        !          6272: 
        !          6273:      'D_WRITE'
        !          6274:           Request write access for the device.
        !          6275: 
        !          6276:      'D_NODELAY'
        !          6277:           Do not delay an open.
        !          6278: 
        !          6279:      The function returns 'D_SUCCESS' if the device was successfully
        !          6280:      opened, 'D_INVALID_OPERATION' if MASTER_PORT is not the master
        !          6281:      device port, 'D_WOULD_BLOCK' is the device is busy and 'D_NOWAIT'
        !          6282:      was specified in mode, 'D_ALREADY_OPEN' if the device is already
        !          6283:      open in an incompatible mode and 'D_NO_SUCH_DEVICE' if NAME does
        !          6284:      not denote a know device.
        !          6285: 
        !          6286:  -- Function: kern_return_t device_open_request
        !          6287:           (mach_port_t MASTER_PORT, mach_port_t REPLY_PORT,
        !          6288:           dev_mode_t MODE, dev_name_t NAME)
        !          6289:  -- Function: kern_return_t ds_device_open_reply
        !          6290:           (mach_port_t REPLY_PORT, kern_return_t RETURN,
        !          6291:           device_t *DEVICE)
        !          6292:      This is the asynchronous form of the 'device_open' function.
        !          6293:      'device_open_request' performs the open request.  The meaning for
        !          6294:      the parameters is as in 'device_open'.  Additionally, the caller
        !          6295:      has to supply a reply port to which the 'ds_device_open_reply'
        !          6296:      message is sent by the kernel when the open has been performed.
        !          6297:      The return value of the open operation is stored in RETURN_CODE.
        !          6298: 
        !          6299:      As neither function receives a reply message, only message
        !          6300:      transmission errors apply.  If no error occurs, 'KERN_SUCCESS' is
        !          6301:      returned.
        !          6302: 
        !          6303: 
        !          6304: File: mach.info,  Node: Device Close,  Next: Device Read,  Prev: Device Open,  Up: Device Interface
        !          6305: 
        !          6306: 10.3 Device Close
        !          6307: =================
        !          6308: 
        !          6309:  -- Function: kern_return_t device_close (device_t DEVICE)
        !          6310:      The function 'device_close' decrements the open count of the device
        !          6311:      by one.  If the open count drops to zero, the close handler for the
        !          6312:      device is called.  The device to close is specified by its port
        !          6313:      DEVICE.
        !          6314: 
        !          6315:      The function returns 'D_SUCCESS' if the device was successfully
        !          6316:      closed and 'D_NO_SUCH_DEVICE' if DEVICE does not denote a device
        !          6317:      port.
        !          6318: 
        !          6319: 
        !          6320: File: mach.info,  Node: Device Read,  Next: Device Write,  Prev: Device Close,  Up: Device Interface
        !          6321: 
        !          6322: 10.4 Device Read
        !          6323: ================
        !          6324: 
        !          6325:  -- Function: kern_return_t device_read (device_t DEVICE,
        !          6326:           dev_mode_t MODE, recnum_t RECNUM, int BYTES_WANTED,
        !          6327:           io_buf_ptr_t *DATA, mach_msg_type_number_t *DATA_COUNT)
        !          6328:      The function 'device_read' reads BYTES_WANTED bytes from DEVICE,
        !          6329:      and stores them in a buffer allocated with 'vm_allocate', which
        !          6330:      address is returned in DATA.  The caller must deallocated it if it
        !          6331:      is no longer needed.  The number of bytes actually returned is
        !          6332:      stored in DATA_COUNT.
        !          6333: 
        !          6334:      If MODE is 'D_NOWAIT', the operation does not block.  Otherwise
        !          6335:      MODE should be 0.  RECNUM is the record number to be read, its
        !          6336:      meaning is device specific.
        !          6337: 
        !          6338:      The function returns 'D_SUCCESS' if some data was successfully
        !          6339:      read, 'D_WOULD_BLOCK' if no data is currently available and
        !          6340:      'D_NOWAIT' is specified, and 'D_NO_SUCH_DEVICE' if DEVICE does not
        !          6341:      denote a device port.
        !          6342: 
        !          6343:  -- Function: kern_return_t device_read_inband (device_t DEVICE,
        !          6344:           dev_mode_t MODE, recnum_t RECNUM, int BYTES_WANTED,
        !          6345:           io_buf_ptr_inband_t *DATA, mach_msg_type_number_t *DATA_COUNT)
        !          6346:      The 'device_read_inband' function works as the 'device_read'
        !          6347:      function, except that the data is returned "in-line" in the reply
        !          6348:      IPC message (*note Memory::).
        !          6349: 
        !          6350:  -- Function: kern_return_t device_read_request (device_t DEVICE,
        !          6351:           mach_port_t REPLY_PORT, dev_mode_t MODE, recnum_t RECNUM,
        !          6352:           int BYTES_WANTED)
        !          6353:  -- Function: kern_return_t ds_device_read_reply
        !          6354:           (mach_port_t REPLY_PORT, kern_return_t RETURN_CODE,
        !          6355:           io_buf_ptr_t DATA, mach_msg_type_number_t DATA_COUNT)
        !          6356:      This is the asynchronous form of the 'device_read' function.
        !          6357:      'device_read_request' performs the read request.  The meaning for
        !          6358:      the parameters is as in 'device_read'.  Additionally, the caller
        !          6359:      has to supply a reply port to which the 'ds_device_read_reply'
        !          6360:      message is sent by the kernel when the read has been performed.
        !          6361:      The return value of the read operation is stored in RETURN_CODE.
        !          6362: 
        !          6363:      As neither function receives a reply message, only message
        !          6364:      transmission errors apply.  If no error occurs, 'KERN_SUCCESS' is
        !          6365:      returned.
        !          6366: 
        !          6367:  -- Function: kern_return_t device_read_request_inband (device_t DEVICE,
        !          6368:           mach_port_t REPLY_PORT, dev_mode_t MODE, recnum_t RECNUM,
        !          6369:           int BYTES_WANTED)
        !          6370:  -- Function: kern_return_t ds_device_read_reply_inband
        !          6371:           (mach_port_t REPLY_PORT, kern_return_t RETURN_CODE,
        !          6372:           io_buf_ptr_t DATA, mach_msg_type_number_t DATA_COUNT)
        !          6373:      The 'device_read_request_inband' and 'ds_device_read_reply_inband'
        !          6374:      functions work as the 'device_read_request' and
        !          6375:      'ds_device_read_reply' functions, except that the data is returned
        !          6376:      "in-line" in the reply IPC message (*note Memory::).
        !          6377: 
        !          6378: 
        !          6379: File: mach.info,  Node: Device Write,  Next: Device Map,  Prev: Device Read,  Up: Device Interface
        !          6380: 
        !          6381: 10.5 Device Write
        !          6382: =================
        !          6383: 
        !          6384:  -- Function: kern_return_t device_write (device_t DEVICE,
        !          6385:           dev_mode_t MODE, recnum_t RECNUM, io_buf_ptr_t DATA,
        !          6386:           mach_msg_type_number_t DATA_COUNT, int *BYTES_WRITTEN)
        !          6387:      The function 'device_write' writes DATA_COUNT bytes from the buffer
        !          6388:      DATA to DEVICE.  The number of bytes actually written is returned
        !          6389:      in BYTES_WRITTEN.
        !          6390: 
        !          6391:      If MODE is 'D_NOWAIT', the function returns without waiting for I/O
        !          6392:      completion.  Otherwise MODE should be 0.  RECNUM is the record
        !          6393:      number to be written, its meaning is device specific.
        !          6394: 
        !          6395:      The function returns 'D_SUCCESS' if some data was successfully
        !          6396:      written and 'D_NO_SUCH_DEVICE' if DEVICE does not denote a device
        !          6397:      port or the device is dead or not completely open.
        !          6398: 
        !          6399:  -- Function: kern_return_t device_write_inband (device_t DEVICE,
        !          6400:           dev_mode_t MODE, recnum_t RECNUM, int BYTES_WANTED,
        !          6401:           io_buf_ptr_inband_t *DATA, mach_msg_type_number_t *DATA_COUNT)
        !          6402:      The 'device_write_inband' function works as the 'device_write'
        !          6403:      function, except that the data is sent "in-line" in the request IPC
        !          6404:      message (*note Memory::).
        !          6405: 
        !          6406:  -- Function: kern_return_t device_write_request (device_t DEVICE,
        !          6407:           mach_port_t REPLY_PORT, dev_mode_t MODE, recnum_t RECNUM,
        !          6408:           io_buf_ptr_t DATA, mach_msg_type_number_t DATA_COUNT)
        !          6409:  -- Function: kern_return_t ds_device_write_reply
        !          6410:           (mach_port_t REPLY_PORT, kern_return_t RETURN_CODE,
        !          6411:           int BYTES_WRITTEN)
        !          6412:      This is the asynchronous form of the 'device_write' function.
        !          6413:      'device_write_request' performs the write request.  The meaning for
        !          6414:      the parameters is as in 'device_write'.  Additionally, the caller
        !          6415:      has to supply a reply port to which the 'ds_device_write_reply'
        !          6416:      message is sent by the kernel when the write has been performed.
        !          6417:      The return value of the write operation is stored in RETURN_CODE.
        !          6418: 
        !          6419:      As neither function receives a reply message, only message
        !          6420:      transmission errors apply.  If no error occurs, 'KERN_SUCCESS' is
        !          6421:      returned.
        !          6422: 
        !          6423:  -- Function: kern_return_t device_write_request_inband
        !          6424:           (device_t DEVICE, mach_port_t REPLY_PORT, dev_mode_t MODE,
        !          6425:           recnum_t RECNUM, io_buf_ptr_t DATA,
        !          6426:           mach_msg_type_number_t DATA_COUNT)
        !          6427:  -- Function: kern_return_t ds_device_write_reply_inband
        !          6428:           (mach_port_t REPLY_PORT, kern_return_t RETURN_CODE,
        !          6429:           int BYTES_WRITTEN)
        !          6430:      The 'device_write_request_inband' and
        !          6431:      'ds_device_write_reply_inband' functions work as the
        !          6432:      'device_write_request' and 'ds_device_write_reply' functions,
        !          6433:      except that the data is sent "in-line" in the request IPC message
        !          6434:      (*note Memory::).
        !          6435: 
        !          6436: 
        !          6437: File: mach.info,  Node: Device Map,  Next: Device Status,  Prev: Device Write,  Up: Device Interface
        !          6438: 
        !          6439: 10.6 Device Map
        !          6440: ===============
        !          6441: 
        !          6442:  -- Function: kern_return_t device_map (device_t DEVICE, vm_prot_t PROT,
        !          6443:           vm_offset_t OFFSET, vm_size_t SIZE, mach_port_t *PAGER,
        !          6444:           int UNMAP)
        !          6445:      The function 'device_map' creates a new memory manager for DEVICE
        !          6446:      and returns a port to it in PAGER.  The memory manager is usable as
        !          6447:      a memory object in a 'vm_map' call.  The call is device dependent.
        !          6448: 
        !          6449:      The protection for the memory object is specified by PROT.  The
        !          6450:      memory object starts at OFFSET within the device and extends SIZE
        !          6451:      bytes.  UNMAP is currently unused.
        !          6452: 
        !          6453:      The function returns 'D_SUCCESS' if some data was successfully
        !          6454:      written and 'D_NO_SUCH_DEVICE' if DEVICE does not denote a device
        !          6455:      port or the device is dead or not completely open.
        !          6456: 
        !          6457: 
        !          6458: File: mach.info,  Node: Device Status,  Next: Device Filter,  Prev: Device Map,  Up: Device Interface
        !          6459: 
        !          6460: 10.7 Device Status
        !          6461: ==================
        !          6462: 
        !          6463:  -- Function: kern_return_t device_set_status (device_t DEVICE,
        !          6464:           dev_flavor_t FLAVOR, dev_status_t STATUS,
        !          6465:           mach_msg_type_number_t STATUS_COUNT)
        !          6466:      The function 'device_set_status' sets the status of a device.  The
        !          6467:      possible values for FLAVOR and their interpretation is device
        !          6468:      specific.
        !          6469: 
        !          6470:      The function returns 'D_SUCCESS' if some data was successfully
        !          6471:      written and 'D_NO_SUCH_DEVICE' if DEVICE does not denote a device
        !          6472:      port or the device is dead or not completely open.
        !          6473: 
        !          6474:  -- Function: kern_return_t device_get_status (device_t DEVICE,
        !          6475:           dev_flavor_t FLAVOR, dev_status_t STATUS,
        !          6476:           mach_msg_type_number_t *STATUS_COUNT)
        !          6477:      The function 'device_get_status' gets the status of a device.  The
        !          6478:      possible values for FLAVOR and their interpretation is device
        !          6479:      specific.
        !          6480: 
        !          6481:      The function returns 'D_SUCCESS' if some data was successfully
        !          6482:      written and 'D_NO_SUCH_DEVICE' if DEVICE does not denote a device
        !          6483:      port or the device is dead or not completely open.
        !          6484: 
        !          6485: 
        !          6486: File: mach.info,  Node: Device Filter,  Prev: Device Status,  Up: Device Interface
        !          6487: 
        !          6488: 10.8 Device Filter
        !          6489: ==================
        !          6490: 
        !          6491:  -- Function: kern_return_t device_set_filter (device_t DEVICE,
        !          6492:           mach_port_t RECEIVE_PORT,
        !          6493:           mach_msg_type_name_t RECEIVE_PORT_TYPE, int PRIORITY,
        !          6494:           filter_array_t FILTER, mach_msg_type_number_t FILTER_COUNT)
        !          6495:      The function 'device_set_filter' makes it possible to filter out
        !          6496:      selected data arriving at or leaving the device and forward it to a
        !          6497:      port.  FILTER is a list of filter commands, which are applied to
        !          6498:      incoming data to determine if the data should be sent to
        !          6499:      RECEIVE_PORT.  The IPC type of the send right is specified by
        !          6500:      RECEIVE_PORT_RIGHT, it is either 'MACH_MSG_TYPE_MAKE_SEND' or
        !          6501:      'MACH_MSG_TYPE_MOVE_SEND'.  The PRIORITY value is used to order
        !          6502:      multiple filters.
        !          6503: 
        !          6504:      There can be up to 'NET_MAX_FILTER' commands in FILTER.  The actual
        !          6505:      number of commands is passed in FILTER_COUNT.  For the purpose of
        !          6506:      the filter test, an internal stack is provided.  After all commands
        !          6507:      have been processed, the value on the top of the stack determines
        !          6508:      if the data is forwarded or the next filter is tried.
        !          6509: 
        !          6510:      The first command is a header which contains two fields: one for
        !          6511:      flags and the other for the type of interpreter used to run the
        !          6512:      rest of the commands.
        !          6513: 
        !          6514:      Any combination of the following flags is allowed but at least one
        !          6515:      of them must be specified.
        !          6516: 
        !          6517:      'NETF_IN'
        !          6518:           The filter will be applied to data received by the device.
        !          6519: 
        !          6520:      'NETF_OUT'
        !          6521:           The filter will be applied to data transmitted by the device.
        !          6522: 
        !          6523:      Unless the type is given explicitly the native NETF interpreter
        !          6524:      will be used.  To select an alternative implementation use one of
        !          6525:      the following types:
        !          6526: 
        !          6527:      'NETF_BPF'
        !          6528:           Use Berkeley Packet Filter.
        !          6529: 
        !          6530:      For the listener to know what kind of packet is being received,
        !          6531:      when the filter code accepts a packet the message sent to
        !          6532:      RECEIVE_PORT is tagged with either NETF_IN or NETF_OUT.
        !          6533: 
        !          6534:      Each word of the command list specifies a data (push) operation
        !          6535:      (high order NETF_NBPO bits) as well as a binary operator (low order
        !          6536:      NETF_NBPA bits).  The value to be pushed onto the stack is chosen
        !          6537:      as follows.
        !          6538: 
        !          6539:      'NETF_PUSHLIT'
        !          6540:           Use the next short word of the filter as the value.
        !          6541: 
        !          6542:      'NETF_PUSHZERO'
        !          6543:           Use 0 as the value.
        !          6544: 
        !          6545:      'NETF_PUSHWORD+N'
        !          6546:           Use short word N of the "data" portion of the message as the
        !          6547:           value.
        !          6548: 
        !          6549:      'NETF_PUSHHDR+N'
        !          6550:           Use short word N of the "header" portion of the message as the
        !          6551:           value.
        !          6552: 
        !          6553:      'NETF_PUSHIND+N'
        !          6554:           Pops the top long word from the stack and then uses short word
        !          6555:           N of the "data" portion of the message as the value.
        !          6556: 
        !          6557:      'NETF_PUSHHDRIND+N'
        !          6558:           Pops the top long word from the stack and then uses short word
        !          6559:           N of the "header" portion of the message as the value.
        !          6560: 
        !          6561:      'NETF_PUSHSTK+N'
        !          6562:           Use long word N of the stack (where the top of stack is long
        !          6563:           word 0) as the value.
        !          6564: 
        !          6565:      'NETF_NOPUSH'
        !          6566:           Don't push a value.
        !          6567: 
        !          6568:      The unsigned value so chosen is promoted to a long word before
        !          6569:      being pushed.  Once a value is pushed (except for the case of
        !          6570:      'NETF_NOPUSH'), the top two long words of the stack are popped and
        !          6571:      a binary operator applied to them (with the old top of stack as the
        !          6572:      second operand).  The result of the operator is pushed on the
        !          6573:      stack.  These operators are:
        !          6574: 
        !          6575:      'NETF_NOP'
        !          6576:           Don't pop off any values and do no operation.
        !          6577: 
        !          6578:      'NETF_EQ'
        !          6579:           Perform an equal comparison.
        !          6580: 
        !          6581:      'NETF_LT'
        !          6582:           Perform a less than comparison.
        !          6583: 
        !          6584:      'NETF_LE'
        !          6585:           Perform a less than or equal comparison.
        !          6586: 
        !          6587:      'NETF_GT'
        !          6588:           Perform a greater than comparison.
        !          6589: 
        !          6590:      'NETF_GE'
        !          6591:           Perform a greater than or equal comparison.
        !          6592: 
        !          6593:      'NETF_AND'
        !          6594:           Perform a bitise boolean AND operation.
        !          6595: 
        !          6596:      'NETF_OR'
        !          6597:           Perform a bitise boolean inclusive OR operation.
        !          6598: 
        !          6599:      'NETF_XOR'
        !          6600:           Perform a bitise boolean exclusive OR operation.
        !          6601: 
        !          6602:      'NETF_NEQ'
        !          6603:           Perform a not equal comparison.
        !          6604: 
        !          6605:      'NETF_LSH'
        !          6606:           Perform a left shift operation.
        !          6607: 
        !          6608:      'NETF_RSH'
        !          6609:           Perform a right shift operation.
        !          6610: 
        !          6611:      'NETF_ADD'
        !          6612:           Perform an addition.
        !          6613: 
        !          6614:      'NETF_SUB'
        !          6615:           Perform a subtraction.
        !          6616: 
        !          6617:      'NETF_COR'
        !          6618:           Perform an equal comparison.  If the comparison is 'TRUE',
        !          6619:           terminate the filter list.  Otherwise, pop the result of the
        !          6620:           comparison off the stack.
        !          6621: 
        !          6622:      'NETF_CAND'
        !          6623:           Perform an equal comparison.  If the comparison is 'FALSE',
        !          6624:           terminate the filter list.  Otherwise, pop the result of the
        !          6625:           comparison off the stack.
        !          6626: 
        !          6627:      'NETF_CNOR'
        !          6628:           Perform a not equal comparison.  If the comparison is 'FALSE',
        !          6629:           terminate the filter list.  Otherwise, pop the result of the
        !          6630:           comparison off the stack.
        !          6631: 
        !          6632:      'NETF_CNAND'
        !          6633:           Perform a not equal comparison.  If the comparison is 'TRUE',
        !          6634:           terminate the filter list.  Otherwise, pop the result of the
        !          6635:           comparison off the stack.  The scan of the filter list
        !          6636:           terminates when the filter list is emptied, or a 'NETF_C...'
        !          6637:           operation terminates the list.  At this time, if the final
        !          6638:           value of the top of the stack is 'TRUE', then the message is
        !          6639:           accepted for the filter.
        !          6640: 
        !          6641:      The function returns 'D_SUCCESS' if some data was successfully
        !          6642:      written, 'D_INVALID_OPERATION' if RECEIVE_PORT is not a valid send
        !          6643:      right, and 'D_NO_SUCH_DEVICE' if DEVICE does not denote a device
        !          6644:      port or the device is dead or not completely open.
        !          6645: 
        !          6646: 
        !          6647: File: mach.info,  Node: Kernel Debugger,  Next: Copying,  Prev: Device Interface,  Up: Top
        !          6648: 
        !          6649: 11 Kernel Debugger
        !          6650: ******************
        !          6651: 
        !          6652: The GNU Mach kernel debugger 'ddb' is a powerful built-in debugger with
        !          6653: a gdb like syntax.  It is enabled at compile time using the
        !          6654: '--enable-kdb' option.  Whenever you want to enter the debugger while
        !          6655: running the kernel, you can press the key combination <Ctrl-Alt-D>.
        !          6656: 
        !          6657: * Menu:
        !          6658: 
        !          6659: * Operation::                     Basic architecture of the kernel debugger.
        !          6660: * Commands::                      Available commands in the kernel debugger.
        !          6661: * Variables::                     Access of variables from the kernel debugger.
        !          6662: * Expressions::                   Usage of expressions in the kernel debugger.
        !          6663: 
        !          6664: 
        !          6665: File: mach.info,  Node: Operation,  Next: Commands,  Up: Kernel Debugger
        !          6666: 
        !          6667: 11.1 Operation
        !          6668: ==============
        !          6669: 
        !          6670: The current location is called "dot".  The dot is displayed with a
        !          6671: hexadecimal format at a prompt.  Examine and write commands update dot
        !          6672: to the address of the last line examined or the last location modified,
        !          6673: and set "next" to the address of the next location to be examined or
        !          6674: changed.  Other commands don't change dot, and set next to be the same
        !          6675: as dot.
        !          6676: 
        !          6677:    The general command syntax is:
        !          6678: 
        !          6679:      COMMAND[/MODIFIER] ADDRESS [,COUNT]
        !          6680: 
        !          6681:    '!!' repeats the previous command, and a blank line repeats from the
        !          6682: address next with count 1 and no modifiers.  Specifying ADDRESS sets dot
        !          6683: to the address.  Omitting ADDRESS uses dot.  A missing COUNT is taken to
        !          6684: be 1 for printing commands or infinity for stack traces.
        !          6685: 
        !          6686:    Current 'ddb' is enhanced to support multi-thread debugging.  A break
        !          6687: point can be set only for a specific thread, and the address space or
        !          6688: registers of non current thread can be examined or modified if supported
        !          6689: by machine dependent routines.  For example,
        !          6690: 
        !          6691:      break/t mach_msg_trap $task11.0
        !          6692: 
        !          6693:    sets a break point at 'mach_msg_trap' for the first thread of task 11
        !          6694: listed by a 'show all threads' command.
        !          6695: 
        !          6696:    In the above example, '$task11.0' is translated to the corresponding
        !          6697: thread structure's address by variable translation mechanism described
        !          6698: later.  If a default target thread is set in a variable '$thread', the
        !          6699: '$task11.0' can be omitted.  In general, if 't' is specified in a
        !          6700: modifier of a command line, a specified thread or a default target
        !          6701: thread is used as a target thread instead of the current one.  The 't'
        !          6702: modifier in a command line is not valid in evaluating expressions in a
        !          6703: command line.  If you want to get a value indirectly from a specific
        !          6704: thread's address space or access to its registers within an expression,
        !          6705: you have to specify a default target thread in advance, and to use ':t'
        !          6706: modifier immediately after the indirect access or the register reference
        !          6707: like as follows:
        !          6708: 
        !          6709:      set $thread $task11.0
        !          6710:      print $eax:t *(0x100):tuh
        !          6711: 
        !          6712:    No sign extension and indirection 'size(long, half word, byte)' can
        !          6713: be specified with 'u', 'l', 'h' and 'b' respectively for the indirect
        !          6714: access.
        !          6715: 
        !          6716:    Note: Support of non current space/register access and user space
        !          6717: break point depend on the machines.  If not supported, attempts of such
        !          6718: operation may provide incorrect information or may cause strange
        !          6719: behavior.  Even if supported, the user space access is limited to the
        !          6720: pages resident in the main memory at that time.  If a target page is not
        !          6721: in the main memory, an error will be reported.
        !          6722: 
        !          6723:    'ddb' has a feature like a command 'more' for the output.  If an
        !          6724: output line exceeds the number set in the '$lines' variable, it displays
        !          6725: '--db_more--' and waits for a response.  The valid responses for it are:
        !          6726: 
        !          6727: '<SPC>'
        !          6728:      one more page
        !          6729: 
        !          6730: '<RET>'
        !          6731:      one more line
        !          6732: 
        !          6733: 'q'
        !          6734:      abort the current command, and return to the command input mode
        !          6735: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.