Communication in C++-with-Ease occurs through objects called contexts. Contexts are first class variables and may be passed as parameters, assigned to one another and stored in structures. Communication is asyncronous - a process writing an object into a context does not wait until that object has been read.
There are four different types of context, each with different properties. A stream context guarantees that the order of object placement matches the order of retrieval (it is a distributed FIFO queue). A bag context relaxes the ordering constraint on stream contexts - the order of object removal is arbitrary. Both of these contexts may contain an unlimited number of objects.
A singleton context may contain at most a single object. If a second object is placed into the context it replaces the existing object.
The fourth type of context is a reply context. This provides remote procedure call semantics. xxx refer to rpc reference: Nelson, B.J. Remote Procedure Call, Doctoral Dissertation, Dept CS Report CMU-CS-81-119, CMU, May 1981.
Context variables may be assigned to one another, passed through contexts, passed as parameters and used in context operations.
Context types are templated on their parameter types. This allows for typesafe context operations and also for the exchange of arbitrary objects (including variable sized objects) through the use of marshalling functions (see section 3.3). The ordering of the types in the reply context declaration corresponds to the order of parameters in a @call.
The types that a context is templated on must have a void constructor, a copy constructor, and an assignment operator. (They may be the ones automatically generated by the compiler for you.)
Context types in C++ -with-Ease may be typedef'd.Due to the limitations in current template implementations, the programmer must assist the C++ compiler by telling it which templates to instantiate. This is acheived using the macro:
declareCtx( context_type ); in the global scope. There is a slight problem with declaring reply context types this way, since the comma is seen to end the context_type parameter. Use the macro _ecAND instead of a comma to fix this.Also, for each type used as a context template parameter, you must use
declareCtxType(type); in the global scope.
In C++ -with-Ease contexts are automatically initialized. The C-with-Ease @init statement is unnecessary.
Context variables are really handles on much larger structures that reside on the processor where the context was initialized. Interactions with the context will interact with that processor.
The location of contexts may be influenced with the @own statement, which directs the runtime system to move the context data nearer to the current processor. This may improve performance by reducing the number of inter-process messages required for context operations.
xxx Discuss migration mechanisms - probably elsewhere.
It is often best to migrate the context data to the process that will be the recipient of most of the data sent through that context.An implementation need not take any action in response to a migration directive.
Contexts die when the process which created them terminates. If a process interacts with a dead context then that process may be killed by the system.
Currently, the only interaction with dead contexts which will not cause the termination of the process is a write from another processor.
Note that a context may outlive the context variable that it was created with and there may be other (copied) handles on the context.
Ease provides four operations on bag, stream and singleton contexts. Reply contexts operations will be described shortly.
The operators are designed to be symmetrical. @write and @read copy data to and from a context, @put and @get move data to and from a context. Once data has been @put it no longer belongs to the caller and should not be referenced.
Only the data type defined in the context declaration may be passed through the context.
The @get! and @put! forms allow for exchange of data by reference. The pointer passed to @put! is reset to 0 (since the current process no longer "owns" the data) and the system takes responsibility for deleteing the data. The pointer passed must therefore be allocated with new. @get! obtains a pointer to the data it receives, the deleteing of this data is the responsibility of the getter..
Combining different forms of get and put is legal: the system takes care of allocation and deallocation as necessary. The user may @put! data and retreive it with @get.
@write should really allow passing of arbirary expressions, but doesn't due to limitations in varargs handling on different architectures and a portable implementation is sought.Data that is @put may still be used by the caller in this implemenation (the same is not true for @put!).
Reply contexts provide call-reply semantics, that is, they allow the process that receives data to send a reply to the process that sent the data. This cannot be easily acheived using the other context types.
The call
A resource statment
The "!" forms behave similarly to @get! and @put!.
The non-pointer call value and the reply value should really be general expressions (as should @write).Note that int C++ -with-Ease , the form of a @reply is different to that of C-with-Ease . This is to facilitate type checking.
The select statement provides a construct to receive data from one of a number of contexts which may or may not be ready to supply data. It also provides a mechanism for testing whether or not a context contains data.
The select construct will only consider a select_clause if it has no select_guard or if the guard expression is true. It then waits until one of the clauses can be satisfied and executes the code associated with that clause (after performing the corresponding get, read or resource statement).
If there is an @else clause with no @after, then if data is not immediately available that clause will be executed. If there is an @else @after clause, then the process will wait for data for at least the time given by the corresponding expr (a double value in seconds).
If there are multiple @else clauses or multiple select clauses for the same context then selection between them is arbitrary. The programmer should not rely upon the selection following any particular rules.
An empty select or one whose clauses all have false guards successfully completes immediately.
Note that while the time before an @else @after clause will execute is at least a particular value, there is no upper limit on the time.Next: Data Marshalling Up: C++-with-Ease language definition Previous: Process controlWhen dealing with contexts on remote processors the select construct can generate a large number of messages, it does however, do no inter-process communication if the operation can be satisfied locally.