Added index entries.
authorMilind Bhandarkar <milind@cs.uiuc.edu>
Wed, 1 Nov 1995 21:16:23 +0000 (21:16 +0000)
committerMilind Bhandarkar <milind@cs.uiuc.edu>
Wed, 1 Nov 1995 21:16:23 +0000 (21:16 +0000)
doc/converse/cmi.tex
doc/converse/cpvmacros.tex
doc/converse/ldb.tex
doc/converse/manual.tex
doc/converse/msgmgr.tex
doc/converse/scheduler.tex
doc/converse/threads.tex

index e952bbb78ebfa61f29680c5fa600acd81ac566b4..3daf6c3b9803e836950d6ef83ca8a21daae34e97 100644 (file)
@@ -4,6 +4,7 @@
 \section{Initialization and Wrap-Up}
 
 \function{void ConverseInit(char *argv[])}
+\index{ConverseInit}
 \desc{This function initializes the machine interface. It should be
 called prior to any other Converse functions. 
 Multiple calls to this function in a process should
@@ -13,6 +14,7 @@ They would be utilized by \param{ConverseInit()} to initialize
 machine specific parameters such as number of processors.}
 
 \function{void ConverseExit(void)}
+\index{ConverseExit}
 \desc{This function frees the resources acquired by Converse and wraps up. 
 Any other Converse function should not be called after a call to this function.
 \note{It does not terminate the calling
@@ -25,23 +27,29 @@ process. A separate call to \param{exit()} is needed after
 
 
 \function {\#define CmiMsgHeaderSizeBytes}
+\index{CmiMsgHeaderSizeBytes}
 \desc{This constant, defined in {\tt converse.h}, denotes
 the size of the message header in bytes.}
  
 \function {void CmiSetHandler(int *MessageBuffer, int HandlerId)}
+\index{CmiSetHandler}
 \desc{This macro sets the handler field of a message to \param{HandlerId}.}
  
 \function {int CmiGetHandler(int *MessageBuffer)}
+\index{CmiGetHandler}
 \desc{This call returns the handler field of a message \param{MessageBuffer}.}
  
 \function {HANDLER CmiGetHandlerFunction(int *MessageBuffer)}
+\index{CmiGetHandlerFunction}
 \desc{This call returns the handler function pointer for a message 
 \param{MessageBuffer}. This
 usually involves looking up a table using the handler-id stored in
 the message header at the sending processor. HANDLER is defined as 
 {\tt typedef void (*HANDLER)(void *)} .}
+\index{HANDLER}
 
 \function {int CmiRegisterHandler(HANDLER HandlerFunction)}
+\index{CmiRegisterHandler}
 \desc{This call registers a message handler with the CMI and returns a
 handler index which can be subsequently used to specify the handler
 for a message. \note{This function should be called
@@ -55,6 +63,7 @@ stage of an application.}}
 
 \internal{
 \function{void *CmiGetSpecificMsg(int HandlerId)}
+\index{CmiGetSpecificMsg}
 \desc{This call waits until a message for the specified handler is
 available, and returns a pointer to the message buffer. Ownership of
 the message buffer is maintained with the CMI (e.g. another call to
@@ -77,15 +86,18 @@ the message buffer.}
 
 
 \function{void CmiSyncSend(unsigned int destPE, unsigned int size, void *msg)}
+\index{CmiSyncSend}
 \desc{ Sends \param{msg} of size \param{size} bytes to processor
 \param{destPE}. Message buffer for \param{msg} could be reused after
 the call returns.}
 
 \function{void CmiSyncSendAndFree(unsigned int destPE, unsigned int size, void *msg)}
+\index{CmiSyncSendAndFree}
 \desc{ Sends \param{msg} of size \param{size} bytes to processor
 \param{destPE} and frees the message buffer for \param{msg}.}
 
 \function{CmiCommHandle CmiAsyncSend(unsigned int destPE, unsigned int size, void *msg)}
+\index{CmiAsyncSend}
 \desc{ Initiates an asynchronous send of \param{msg} of length
 \param{size} bytes to processor \param{destPE} and returns a
 communication handle which could be used to enquire the status of this
@@ -93,10 +105,12 @@ communication. Message buffer for \param{mesg} should not be reused or freed
 until communication is complete.}
 
 \function{int CmiAsyncMsgSent(CmiCommHandle handle)}
+\index{CmiAsyncMsgSent}
 \desc{Returns the status of asynchronous send specified by
 communication handle \param{handle}.}
 
 \function{void CmiReleaseCommHandle(CmiCommHandle handle)}
+\index{CmiReleaseCommHandle}
 \desc{ Releases the communication handle \param{handle} and
 associated resources. It does not free the message buffer.
 \param{handle} could be reused by CMI for another communication after
@@ -119,12 +133,14 @@ communication is complete.}
 }
 
 \function{void CmiGrabBuffer(void **pbuf)}
+\index{CmiGrabBuffer}
 \desc{ Transfers the ownership of the buffer pointed to by
 \param{*pbuf} to the calling procedure. If \param{*pbuf} points to a
 system buffer, CMI copies the buffer contents to newly allocated user
 space and updates \param{*pbuf} to point to the new buffer.}
 
 \function{int CmiDeliverMsgs(int MaxMsgs)}
+\index{CmiDeliverMsgs}
 \desc{ Retrieves messages from the network message queue and invokes 
 corresponding handler functions for arrived messages. This function 
 returns after either the network message queue becomes empty or after
@@ -136,6 +152,7 @@ CMI and the handler function should call \param{CmiGrabBuffer()} to
 acquire the message buffer.}
 
 \function{void CmiDeliverSpecificMsg(int HandlerId)}
+\index{CmiDeliverSpecificMsg}
 \desc{ Retrieves messages from the network queue and delivers the first message
 with its handler field equal to \param{HandlerId}. This functions queues
 the remaining messages retrieved from the network. It returns after the 
@@ -181,27 +198,32 @@ which could be used to  enquire about the status of this operation.}
 \section{Broadcast}
 
 \function{void CmiSyncBroadcast(unsigned int size, void *msg)}
+\index{CmiSyncBroadcast}
 \desc{Sends \param{msg} of length \param{size} bytes to all processors
 excluding the processor on which the caller resides. }
 
 \function{void CmiSyncBroadcastAndFree(unsigned int size, void *msg)}
+\index{CmiSyncBroadcastAndFree}
 \desc{Sends \param{msg} of length \param{size} bytes to all processors
 excluding the processor on which the caller resides. Frees the message buffer
 for \param{msg} when the broadcast completes. Therefore \param{msg} must
 point to a dynamically allocated buffer.}
 
 \function{void CmiSyncBroadcastAll(unsigned int size, void *msg)}
+\index{CmiSyncBroadcastAll}
 \desc{Sends \param{msg} of length \param{size} bytes to all processors
 including the processor on which the caller resides. This function
 does not free the message buffer for \param{msg}.}
 
 \function{void CmiSyncBroadcastAllAndFree(unsigned int size, void *msg)}
+\index{CmiSyncBroadcastAllAndFree}
 \desc{Sends \param{msg} of length \param{size} bytes to all processors
 including the processor on which the caller resides. This function
 frees the message buffer for \param{msg} before returning, so
 \param{msg} must point to a dynamically allocated buffer.}
 
 \function{CmiCommHandle CmiAsyncBroadcast(unsigned int size, void *msg)}
+\index{CmiAsyncBroadcast}
 \desc{ Initiates asynchronous broadcast of message \param{msg} of
 length \param{size} bytes to all processors excluding the processor on
 which the caller resides. It returns a communication handle which
@@ -210,6 +232,7 @@ could be used to check the status of this send using
 freed before the communication is complete.}
 
 \function{CmiCommHandle CmiAsyncBroadcastAll(unsigned int size, void *msg)}
+\index{CmiAsyncBroadcastAll}
 \desc{ Initiates asynchronous broadcast of message \param{msg} of
 length \param{size} bytes to all processors including the processor on
 which the caller resides. It returns a communication handle which
@@ -220,6 +243,7 @@ freed before the communication is complete.}
 \section{Timer}
 
 \function{double CmiTimer(void)}
+\index{CmiTimer}
 \desc{Returns current value of the timer in seconds. This is
 typically the time spent since the \param{ConverseInit()} call.
 The precision of this timer is the best available on the particular machine,
@@ -228,16 +252,19 @@ and usually has at least microsecond accuracy.}
 \section{Processor Ids}
 
 \function{int CmiNumPe(void)}
+\index{CmiNumPe}
 \desc{ Returns total number of processors in the machine on which the 
 parallel program is being run.}
 
 \function{int CmiMyPe(void)}
+\index{CmiMyPe}
 \desc{ Returns the logical processor identifier of processor on which the 
 caller resides. A processor Id is between \param{0} and \param{CmiNumPe()-1}.}
 
 \section{Memory Management}
 
 \function{void *CmiAlloc(int size)}
+\index{CmiAlloc}
 \desc{Allocates memory of size \param{size} in heap and returns pointer to 
 the usable space. All the converse entities (e.g. messages) should be 
 allocated with \param{CmiAlloc} and not with standard C library 
@@ -247,11 +274,13 @@ around \param{malloc}. However, in future, sophisticated memory allocation
 strategies will be incorporated into converse.}}
 
 \function{int CmiSize(void *ptr)}
+\index{CmiSize}
 \desc{This function returns the allocated size of memory pointed to by 
 \param{ptr}. \param{ptr} should be returned by an earlier call to 
 \param{CmiAlloc}.}
 
 \function{void CmiFree(void *ptr)}
+\index{CmiFree}
 \desc{This function frees the memory pointed to by \param{ptr}. \param{ptr}
 should be returned by an earlier callto \param{CmiAlloc}.}
 
@@ -259,17 +288,20 @@ should be returned by an earlier callto \param{CmiAlloc}.}
 \section{Input/Output}
 
 \function{void CmiPrintf(char *format, arg1, arg2, ...)}
+\index{CmiPrintf}
 \desc{This function does an atomic \param{printf()} on \param{stdout}. 
 On machine with host, this is implemented on top of the messaging 
 layer using asynchronous sends.}
 
 \function{int CmiScanf(char *format, void *arg1, void *arg2, ...)}
+\index{CmiScanf}
 \desc{This function performs an atomic \param{scanf} from \param{stdin}.
 The processor, on which the caller resides, blocks for input. On machines with
 host, this is implemented on top of the messaging layer using asynchronous
 send and blocking receive.}
 
 \function{void CmiError(char *format, arg1, arg2, ...)}
+\index{CmiError}
 \desc{This function does an atomic \param{printf()} on \param{stderr}. 
 On machines with host, this is implemented on top of the messaging 
 layer using asynchronous sends.}
@@ -323,16 +355,20 @@ because message communication patterns can be made to proceed along the
 spanning tree arcs to avoid bottlenecks at a single node.
 
 \function{int CmiSpanTreeRoot()}
+\index{CmiSpanTreeRoot}
 \desc{Returns the processor number of the root of the spanning tree.}
 
 \function{int CmiSpanTreeParent(int node)}
+\index{CmiSpanTreeParent}
 \desc{This function returns the processor number of the parent of
 \param{node} in the spanning tree.}
 
 \function{int CmiNumSpanTreeChildren(int node)}
+\index{CmiNumSpanTreeChildren}
 \desc{Returns the number of children of \param{node} in the spanning tree.}
 
 \function{void CmiSpanTreeChildren(int node, int *children)}
+\index{CmiSpanTreeChildren}
 \desc{This function fills the array \param{children} with processor
 numbers of children of \param{node} in the spanning tree.}
 
index 81321db830664b1fcf673d3d200fd9a52f93a558..54efe209903bbac9387832edf9722dc1f297e996 100644 (file)
 % REVISION HISTORY:
 %
 % $Log$
-% Revision 1.3  1995-10-30 17:33:54  milind
+% Revision 1.4  1995-11-01 21:16:23  milind
+% Added index entries.
+%
+% Revision 1.3  1995/10/30  17:33:54  milind
 % Changed Cth variables macros to Ctv macros.
 % Added "More on Shared Memory Machines" section.
 %
 %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-\chapter{Global Variable Usage}
+\chapter{Machine Model and Global Variables}
+
+
+The machine model assumed by Converse consists of a collection of
+nodes, where each node comprises of a number of processors that
+share memory. In addition, each of the processors could have multiple
+threads running on them which share code and data but have different
+stacks. On networks of workstations or distributed memory MIMD
+machines, number of processors in each node is assumed to be one and on
+machines that do not have native thread support, there is only one
+thread per processor. Converse provides functions to determine rank of
+a processor within a node and a consistent access/modification
+mechanism to manipulate global variables.
 
+\section{Global Variables}
 
 Global variables are allowed in Converse via specific macros.  These macros 
 ensure that the program runs portably on various parallel machines. 
 Three classes of global variables are supported: node-private,
 process-private, and thread-private variables. 
-%These classes are
-%strongly related to the machine model described in Section x.
 
 \begin{description}
 \item[Node-private global variables] are specific to a node. They are
@@ -64,6 +78,11 @@ CsvInitialize(type,variable)
 CsvAccess(variable)
 \end{verbatim}
 
+\index{CsvDeclare}
+\index{CsvStaticDeclare}
+\index{CsvExtern}
+\index{CsvInitialize}
+\index{CsvAccess}
 
 Macros for process-private variables:
 \begin{verbatim}
@@ -73,6 +92,11 @@ CpvExtern(type,variable)
 CpvInitialize(type,variable)
 CpvAccess(variable)
 \end{verbatim}
+\index{CpvDeclare}
+\index{CpvStaticDeclare}
+\index{CpvExtern}
+\index{CpvInitialize}
+\index{CpvAccess}
 
 Macros for thread-private variables:
 \begin{verbatim}
@@ -82,9 +106,14 @@ CtvExtern(type,variable)
 CtvInitialize(type,variable)
 CtvAccess(variable)
 \end{verbatim}
+\index{CtvDeclare}
+\index{CtvStaticDeclare}
+\index{CtvExtern}
+\index{CtvInitialize}
+\index{CtvAccess}
 
 
-\section{Example of Usage}
+\subsection{Example of Usage}
 
     A sample code to illustrate the usage of the macros is provided
     in Figure~\ref{fig:cpv}.
@@ -127,28 +156,32 @@ File Module1.c
     int func1() 
     {
          CpvAccess(p).x = 0;
-         CpvAccess(p).y = 0;
+         CpvAccess(p).y = CpvAccess(p).x + 1;
     }
 \end{verbatim}
 \caption{An example code for global variable usage}
 \label{fig:cpv}
 \end{figure}
 
-\section{More on Shared-Memory machines}
+\section{Utility Functions}
 
-To simplify programming with global variables on shared memory machines,
+To further simplify programming with global variables on shared memory machines,
 Converse provides following functions and/or macros. \note{These functions
+are defined on machines other than shared-memory machines also, and
 have the effect of only one processor per node and only one thread per 
-processor on other machines.}
+processor.}
 
 \function{int CmiMyRank()}
+\index{CmiMyRank}
 \desc{Returns the rank of the calling processor within a shared memory node.}
 
 \function{void CmiNodeBarrier()}
+\index{CmiNodeBarrier}
 \desc{Provide barrier synchronization at the node level, i.e. all the 
 processors belonging to the node participate in this barrier.}
 
 \function{void *CmiSvAlloc(int size)}
+\index{CmiSvAlloc}
 \desc{Allocates a block of memory of \param{size} bytes from the heap in node's 
 local memory and returns pointer to the start of this block. \note{On 
 machines other than shared-memory machines, this is equivalent to 
index 490e6c308c70fb4d5692331ca817e13ee9ad0300..4560ac11366d236534792c881f10a4c9cbb94a47 100644 (file)
@@ -1,26 +1,43 @@
 \chapter{Load Balancer Calls}
 
-\internal{
-\function {void ClbInit(void)}
-Routine called at scheduler startup to allow the load balancer to
-register its own message handlers.
-}
 
-\function {void ClbEnqueue(Message *msg, FunctionPtr send\_func)}
-Function called by a handler to let the load balancer know about a
-``seed'' message. If the seed is to be processed locally, the
-load balancer will
-enqueue it in the scheduler's queue to be eventually executed.
-{\sf send\_func} specifies the function
-which should be used to send the seed to another processor
-if it is not to be processed locally.
+\function{CldNewSeedFromLocal()}
+\index{CldNewSeedFromLocal}
+\desc{}
 
-\function {void ClbEnqueuePrio(Message *msg, FunctionPtr send\_func,
-void *prio, int len)} 
-Same as {\sf ClbEnqueue()}, except that a priority {\sf prio} of length
-{\sf len} bytes is associated with the message.
+\function{CldNewSeedFromNet()}
+\index{CldNewSeedFromNet}
+\desc{}
 
+\function{CldFillLdb()}
+\index{CldFillLdb}
+\desc{}
 
+\function{CldStripLdb()}
+\index{CldStripLdb}
+\desc{}
+
+%\internal{
+%\function {void ClbInit(void)}
+%Routine called at scheduler startup to allow the load balancer to
+%register its own message handlers.
+%}
+%
+%\function {void ClbEnqueue(Message *msg, FunctionPtr send\_func)}
+%Function called by a handler to let the load balancer know about a
+%``seed'' message. If the seed is to be processed locally, the
+%load balancer will
+%enqueue it in the scheduler's queue to be eventually executed.
+%{\sf send\_func} specifies the function
+%which should be used to send the seed to another processor
+%if it is not to be processed locally.
+%
+%\function {void ClbEnqueuePrio(Message *msg, FunctionPtr send\_func,
+%void *prio, int len)} 
+%Same as {\sf ClbEnqueue()}, except that a priority {\sf prio} of length
+%{\sf len} bytes is associated with the message.
+%
+%
 %The most general load balancing scheme will have three opportunities
 %to migrate load.  The first will be when {\sf ClbEnQueue()} is called.
 %This routine will either immediately send the message elsewhere for
index 63b02af91ce0b49de6e325f03f12ca283b69ed16..d52a114a045df1e85d919e2d9d61022e46036a36 100644 (file)
 
 \date{ }
 
+\makeindex
 
 \begin{document}
 
 \maketitle
  
+\tableofcontents
 
 \input{scheduler}
 \input{queue}
index a54c2c4d25b556d13001811aef151d2b49bd41ad..f758d65c1ed2b1fed228f0a8f2cb30e910ca165c 100644 (file)
@@ -17,15 +17,18 @@ need to be pointers to converse messages.  They can be pointers to
 anything.
 
 \function{typedef struct CmmTableStruct *CmmTable}
+\index{CmmTable}
 \desc{This opaque type is defined in {\tt converse.h}.  It represents
 a table which can be used to store messages.  No information is publicized
 about the format of a CmmTableStruct.}
 
 \function{\#define CmmWildCard (-1)}
+\index{CmmWildCard}
 \desc{This \#define is in {\tt converse.h}.  The tag -1 is the ``wild
 card'' for the tag-based lookup functions in the message manager.}
 
 \function{CmmTable CmmNew();}
+\index{CmmNew}
 \desc{This function creates a new message-table and returns it.}
 
 \function{void CmmPut(CmmTable t, int ntags, int *tags, void *msg)}
@@ -35,6 +38,7 @@ array.  The {\tt tags} array contains the tags themselves.  {\tt msg}
 and {\tt t} specify the message and table, respectively.}
 
 \function{void *CmmGet(CmmTable t, int ntags, int *tags, int *ret\_tags)}
+\index{CmmGet}
 \desc{This function looks up a message from a message table.  A
 message will be retrieved that ``matches'' the specified {\tt tags}
 array.  If a message is found that ``matches'', the tags with which
@@ -50,10 +54,12 @@ CmmWildCard} (yes, that means if I can {\tt store} messages with
 wildcard tags, making it easier to find those messages on retrieval).}
 
 \function{void *CmmProbe(CmmTable t, int ntags, int *tags, int *ret\_tags)}
+\index{CmmProbe}
 \desc{This function is identical to {\tt CmmGet} above, except that
 the message is not deleted from the table.}
 
 \function{void CmmFree(CmmTable t);}
+\index{CmmFree}
 \desc{This function frees a message-table t.  WARNING: It also frees all
 the messages that have been inserted into the message table.  It assumes
 that the correct way to do this is to call {\tt CmiFree} on the message.
index 68c387add18f15ac6b5954979d0827acc407bcad..df86899a484b93f854fe6b9560efb08ea366b8d4 100644 (file)
@@ -2,6 +2,7 @@
 
 
 \function{void ConverseInit(char *argv[])}
+\index{ConverseInit}
 \desc{This function initializes the machine interface. It should be
 called prior to any other Converse functions. 
 Multiple calls to this function in a process should
@@ -11,6 +12,7 @@ It would be utilized by \param{ConverseInit()} to initialize
 machine specific parameters such as number of processors.}
 
 \function{void ConverseExit(void)}
+\index{ConverseExit}
 \desc{This function frees the resources acquired by Converse and wraps up. 
 Any other Converse function should not be called after a call to this function.
 \note{It does not terminate the calling
@@ -30,17 +32,20 @@ ConverseInit().
 }
 
 \function {void CsdScheduler(int NumberOfMessages)}
+\index{CsdScheduler}
 \desc{This call invokes the Converse scheduler. The {\tt NumberOfMessages}
 parameter specifies how many messages should be processed (i.e. delivered
 to their handlers). If set to -1, the scheduler continues processing
 messages until CsdExitScheduler() is called from a message handler.}
 
 \function {void CsdExitScheduler(void)}
+\index{CsdExitScheduler}
 \desc{This call causes the scheduler
 to stop processing messages when control has returned back to it.
 The scheduler then returns to its calling routine.}
 
 \function{void CsdEnqueueGeneral(void *Message, int strategy, int priobits, int *prioptr)}
+\index{CsdEnqueueGeneral}
 \desc{This call enqueues a message to the scheduler's queue, to be processed in 
 accordance with the queueing \param{strategy}. \param{priobits} and
 \param{prioptr} specify information about priority associated with the message
@@ -59,7 +64,9 @@ Also, it is used to enqueue local ready entities, such as threads.
 because on returning from the handler, the system can reuse the buffer.}}
 
 \function {void CsdEnqueue(void *Message)}
+\index{CsdEnqueue}
 \function{void CsdEnqueueFifo(void *Message)}
+\index{CsdEnqueueFifo}
 \desc{
        This macro is a shorthand for 
        {\tt CsdEnqueueGeneral(Message, CQS\_QUEUEING\_FIFO,0, NULL)} 
@@ -68,6 +75,7 @@ because on returning from the handler, the system can reuse the buffer.}}
 
 
 \function{void CsdEnqueueLifo(void *Message)}
+\index{CsdEnqueueLifo}
 \desc{
        This macro is a shorthand for
        {\tt CsdEnqueueGeneral(Message, CQS\_QUEUEING\_LIFO,0, NULL)} 
@@ -75,6 +83,7 @@ because on returning from the handler, the system can reuse the buffer.}}
 }
 
 \function{int CsdEmpty()}
+\index{CsdEmpty}
 \desc{
        This function returns non-zero integer when the scheduler's queue
        is empty, zero otherwise.
index 998723e0fad29c0b2e5d6db334dd6fb26ba9ff5e..0843cdef4da23fb42d2b363c90d6ee0bd67be571 100644 (file)
@@ -40,34 +40,41 @@ that causes a thread to be automatically scheduled by the converse
 scheduler {\tt CsdScheduler}.
 
 \function{int CthImplemented()}
+\index{CthImplemented}
 \desc{Returns true if the current hardware platform supports the threads
 functions described below.}
 
 \function{typedef struct CthThreadStruct *CthThread;}
+\index{CthThread}
 \desc{This is an opaque type defined in {\tt converse.h}.  It represents
 a first-class thread object.  No information is publicized about the
 contents of a CthThreadStruct.}
 
 \function{typedef void (CthVoidFn)();}
+\index{CthVoidFn}
 \desc{This is a type defined in {\tt threads.h}.  It represents
 a function that returns nothing.}
 
 \function{typedef CthThread (CthThFn)();}
+\index{CthThFn}
 \desc{This is a type defined in {\tt threads.h}.  It represents
 a function that returns a CthThread.}
 
 \function{void CthInit()}
+\index{CthInit}
 \desc{Caution: you must call either {\tt ConverseInit} {\tt or} {\tt
 CthInit} before calling any of the thread functions described below,
 but you must {\tt not} call both.}
 
 \function{CthThread CthSelf()}
+\index{CthSelf}
 \desc{Returns the currently-executing thread.  Note: even the initial
 flow of control that inherently existed when the program began
 executing {\tt main} counts as a thread.  You may retrieve that thread
 object using {\tt CthSelf} and use it like any other.}
 
 \function{void CthResume(CthThread t)}
+\index{CthResume}
 \desc{Immediately transfers control to thread {\tt t}.  Note:
 normally, the user of a thread package wouldn't explicitly choose
 which thread to transfer to.  Instead, the user would rely upon a
@@ -79,6 +86,7 @@ barriers, and other synchronization devices should also probably
 rely on {\tt CthSuspend} and {\tt CthAwaken}.}
 
 \function{CthThread CthCreate(CthVoidFn fn, void *arg, int size)}
+\index{CthCreate}
 \desc{Creates a new thread object.  The thread is not given control
 yet.  The thread is not passed to any scheduler.  When (and if) the
 thread eventually receives control, it will begin executing the
@@ -94,12 +102,14 @@ CthSelf} in {\tt main}), and it can be used like any other {\tt
 CthThread}.}
 
 \function{void CthFree(CthThread t)}
+\index{CthFree}
 \desc{Frees thread {\tt t}.  You may even free the currently-executing
 thread, although the free will actually be postponed until the thread
 suspends.  This is how a thread terminates itself: it calls {\tt
 CthFree(CthSelf())}, then gives up control to another thread.}
 
 \function{void CthSuspend()}
+\index{CthSuspend}
 \desc{This is part of the scheduler-interface.  When a scheduler is
 being used, threads should call {\tt CthSuspend} when they wish to
 give up control of the CPU.  {\tt CthSuspend} will then automatically
@@ -109,6 +119,7 @@ user-supplied ``choose-next'' function (see {\tt CthSetStrategy}
 below).}
 
 \function{void CthAwaken(CthThread t)}
+\index{CthAwaken}
 \desc{This is part of the scheduler-interface.  When a scheduler is
 being used, this function should be used to notify the scheduler that
 thread {\tt t} wants the CPU.  This will enable the scheduler to
@@ -119,6 +130,7 @@ function (see {\tt CthSetStrategy} below).  It is illegal to call
 the thread has been scheduled since the last awaken.}
 
 \function{void CthSetStrategy(CthThread t, CthVoidFn awakenfn, CthThFn choosefn)}
+\index{CthSetStrategy}
 \desc{This is part of the scheduler-interface.  It should be used by
 the creator of thread {\tt t} to specify the scheduling functions to
 be used for thread {\tt t}.  The scheduling functions must have the
@@ -159,6 +171,7 @@ module to resume {\tt t} whenever it so desires: presumably, the
 scheduling module knows when its threads want the CPU.}
 
 \function{void CthYield()}
+\index{CthYield}
 \desc{This function is part of the scheduler-interface.  It simply
 executes {\tt \{ CthAwaken(CthSelf()); CthSuspend(); \} }.  This combination
 gives up control temporarily, but ensures that control will eventually
@@ -207,6 +220,7 @@ that {\tt var} will be set to when {\tt t} is running.}
 }
 
 \function{void CthSetStrategyDefault(CthThread t)}
+\index{CthSetStrategyDefault}
 \desc{This the simple scheduler provided to converse users as a
 convenience.  Calling this function on a thread {\tt t} causes thread
 {\tt t} to be scheduled by the built-in converse scheduler {\tt