Chares are concurrent objects with methods that can be invoked remotely. These methods are known as entry methods, and must be specified in the interface (.ci) file:
A corresponding chare definition in the .h file would have the form:
Chares are concurrent objects encapsulating medium-grained units of work. Chares can be dynamically created on any processor; there may be thousands of chares on a processor. The location of a chare is usually determined by the dynamic load balancing strategy; however, once a chare commences execution on a processor, it does not migrate to other processors11. Chares do not have a default ``thread of control'': the entry methods in a chare execute in a message driven fashion upon the arrival of a message12.
The entry method definition specifies a function that is executed without interruption when a message is received and scheduled for processing. Only one message per chare is processed at a time. Entry methods are defined exactly as normal C++ function members, except that they must have the return value void (except for the constructor entry method which may not have a return value, and for a synchronous entry method, which is invoked by a threaded method in a remote chare) and they must have exactly one argument which is a pointer to a message.
Each chare instance is identified by a handle which is essentially a global pointer, and is unique across all processors. The handle of a chare has type CkChareID. The variable thishandle holds the handle of the chare whose entry function or public function is currently executing. thishandle is a public instance variable of the chare object which is inherited from the system-defined superclass CBase_ClassType. Following the older syntax, chares are also allowed to inherit directly for the superclass Chare instead of CBase_ClassType, although this form is not suggested. thishandle can be used to set fields in a message. This mechanism allows chares to send their handles to other chares.
First, a chare needs to be declared, both in .ci file and in .h file, as stated earlier. The following is an example of declaration for a chare of user-defined type C, where M1 and M2 are user-defined message types, and someEntry is an entry method.
In the mod.ci file we have:
and in the mod.h file:
Now one can use the class CProxy_chareType to create a new instance of a chare. Here chareType gets replaced with whatever chare type we want. For the above example, proxies would be of type CProxy_C. A number of chare creation calls exist as static or instance methods of class CProxy_chareType:
Each item above is optional, and:
The chare creation method deposits the seed for a chare in a pool of seeds and returns immediately. The chare will be created later on some processor, as determined by the dynamic load balancing strategy. When a chare is created, it is initialized by calling its constructor entry method with the message parameter specified to the chare creation method. The method operator does not return any value but fills in the virtual handle to the newly created chare if specified.
The following are some examples on how to use the chare creation method to create chares.
A message may be sent to a chare using the notation:
chareProxy.EntryMethod(parameters)
This invokes the entry method EntryMethod on the chare referred to by the proxy chareProxy. This call is asynchronous and non-blocking; it returns immediately after sending the message.
You can get direct access to a local chare using the proxy's ckLocal method, which returns an ordinary C++ pointer to the chare if it exists on the local processor; and NULL if the chare does not exist or is on another processor.
November 23, 2009
Charm Homepage