Each context has an integer name, which can be chosen by the creator of the context, and which must be unique among its siblings (i.e. all of the other child contexts belonging to the same parent context). Also, CDS automatically assigns each context a context ID, which is a handle (i.e. typically a small integer which serves as an index into an internal table containing information about the context), and this is the value that is passed to the various routines. The context ID is best considered as a shorthand for a sequence of integer context names which describes a path from the root context to the context being dealt with. When a context ID is used in a CDS operation to refer to a context in another process, it will refer to the context represented by the same sequence of integer context names in that process, even if the other process uses a different numerical value locally for its context ID for that context.
The general approach to using these contexts is for each library (or other logical sub-entity in the process) to use its own context for virtually all of communication with its cohorts. In general, the initialization function for a library will accept the context ID in which the caller is operating as one of its arguments, and create its own context as a child of the caller's context. If all processes are guaranteed to call all initialization routines in the same order, then it is sufficient for each initialization routine to request the next available child context in that parent context. If initialization routines are not guaranteed to be called in the same order in each process, then it is up to the program designer to "stake out" certain context names for use by certain libraries, in much the same way that certain ports are reserved in a socket-based system for communication. In that case, the initialization routine would request its context by name.
In many cases (such as those where the initialization routines must themselves perform communication with their cohorts on other processors), creating a context is not sufficient. The routine must let its cohorts know when the new context is ready to be used. The easiest way to do this is to "borrow" a cell from the parent's context to communicate this information to cohorts. In this case, the parent is not only asked to pass its context ID to the initialization routine, but also to pass a cell number within that context which can be used bythe initialization routine for this synchronization.
Contexts are created by the cds_mkcntxt operation, and deleted by the cds_rmcntxt operation. In addition to just creating the context, cds_mkcntxt also allows the caller to specify information about the cells, such as which operations should be suppressed to them from other processes, and whether or not the CDS_NODTA permission is likely to be used on the cell (which can be used to optimize transfers in some cases).
Communicating a context ID from one process to another (i.e. within a region) requires the same sort of care that process IDs require. That is, the cds_copyto and cds_copyfm operations must be used to transfer the internal representation of the context (which is basically the name sequence discussed earlier) to and from the region. Unfortunately, the length of this internal representation may vary depending upon the depth of the context within the process's context tree. For the context data type (CDS_TCNTXT), the cds_typlen operation therefore returns the length of this representation for just one level, and the caller is advised to multiply that by a reasonable number to accomodate the maximum depth that the context tree is expected to reach. (The cds_copy routines are always careful not to run past a region's boundary, and report the number of bytes actually transferred.)
cds_mkcntxt(&newcntxt, parcntxt, name, ncells, nrgns, nbytes, nperms, perms)newcntxt is the context ID of the new (child) context created by the operation, parcntxt is the context ID of the parent context, name is the name to be given to the new context, ncells is the numner of cells to be created in the context, nrgns is the number of regions which might be in all of those cells at any one time (plus regions that exist and were or will be in one of those cells), nbytes is the number of bytes to be added to the comm heap to accomodate those regions, nperms is the number of cell permission blocks to be specified, and perms is a vector of those blocks. Each element of perms is an integer, denoting a number of next sequential cells to be denied a particular permission, OR'd with permission flags CDS_NOENQ, CDS_NOWRIT, CDS_NODEQ, CDS_NOREAD, and/or CDS_NODTA. (The sum of all of the cells denied permissions in perms must be less than or equal to ncells.) Note: Because of fragmentation of the comm heap, nbytes may need to be up to twice the actual number of bytes expected to be used by regions in the context.
cds_rmcntxt(cntxt)
The CDS_NODTA permission is meant to allow a process to deal with regions without necessarily sequentializing them, and in some cases, without bringing them into accessible memory (e.g. they may remain deep within the communication subsystem). It is necessary to flag the cell to which the region is being delivered so that the communication agent can avoid any special overhead associated with sequentializing a message and making it available via a pointer to the rest of the program. Even if CDS_NODTA is specified for a cell, if the particular operation which operates on a region from the cell does not also specify CDS_NODTA, the region may need to be sequentialized and made available anyway, and this may be less efficient over all than if CDS_NODTA had not been specified for the cell in the first place.
Copyright 2000 © elepar All rights reserved