As the user sees it, contexts are a communication channel they may have passed to other processes within an Ease program. The user has a context value, which they may pass between processes. This value has a corresponding structure kept by the Ease library on the cell where the context was created. Interaction with the context occurs directly within a cell or via messages between cells.
Each context operation is translated into a single function call (except in
the case of a resource/reply operation). In C-with-Ease
, the operation (a get
from context c into pointer a):
@get!(c, a);Is translated into:
__ease_get_p(&c,(sizeof(*(a))),&(a));
The address of the context is passed to permit the library to modify the context structure if it is necessary (if the context is migrated the new address of the context could be placed into the user's handle to improve efficiency). The size is passed since the library only deals with void pointers and does not know the size of the types of the user.
In C++ -with-Ease , the same call is translated into:
__EASE_get_p(&c,(sizeof(*(a))),&(a));The difference is due to the use of parameterized context types. A collection of macros exist to translate all
__EASE calls to
calls to the appropriate method of the context type. The appropriate
macro here looks like:
#define __EASE_get_p(ctx, size, pointer) (ctx)->getP(size,pointer)Notice the compiler does type checking of context operations. Other basic context operations translate into similar functions.
Call/reply operations require different treatment due to their different syntax. The C-with-Ease resource/reply operation:
@resource(c, a) { /* Some code */ } @reply b;
is translated into:
{
_ec_reply_info _ec_rep;
_ec_rep = __ease_get_reply(&c,(sizeof( a)),&( a));
{ /* Some code */ } ;
__ease_write_reply(_ec_rep,0,(sizeof( b)),&( b));
};
The _ec_reply_info structure holds the "return address" for
the call. This consists of the cell and the thread identifiers. Using
this structure, resource/reply's may be nested arbitrarily.
(The second parameter to __ease_write_reply (the 0) is used in
C++ -with-Ease
to pass the context, which is required for type checking and for
supply of the marshalling operations if required.)
In C-with-Ease
, contexts must be explicitly initialized using the @init(ctx)
operation. This initializes the user's handle with the integer
identifier of a newly created (internal) context structure.
In C++ -with-Ease
, the constructor mechanism is used to create the internal
context data structure so the @init construct is unnecessary. The
constructor for contexts also associates a number of conversion
functions with the context. These functions are wrappers around calls to
the copy constructor, the assignment operator, marshalling functions,
new and delete for the data type used by the context. They allow the
Ease
library to correctly handle C++
classes using callbacks from C
code. This is discussed further in section 5.6.
There are two layers of context handling in the Ease library. The data layer handles the actual storage of the data and the queuing of requests. The interface layer handles communication with threads both local and remote to the context's cell.
The interface layer receives requests in the form of function calls from local threads and messages from remote threads. It passes the data or request through to the data layer together with a callback function and a structure to supply to the callback which identifies the process requesting data. The callback function either copies the data to a local thread or transmits it to a remote cell.
The interface layer will suspend a local thread if data is not immediately available and resume the thread once data has been supplied.
The data layer handles the internal context type. The internal context structure is private to the data layer and is not accessed directly by any other part of the Ease system. All calls to the data layer return immediately, whether or not data is available, as the data layer has no knowledge of scheduling. Callbacks are used to complete operations that take an indeterminate time to complete (such as any get or read operation).
The context structure contains the following data:
The interface to the data layer consists of the following functions:
Context. If data is available
immediately then the Callback function is called with the
supplied ProcId and the data, the function then returns true. If
data is not available readFromContext will return false, and
will also queue a request if immed is false. The immed flag is
set to true for code that uses @select with an @else clause
where the caller does not want a request queued if data cannot be
immediately supplied. It is the responsibility of the caller and
callback functions to suspend and resume the current thread as
necessary.
getFromContext is identical to that for
readFromContext except that the data is removed once it has
been read.
Context. If yours is
true then the data now belongs to the context, which will
generally pass ownership on to the recipient of the data. If
yours is false then the data must be copied. The thread
supplied identifies the caller. If this is non-zero and the
context no longer exists then this thread will be killed.
If marshal is true, then the data is in marshalled format. Data
must be marshalled before it is transmitted in a message. In
C-with-Ease
, marshalling consists of a binary copy. The C++ -with-Ease
programmer may supply marshalling functions to allow transmission of complicated data types.
getFromContext and writeToContext
respectively except that they deal with reply context types.
Context or removes a lock. This
is used as part of the select mechanism (see section
5.4). If get is true, then the unlock refers to a prior
get request, otherwise it refers to a read request.
The supplied ProcId should be identical to that supplied to the
corresponding read/get request. If used is true, then the call
is an accept request, acknowledging data that was supplied.
Otherwise it is a reject request (data was sent which was
not longer required when it arrived at its destination) or an
indication that the initial request is no longer required (see
section 5.4.3 for a discussion of messages involved
in selection). For reject requests, data and marshal may be
used to return the data for freeing in the appropriate manner.
xxx State transition tables for context operations on different context types.
Various messages are used to handle context operations.
READ and GET messages request data from bag, stream and singleton
contexts, they are supplied data using a GIVE message. Data is written
into a context (from a put or write) using a WRITE
message.
xxx Diagram of read/get messages?
The message contents are:
READ and GET
WRITE
GIVE
A CALL message sends data from a call into a reply
context, while a RESOURCE message requests data from a reply context.
The call is given to the resource using a GIVE_CALL message and the
reply is returned to the caller using a GIVE message.
xxx Diagram of call messages?
Message contents for call reply context messages are:
CALL
RESOURCE
GIVE_CALL
_ec_reply_info structure
xxx This paragraph doesn't belong here. Maybe in CellOS or PVM section?
Many message passing libraries (for example PVM and the AP1000's CellOS)
have a message type associated with each message. To avoid excess
copying of data, two values are packed into the system message type: the
Ease
message type (for example READ) and another value, such as the
destination thread or context identifier.
Next: Select Implementation
Up: Implementation
Previous: Process Implementation