template<class S>
class MPIslave
  int nprocs, myid;
  vector<int> idle; /* list of waiting slaves, valid on master */
  ~MPIslave() {finalize();}
  void init();
  void finalize();
  MPIbuf& operator<<(void (S::*m)(MPIbuf&))
  template <class T> MPIbuf& operator<<(const T& x);
  void exec(MPIbuf& x);
  MPIbuf& get_returnv();
  void wait_all_idle();
  void bcast(MPIbuf& c=cmd);

MPIslave is an implementation of a master-slave application. An MPIslave object must be created within an MPI parallel region (eg created by MPISPMD). The slave code is implemented as a class (S say), with each method implementing a remote procedure being of type void (MPIbuf&). Declaring a variable of type MPIslave<S> will set up an interpreter on the slave processor. The remote processes are closed down once the variable is finalised, or goes out of scope.

See the file in the mpi-examples for an example of how this works.

operator<< is provided as a convenience -- one can compose a message of the form:

MPIslave<S> slave;
slave << &S::foo << x << send(1);
without needing to declare additional MPIbufs.

For managing a list of idle slaves, the idle vector is employed, and is manipulated through the exec method, which dispatches a command to be executed on a slave, and the get_returnv() which returns the returned result as an MPIbuf, and places the processor from which it received a value back on the idle list. This technique is only valid for slave methods returning a message (even if its a null message). The wait_all_idle method waits for all slaves to return.

The bcast() method is a convenience method for sending the contents of MPISlave::cmd, or the optional MPIbuf argument to all slaves.