Cheetah Controller Reference

Controllers are the fundamental interface to one sided messaging. For a general overview of the motivation and architecture of controllers, see the controller guide. Here we provide a detailed description of the controller interface.

Constructors and Destructor

Controller()

The null constructor takes no action. The RefCountedPtr within the controller initializes itself to a null pointer. No communication can be done through this controller. It can be initialized by assigning a valid controller to it.

Controller(int &argc, char **&argv)

Build a controller using the command line parameters. The ControllerImpl class has a static factory member function which takes these arguments and builds a controller implementation depending on the types of the arguments. Each ControllerImpl subclass that can be built in this way must register its name, so that it will be constructed using the command line arguments. See the section below on the ControllerImpl class interface.

The name '-shmem' is used to build a shared memory controller, '-mpi' to build an MPI controller, and '-ulm' to build a User Level Messaging controller.

~Controller()

No destructor is explicitly defined because the implicit destructor calls the appropriate unlink operation in the RefCountedPtr.

Typedefs

typedef void (*Handler_t)(int who, int tag, void* buf,int len);

The type for a handler called by ainvoke. 'Who' is the calling context, 'tag' is the integer ID that the calling context used to call this function, 'buf' is a pointer to the data buffer the calling context sent, and 'len' is the number of bytes in the buffer. The system will handle deleting the buffer, so the user should not free it.

Query Functions

bool isValid()

Return true if the controller has been properly constructed, false otherwise.

int ncontexts() const

Return the number of contexts that are available through this controller. Asserts that the controller is valid.

int mycontext() const

Return the number for this context in [0...ncontexts-1]. Asserts that the controller is valid.

Messaging Functions

int registerHandler(Handler_t handler)

Register a new ainvoke handler with this controller. Returns an integer tag to be used in ainvoke to call this function remotely.

void ainvoke(int context, int tag, void *buffer, int len, int *local_bell)

Call the function registered as 'tag' in 'context' with the provided 'buffer' of length 'len'. When the local buffer can be reused (either by copying it into a system buffer or into the network) the local bell is rung. If local_bell==0, this function becomes synchronous in the sense that the buffer can be reused immediately upon return from ainvoke.

No guarantees are made about when the remote function is actually invoked! In particular, ringing the local bell does not imply that the remote function has been called.

No guarantees are made about how the buffer is packed with user data: it is up the handler being called to understand the packing of the buffer.

No value is returned from the remote function. If the user wishes to return some result from calling the function it should be handled by passing information about how to return that value in the buffer.

The 'poll' or 'wait' function below must be called at some point in the remote context for the ainvoke to be called in that context.

void put(int context, void *remote, void *local, int len, int *local_bell, int *remote_bell)

Put data in the 'local' buffer of length 'len' to the 'remote' buffer in another 'context'. Ring 'local_bell' in this context when the local buffer can be reused, and ring 'remote_bell' in the remote context when the destination buffer has been filled.

In general, the 'poll' or 'wait' function below must be called at some point in the remote context for the data to be copied into the remote buffer.

void get(int context, void *remote, void *local, int len, int *local_bell, int *remote_bell)

Get data from a buffer 'remote' of length 'len' in a remote 'context' and put it in the 'local' buffer. Ring 'remote_bell' in the remote context when the data has been copied out of that buffer, and ring 'local_bell' when it has been copied into the local buffer.

In general, the 'poll' or 'wait' function below must be called in the local and remote contexts for the data to be copied.

void barrier()

Wait until all of the other contexts associated with this controller to also call barrier. No context will exit the barrier until all of the contexts have entered the barrier.

void poll()

Process the currently pending message events that have come off the wire, but don't wait around for any new things to come off the wire.

void wait(volatile int *bell, int value)

Wait until the provided bell reaches the provided value. Call poll while waiting to keep messages flowing.