Copyright (c) 1993 Xerox Corporation.  All rights reserved.
TODO:
- sigsetjmp nyi
- the PCR←IO←gfdLim and PCR←IOGblUFSImpl←openFileMax stuff in
  PCR←IOGblUFSImpl←Setup needs to become OS dependent?!
- There is no fcntl/ioctl implementation in PCR←IOGblUFSImpl.c!!!
- What is the organization for optional things? e.g. sockets?
    seems like the simplest thing is to make the header file
    break if not defined(PCR←NO←HOSTDEP←ERR).
    A special subdir hostdep behaves like ansi and posix,
    has includes that may or may not be implemented.
- Emulation for non-blocking I/O ?????
- think about which signals cannot be caught and by whom?
- There is no implementation of advisory record locking yet.
- the typical cc include file mechanism picks up the wrong file
    when host include files include what should be other host include 
    files.  Often a PCR include file will be used, instead.
- need a way to start pcr that displays help for its supported switches

SIGNAL STUFF TODO:
  fix default handler to do sanity checks
  
- Does the PCR implementation get to use the string compare procs
  under their usual names?  This is probably safe in most
  implementations, but I do have a bit of exposure here.

What is it?
- Threads (preemptive prio sched)
  dyload (commit/abort),
  GC (conservative, useful for C).
- Thread-safe ANSI C library.
- POSIX.1 compliant ANSI C programs run as threads.
  This implies a certain amount of state -- working
  directory, (some) file descriptors, local data for some C library
  procedures, etc. -- must be kept per-thread. 
- Source-level POSIX.1 implementation, client code must be compiled
  with special PCR header files.
- Renaming => must include files for all POSIX symbols referenced or things
  break.  Use dyloading to develop code.


PCR←ERes and PCR←GetErrno()
The model of signal interaction
  res = PCR←Foo(...,PCR←sigset←t *sigMask, PCR←MSecs wakeup) interpretation of
  the sigMask and wakeup parameters
Externally generated signals caught by high-priority thread
  that redistributes them as required.

Naming conventions for PCR identifiers, files, ...

Startup
- main is in a client routine *not* compiled with symbol translation
  turned on in the pcr headers?  What is the client entitled to do?
- PCR←BaseArgs used to split/interpret args

List of Public Interfaces with brief explanation of each ...
  ansi, base, cmd, config, dbg, emu, il, mm, sig, th, vd
  Base
    Startup, some other utilities that pertain to the entire PCR
    world.
    Optional(?) utilities for parsing Unix-like command lines.
  Cmd
    Optional.  No setup.
    Implementation of a simple command interpreter for use with
    dyload, etc.
  Config
    Not directly used by clients.
    Configuration stuff for porting between architectures and
      operating systems.
  Dbg
    I don't know what to do about this one.  It is a trivial interface,
    but if there's going to be a Cirio-like thing, there will have to be
    something like this institutionalized.
  Emu
    Not directly used by clients.
    Implementations of PCR emulations of POSIX, ANSI, and hostdep stuff.
  Exec
    Uses a process forked at pcr startup to exec other host applications.
    Starting pcr with the -noexec option prevents the server process from being
    forked (and of course, suppresses the ability to do the exec operations).
  IL
    Incremental loader.  (Can this be made optional?)
    Discussion of loader lock; symbol binding; commit/abort.
    ??? discussion somewhere of how to write a file reader ???
  IO
    Input/Output.  Here we need to explain the difference between
    local and global descriptors.  Ugh.
  MM
    Allocation / memory management.  Same interface whether or not the GC
    is included.  Without a GC, PCR itself leaks memory a bit.
  Sig
    Some signal IDs and types, plus the interface used to catch externally
    generated signals.  
  Th
    Threads stuff.  Note ThCtl and ThUWProt.  (Here's something that depends
    on setjmp.h!)  Per-thread signals are here.
  VD
    Not directly used by clients.
    Virtual dirty bits, used by GC.


Introduction

    This is PPCR, (POSIX Portable Common Runtime), a completely new
implementation of the Xerox Portable Common Runtime described in [???].
Unlike the original, it is intended (and believed) to be lightweight
and portable enough for use by mere mortals.  PPCR consists of:

    A lightweight threads package with preemptive priority scheduler.
    Threads behave sensibly with respect to I/O and blocking (emulated)
    system calls -- the thread invoking the operation may block,
    but other threads continue to run.

    A dynamic object code (re-)loading facility, with client access
    to runtime symbol tables.

    A conservative (hence non-copying), mostly-parallel (hence nearly
    real-time) garbage collector based on the work described in [xx],
    [yy], [zz].  We routinely use this collector on hand-written C
    code as well as on the C code produced by our Cedar compiler.

    Miscellaneous other creature comforts.

The "POSIX" refers to refers to POSIX.1 (IEEE Std 1003.1-1990 [??]), not
(yet) the IEEE Realtime Extensions [??] or PThreads [??] efforts.  PPCR
relates to POSIX.1 in two ways:

    As a client: PPCR should be easily portable to any (32-bit, byte-
    addressed) system providing POSIX.1 and a very minimal set of
    extensions.  PPCR is written in ANSI C, assuming the Multiple
    External Definitions extension defined in Section F.5.11 of the
    ANSI C definition [??], and assuming reasonably long case-
    sensitive external symbols. It is compatible with version 2.1
    the gnu C compiler.


    As an implementation: PPCR provides a nearly exact ANSI C POSIX.1
    environment for each thread independently.  That is, multiple POSIX.1
    compliant (ANSI) C programs can run without source changes as
    separate threads in the same PPCR world, without interfering with
    one another.  In particular, PPCR includes (nearly) complete
    thread-safe POSIX.1 emulation and ANSI C libraries.  To make this
    work, PPCR maintains considerable state (e.g. the current working
    directory, (some) file descriptors, local data for certain library
    procedures) on a per-thread basis.
    
    Note that POSIX.1 is a source code standard, not an object code
    standard.  PPCR provides its own set of {ANSI,POSIX} header files.
    Code to be run inside PPCR must be compiled using these files;
    otherwise it will not work and is likely to crash PPCR.

Organization

  Organization
  
    PPCR consists of a number of components, some of which are
    optional or host-dependent.  Each component occupies a
    separate subdirectory of the distribution directory.
  
  Naming conventions
  
    To make up (in part) for the lack of qualified names in C and Unix,
    PPCR adheres to a strict set of naming conventions for files
    and global variables:
    
    Every (file or variable) name within PPCR begins with the
    4-character sequence "PCR←".  Consequently, client programs
    should avoid such names.  (Already this means PPCR is not
    quite POSIX compliant, but we believe the number of programs
    that will break because of this name space restriction is
    acceptably small).
    
    The next few letters of a file name usually identify the component
    (subdirectory) containing the file.  For example, PCR←Th.h is
    in the th (threads) component, while PCR←IOLcl.h is in the io
    component.

    A C identifier with file or global scope will usually begin with an
    indication of its declaring (header or implementation) file, followed
    by an underscore.  For example, the procedure PCR←IOGbl←FPathConf
    is declared  in io/PCR←IOGbl.h, and defined in io/PCR←IOGblImpl.c;
    while the static variable PCR←IOGblUFSImpl←methods is both declared
    and defined in io/PCR←IOGblUFSImpl.c.

    Usually an initial uppercase letter indicates a type or procedure
    name (so an initial lowercase letter indicates a variable or
    constant name).  For example, PCR←Th←Fork is a procedure, PCR←Th←CV
    is a type, and PCR←Th←CV←null is a constant of that type.  An
    important departure from this convention is names that are part
    of the ANSI or POSIX.1 standards.  These are renamed by prepending
    "PCR←" with no other change.  For example, the PPCR fcntl.h header
    file renames open to PCR←open (using #define).

  The ansi directory
  
    This contains PPCR versions of all the standard ANSI header files.
    In most cases these files use the C preprocessor to rename symbols
    (e.g. strtok becomes PCR←strtok) unless the preprocessor variable
    PCR←NO←RENAME is set.  This trick allows PPCR to be both a client and
    an implementation of the ANSI library, enabling thread-safe versions
    of many procedures to be implemented in terms of their host-provided
    (possibly thread-unsafe) versions.

  The posix directory

    This contains PPCR versions of all the standard POSIX.1 header files.
    In most cases these #include the corresponding header files of the
    host OS and do preprocessor tricks to rename symbols (e.g. open
    becomes PCR←open) unless the preprocessor variable PCR←NO←RENAME
    is set.  This trick enables PPCR to be both a client and an
    implementation of the POSIX.1 interface, as described above for
    the ANSI library.

  The hostdep directory
  
    This directory contains PPCR header files for features that are
    not ANSI or POSIX mandated, and are host-dependent or may be
    unimplemented on some hosts.

  The hostansi directory
  
    This is a symbolic link to the directory containing the ANSI include
    files provided with the host OS.

  The hostposix directory
  
    This is a symbolic link to the directory containing the POSIX.1 include
    files provided with the host OS.

  The threads directory

    This is a major component of PPCR.  It includes several public or
    semi-public interfaces:

    PCR←Th.h
    
      Types and operations for dealing with

        threads
        monitor locks and conditions
        timeouts
        asynchronous signals

      are defined here.
      
    PCR←ThUWProt.h
    PCR←ThDynEnv.h
    
      ??? Two different interfaces that support unwinding of stacks.
      They don't (yet) know about one another.  PCR←ThDynEnv.h supports
      a general dynamic environment, including other data in addition
      to just unwind protection.  PCR←ThUWProt.h interacts correctly with
      calls to setjmp()/longjmp().  

    PCR←ThCtl.h
    
      An interface to allow threads to exercise control over other threads.
      This is primarily for use by the garbage collector, but other clients
      can use it as well.
      
    PCR←ThData.h
    
      An interface to support arbitrary per-thread data.  This makes
      special provision for the PPCR builtin ANSI/POSIX emulations; other
      clients need to cooperate, at least to the extent of knowing about
      one another's index values.  ??? Possibly this should be fixed ???
    
  The base subdirectory
  
    This directory contains the PPCR startup procedure and some utilities
    that pertain to the entire PPCR world. 
    
    PCR←Base.h

      Procedures to start and terminate the entire PPCR world.

    PCR←BaseArgs.h

      Procedures that enable client threads to access command-line
      arguments supplied to PPCR.

  The config directory
  
    This directory contains OS and architecture configuration information,
    plus some ubiquitous datatypes and their associated operations.

    PCR←Arch.h
    
      Identification and description of the host architecture:
      word size, big-endian or little-endian, etc.
      
    PCR←OS.h
    
      Identification of the host OS, plus description of those areas
      where PPCR's use of it deviates from strict POSIX compliance.

    PCR←StdDefs.h
    
      This file is included indirectly by nearly every PPCR header
      file.  It cointains two important definitions:

        PCR←Any, an arithmetic type capable of containing
          either a void * or a long without information loss.
          Defining this as a union type would have undesirable
          consequences (e.g. with respect to parameter passing)
          on some systems

        PCR←ERes, the result type of most PPCR "system calls."
          By convention, a nonnegative value is success of some
          kind, while a negative value is an error code.

      Arguably this file is mislocated, and it may move in the
      future.

  The dbg directory

    ??? I have no idea about this ???

  The emu directory

    This directory contains implementations of PPCR's ANSI and POSIX.1
    emulations.
    
    There is a complete ANSI C library, including compatible thread-safe
    and thread-unsafe versions of stdio.  There are emulations of all
    required POSIX.1 calls.
    
    Both the ANSI and POSIX emulations are basically clients of the
    rest of PPCR, and it can be built without including them.
    Per-thread state required for these emulations is maintained
    using the th/PCR←ThData.h package.

Installation / Portability

    ??? what makefile, sed, ld, cc ???
    C external symbol / common resolution rules
    Include file lookup rules ???
      If you don't have a -I... you're in trouble.
      If nested includes behave differently you're in trouble.