00001
00002
00003 #ifndef _BCP_MESSAGE_H
00004 #define _BCP_MESSAGE_H
00005
00006
00007
00008 #include <utility>
00009
00010 #include "BCP_string.hpp"
00011 #include "BCP_message_tag.hpp"
00012 #include "BCP_vector.hpp"
00013
00014
00015
00016
00017 class BCP_buffer;
00018 class USER_initialize;
00019
00020
00021
00029 class BCP_proc_id {
00030 public:
00035 virtual ~BCP_proc_id() {}
00043 virtual bool is_same_process(const BCP_proc_id* other_process) const = 0;
00050 virtual BCP_proc_id* clone() const = 0;
00052 };
00053
00054
00055 const BCP_proc_id* const BCP_AnyProcess = 0;
00056
00057
00058
00061 class BCP_proc_array {
00062 private:
00066 BCP_proc_array(const BCP_proc_array&);
00068 BCP_proc_array& operator=(const BCP_proc_array&);
00070 private:
00074 BCP_vec<BCP_proc_id*> _procs;
00076 BCP_vec<BCP_proc_id*> _free_procs;
00078 public:
00082 BCP_proc_array() : _procs(), _free_procs() {}
00084 ~BCP_proc_array() {
00085 purge_ptr_vector(_procs);
00086 }
00092 inline bool is_free_proc(const int index) {
00093 const BCP_proc_id* proc = _procs[index];
00094 int i;
00095 for (i = _free_procs.size() - 1; i >= 0; --i)
00096 if (_free_procs[i]->is_same_process(proc))
00097 break;
00098 return (i >= 0);
00099 }
00102 inline int index_of_proc(const BCP_proc_id* proc) {
00103 int i;
00104 for (i = _procs.size() - 1; i >= 0; --i)
00105 if (_procs[i]->is_same_process(proc))
00106 break;
00107 return i;
00108 }
00110 inline BCP_vec<BCP_proc_id*>& procs() { return _procs; }
00112 inline const BCP_vec<BCP_proc_id*>& procs() const { return _procs; }
00114 inline const BCP_proc_id* process(const int i) { return _procs[i]; }
00116 inline int size() const { return _procs.size(); }
00118 inline int free_num() const { return _free_procs.size(); }
00120 inline int busy_num() const { return _procs.size() - _free_procs.size(); }
00122 BCP_proc_id* get_free_proc() {
00123 if (_free_procs.size() > 0) {
00124 BCP_proc_id* proc = _free_procs.back();
00125 _free_procs.pop_back();
00126 return proc;
00127 }
00128 return 0;
00129 }
00135 inline void clear() {
00136 purge_ptr_vector(_procs);
00137 _free_procs.clear();
00138 }
00141 inline void add_procs(BCP_vec<BCP_proc_id*>::const_iterator first,
00142 BCP_vec<BCP_proc_id*>::const_iterator last) {
00143
00144 _free_procs.insert(_free_procs.end(), first, last);
00145 while (first != last) {
00146 _procs.insert(_procs.end(), (*first)->clone());
00147 ++first;
00148 }
00149 }
00153 inline void delete_proc(const int index) {
00154 const BCP_proc_id* proc = _procs[index];
00155 int i;
00156 for (i = _free_procs.size() - 1; i >= 0; --i)
00157 if (_free_procs[i]->is_same_process(proc))
00158 break;
00159 if (i >= 0)
00160 _free_procs.erase(_free_procs.entry(i));
00161 delete _procs[index];
00162 _procs.erase(_procs.entry(index));
00163 }
00164
00165
00169 void set_proc_free(BCP_proc_id* proc) {
00170 _free_procs.push_back(proc);
00171 }
00173 };
00174
00175
00176
00184 class BCP_message_environment{
00185 public:
00190 virtual ~BCP_message_environment() {}
00197 virtual BCP_proc_id* register_process(USER_initialize* user_init) = 0;
00204 virtual BCP_proc_id* parent_process() = 0;
00211 virtual bool alive(const BCP_proc_id* pid) = 0;
00215 virtual BCP_vec<BCP_proc_id*>::iterator
00216 alive(const BCP_proc_array& parray) = 0;
00223 virtual void send(const BCP_proc_id* const target,
00224 const BCP_message_tag tag) = 0;
00227 virtual void send(const BCP_proc_id* const target,
00228 const BCP_message_tag tag,
00229 const BCP_buffer& buf) = 0;
00236 virtual void multicast(const BCP_proc_array* const target,
00237 const BCP_message_tag tag) = 0;
00240 virtual void multicast(const BCP_proc_array* const target,
00241 const BCP_message_tag tag,
00242 const BCP_buffer& buf) = 0;
00249 virtual void multicast(BCP_vec<BCP_proc_id*>::const_iterator beg,
00250 BCP_vec<BCP_proc_id*>::const_iterator end,
00251 const BCP_message_tag tag) = 0;
00254 virtual void multicast(BCP_vec<BCP_proc_id*>::const_iterator beg,
00255 BCP_vec<BCP_proc_id*>::const_iterator end,
00256 const BCP_message_tag tag,
00257 const BCP_buffer& buf) = 0;
00260
00273 virtual void receive(const BCP_proc_id* const source,
00274 const BCP_message_tag tag, BCP_buffer& buf,
00275 const double timeout) = 0;
00282 virtual bool probe(const BCP_proc_id* const source,
00283 const BCP_message_tag tag) = 0;
00291 virtual BCP_proc_id* start_process(const BCP_string& exe,
00292 const bool debug) = 0;
00294 virtual BCP_proc_id* start_process(const BCP_string& exe,
00295 const BCP_string& machine,
00296 const bool debug) = 0;
00298 virtual BCP_proc_array* start_processes(const BCP_string& exe,
00299 const int proc_num,
00300 const bool debug) = 0;
00303 virtual BCP_proc_array* start_processes(const BCP_string& exe,
00304 const int proc_num,
00305 const BCP_vec<BCP_string>& machines,
00306 const bool debug) = 0;
00309
00310
00311
00315 virtual BCP_proc_id* unpack_proc_id(BCP_buffer& buf) = 0;
00317 virtual void pack_proc_id(BCP_buffer& buf, const BCP_proc_id* pid) = 0;
00323 virtual int num_procs() { return 0; }
00328 };
00329
00330 #endif