// // mstate.h // // Copyright (C) 1996 Limit Point Systems, Inc. // // Author: Curtis Janssen // Maintainer: LPS // // This file is part of the SC Toolkit. // // The SC Toolkit is free software; you can redistribute it and/or modify // it under the terms of the GNU Library General Public License as published by // the Free Software Foundation; either version 2, or (at your option) // any later version. // // The SC Toolkit is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Library General Public License for more details. // // You should have received a copy of the GNU Library General Public License // along with the SC Toolkit; see the file COPYING.LIB. If not, write to // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. // // The U.S. Government is granted a limited license as per AL 91-7. // #ifdef __GNUC__ #pragma interface #endif #ifndef _util_group_mstate_h #define _util_group_mstate_h #include #include #include #include namespace sc { /** The MsgStateSend is an abstract base class that sends objects to nodes in a MessageGrp. */ class MsgStateSend: public StateOut { private: // do not allow copy constructor or assignment MsgStateSend(const MsgStateSend&); void operator=(const MsgStateSend&); protected: Ref grp; int nbuf; // the number of bytes used in the buffer int bufsize; // the allocated size of the data buffer char* buffer; // the data buffer char* send_buffer; // the buffer used to send data (includes nbuf) int nheader; // nbuf + nheader = the number of bytes in send_buffer to send int* nbuf_buffer; // the pointer to the nbuf stored in the buffer int put_array_void(const void*, int); public: MsgStateSend(const Ref&); virtual ~MsgStateSend(); /// Specializations must implement flush(). virtual void flush() = 0; /** The buffer size of statein and stateout objects that communicate with each other must match. */ void set_buffer_size(int); /** I only need to override put(const ClassDesc*) but C++ will hide all of the other put's so I must override everything. */ int put(const ClassDesc*); int put(char r); int put(unsigned int r); int put(int r); int put(float r); int put(double r); int put(const char*,int); int put(const int*,int); int put(const unsigned int*,int); int put(const float*,int); int put(const double*,int); }; /** The MsgStateBufRecv is an abstract base class that buffers objects sent through a MessageGrp. */ class MsgStateBufRecv: public StateIn { private: // do not allow copy constructor or assignment MsgStateBufRecv(const MsgStateBufRecv&); void operator=(const MsgStateBufRecv&); protected: Ref grp; int nbuf; // the number of bytes used in the buffer int ibuf; // the current pointer withing the buffer int bufsize; // the allocated size of the buffer char* buffer; // the data buffer char* send_buffer; // the buffer used to send data (includes nbuf) int nheader; // nbuf + nheader = the number of bytes in send_buffer to send int* nbuf_buffer; // the pointer to the nbuf stored in the buffer int get_array_void(void*,int); /// Specializations must implement next_buffer(). virtual void next_buffer() = 0; public: /// MsgStateBufRecv can be initialized with a MessageGrp. MsgStateBufRecv(const Ref&); /// Use the default MessageGrp. MsgStateBufRecv(); virtual ~MsgStateBufRecv(); /** The buffer size of statein and stateout objects that communicate with each other must match. */ void set_buffer_size(int); }; /** The MsgStateRecv is an abstract base class that receives objects from nodes in a MessageGrp. */ class MsgStateRecv: public MsgStateBufRecv { private: // do not allow copy constructor or assignment MsgStateRecv(const MsgStateRecv&); void operator=(const MsgStateRecv&); public: /// MsgStateRecv must be initialized with a MessageGrp. MsgStateRecv(const Ref&); virtual ~MsgStateRecv(); /** Returns the version of the ClassDesc. This assumes that the version of the remote class is the same as that of the local class. */ int version(const ClassDesc*); /** I only need to override get(ClassDesc**) but C++ will hide all of the other get's so I must override everything. */ int get(const ClassDesc**); int get(char&r, const char *key = 0); int get(unsigned int&r, const char *key = 0); int get(int&r, const char *key = 0); int get(float&r, const char *key = 0); int get(double&r, const char *key = 0); int get(char*&); int get(unsigned int*&); int get(int*&); int get(float*&); int get(double*&); }; /** StateSend is a concrete specialization of MsgStateSend that does the send part of point to point communication in a MessageGrp. */ class StateSend: public MsgStateSend { private: // do not allow copy constructor or assignment StateSend(const StateSend&); void operator=(const StateSend&); private: int target_; public: /// Create a StateSend given a MessageGrp. StateSend(const Ref&); ~StateSend(); /// Specify the target node. void target(int); /// Flush the buffer. void flush(); }; /** StateRecv is a concrete specialization of MsgStateRecv that does the receive part of point to point communication in a MessageGrp. */ class StateRecv: public MsgStateRecv { private: // do not allow copy constructor or assignment StateRecv(const StateRecv&); void operator=(const StateRecv&); private: int source_; protected: void next_buffer(); public: /// Create a StateRecv given a MessageGrp. StateRecv(const Ref&); /// Specify the source node. void source(int); }; /** BcastStateSend does the send part of a broadcast of an object to all nodes. Only one node uses a BcastStateSend and the rest must use a BcastStateRecv. */ class BcastStateSend: public MsgStateSend { private: // do not allow copy constructor or assignment BcastStateSend(const BcastStateSend&); void operator=(const BcastStateSend&); public: /// Create the BcastStateSend. BcastStateSend(const Ref&); ~BcastStateSend(); /// Flush the data remaining in the buffer. void flush(); }; /** BcastStateRecv does the receive part of a broadcast of an object to all nodes. Only one node uses a BcastStateSend and the rest must use a BcastStateRecv. */ class BcastStateRecv: public MsgStateRecv { private: // do not allow copy constructor or assignment BcastStateRecv(const BcastStateRecv&); void operator=(const BcastStateRecv&); protected: int source_; void next_buffer(); public: /// Create the BcastStateRecv. BcastStateRecv(const Ref&, int source = 0); /// Set the source node. void source(int s); }; /** This creates and forwards/retrieves data from either a BcastStateRecv or a BcastStateSend depending on the value of the argument to constructor. */ class BcastState { private: BcastStateRecv *recv_; BcastStateSend *send_; public: /// Create a BcastState object. The default source is node 0. BcastState(const Ref &, int source = 0); ~BcastState(); /** Broadcast data to all nodes. After these are called for a group of data the flush member must be called to force the source node to actually write the data. */ void bcast(int &); void bcast(double &); void bcast(int *&, int); void bcast(double *&, int); template void bcast(Ref&a) { if (recv_) { a << SavableState::restore_state(*recv_); } else if (send_) { SavableState::save_state(a.pointer(),*send_); } } /** Force data to be written. Data is not otherwise written until the buffer is full. */ void flush(); /** Call the StateOut or StateIn forget_references member. */ void forget_references(); /// Controls the amount of data that is buffered before it is sent. void set_buffer_size(int); }; /** BcastStateBin reads a file in written by StateInBin on node 0 and broadcasts it to all nodes so state can be simultaneously restored on all nodes. */ class BcastStateInBin: public MsgStateBufRecv { private: // do not allow copy constructor or assignment BcastStateInBin(const BcastStateRecv&); void operator=(const BcastStateRecv&); protected: int opened_; int file_position_; std::streambuf *buf_; void next_buffer(); int get_array_void(void*, int); public: /// Create the BcastStateRecv using the default MessageGrp. BcastStateInBin(const Ref &); /// Create the BcastStateRecv. BcastStateInBin(const Ref&, const char *filename); ~BcastStateInBin(); virtual int open(const char *name); virtual void close(); void seek(int loc); int seekable(); int tell(); int use_directory(); }; } #endif // Local Variables: // mode: c++ // c-file-style: "CLJ" // End: