5 #if defined(COIN_HAS_PVM)
20 BCP_pvm_environment::~BCP_pvm_environment()
22 check_error( pvm_exit(),
"~BCP_pvm_environment()");
28 BCP_pvm_environment::check_error(
const int code,
const char* str)
const
31 printf(
"%s returned error code %i.\n", str, code);
41 int pid = pvm_mytid();
42 check_error(pid,
"pvm_mytid()");
43 int parent = parent_process();
45 check_error(pvm_catchout(stdout),
"register_process -- pvm_catchout\n");
47 setvbuf(stdout, (
char *)NULL, _IOLBF, 0);
52 BCP_pvm_environment::parent_process()
54 int pid = pvm_parent();
55 if (pid == PvmNoParent)
57 check_error(pid,
"pvm_parent()");
62 BCP_pvm_environment::alive(
const int pid)
64 return pvm_pstat(pid) == PvmOk;
68 BCP_pvm_environment::alive(
const BCP_proc_array& parray)
72 while (first != last) {
87 check_error( pvm_initsend(PvmDataInPlace),
"send() - initsend");
88 check_error( pvm_send(target, tag),
"send() - send");
95 check_error( pvm_initsend(PvmDataInPlace),
"send() - initsend");
96 check_error( pvm_pkbyte(const_cast<char*>(buf.
data()), buf.
size(), 1),
98 check_error( pvm_send(target, tag),
"send() - send");
104 BCP_pvm_environment::multicast(
const BCP_proc_array*
const target,
107 check_error( pvm_initsend(PvmDataInPlace),
"multicast() - initsend");
108 check_error( pvm_mcast(&target->procs()[0], target->size(), tag),
109 "multicast() - send");
113 BCP_pvm_environment::multicast(
const BCP_proc_array*
const target,
117 check_error( pvm_initsend(PvmDataInPlace),
"multicast() - initsend");
118 check_error( pvm_pkbyte(const_cast<char*>(buf.
data()), buf.
size(), 1),
119 "multicast() - pkbyte");
120 check_error( pvm_mcast(&target->procs()[0], target->size(), tag),
121 "multicast() - send");
128 int* pids = BCP_process_vec_2_int(beg, end,
"multicast() - parray_2_int");
129 check_error( pvm_initsend(PvmDataInPlace),
"multicast() - initsend");
130 check_error( pvm_mcast(pids, end - beg, tag),
"multicast() - send");
139 int* pids = BCP_process_vec_2_int(beg, end,
"multicast() - parray_2_int");
140 check_error( pvm_initsend(PvmDataInPlace),
"multicast() - initsend");
141 check_error( pvm_pkbyte(const_cast<char*>(buf.
data()), buf.
size(), 1),
142 "multicast() - pkbyte");
143 check_error( pvm_mcast(pids, end - beg, tag),
"multicast() - send");
150 BCP_pvm_environment::receive(
const int const source,
152 const double timeout) {
156 int pid = source ==
BCP_AnyProcess? -1 : BCP_is_pvm_id(source,
"receive()");
164 tout.tv_sec = 10; tout.tv_usec = 0;
166 check_error( bufid = pvm_trecv(pid, msgtag, &tout),
167 "receive() - trecv");
168 if (pvm_pstat(pid) != PvmOk)
173 check_error( bufid = pvm_recv(pid, msgtag),
"receive() - recv");
176 tout.tv_sec =
static_cast<int>(floor(timeout));
177 tout.tv_usec =
static_cast<int>(floor((timeout - tout.tv_sec)*1e6));
178 check_error( bufid = pvm_trecv(pid, msgtag, &tout),
"receive() - trecv");
186 check_error( pvm_bufinfo(bufid, &bytes, &msgtag, &pid),
187 "receive() - bufinfo");
191 buf.
_sender =
new BCP_pvm_id(pid);
193 check_error( pvm_upkbyte(buf.
_data, bytes, 1),
"receive() - upkbyte");
199 BCP_pvm_environment::probe(
const int const source,
201 int pid = source ==
BCP_AnyProcess? -1 : BCP_is_pvm_id(source,
"probe()");
205 if (pvm_pstat(pid) != PvmOk)
210 int probed = pvm_probe(pid, msgtag);
219 BCP_pvm_environment::unpack_proc_id(
BCP_buffer& buf) {
222 return new BCP_pvm_id(pid);
226 BCP_pvm_environment::pack_proc_id(
BCP_buffer& buf,
const int pid) {
227 buf.
pack(BCP_is_pvm_id(pid,
"pack_proc_id()"));
233 BCP_get_next_word(
const char*& ctmp,
const char* last)
235 for ( ; ctmp != last && !isgraph(*ctmp); ++ctmp);
236 const char* word = ctmp;
237 for ( ; ctmp != last && !isspace(*ctmp); ++ctmp);
240 const int len = ctmp - word;
241 char* new_word =
new char[len + 1];
242 memcpy(new_word, word, len);
248 BCP_pvm_split_exe(
const BCP_string& exe,
char*& exe_name,
char**& exe_args)
250 const char* ctmp = exe.
c_str();
251 const char* last = ctmp + exe.
length();
252 std::vector<char*> arglist;
253 exe_name = BCP_get_next_word(ctmp, last);
254 while (ctmp != last) {
255 char* word = BCP_get_next_word(ctmp, last);
257 arglist.push_back(word);
259 if (arglist.size() == 0) {
262 exe_args =
new char*[arglist.size() + 1];
263 std::copy(arglist.begin(), arglist.end(), exe_args);
264 exe_args[arglist.size()] = 0;
269 BCP_pvm_environment::start_process(
const BCP_string& exe,
const bool debug) {
270 int flag = debug ? PvmTaskDebug : 0;
274 BCP_pvm_split_exe(exe, exe_name, exe_args);
275 pvm_spawn(exe_name, exe_args, flag, 0, 1, &pid);
278 while (*exe_args != 0) {
284 check_error(pid,
"start_process() - spawn");
285 return new BCP_pvm_id(pid);
289 BCP_pvm_environment::start_process(
const BCP_string& exe,
292 int flag = PvmTaskHost | (debug ? PvmTaskDebug : 0);
296 BCP_pvm_split_exe(exe, exe_name, exe_args);
297 pvm_spawn(exe_name, exe_args, flag,
298 const_cast<char*>(machine.
c_str()), 1, &pid);
301 while (*exe_args != 0) {
307 check_error(pid,
"start_process() - spawn");
308 return new BCP_pvm_id(pid);
312 BCP_pvm_environment::start_processes(
const BCP_string& exe,
318 int flag = debug ? PvmTaskDebug : 0;
319 int* pids =
new int[proc_num];
322 BCP_pvm_split_exe(exe, exe_name, exe_args);
323 pvm_spawn(exe_name, exe_args, flag, 0, proc_num, pids);
326 while (*exe_args != 0) {
332 for (
int i = 0; i != proc_num; ++i)
333 check_error(pids[i],
"start_processes() - spawn");
334 for (
int i = 0; i != proc_num; ++i)
335 procs.
push_back(
new BCP_pvm_id(pids[i]));
337 BCP_proc_array* pa =
new BCP_proc_array;
338 pa->add_procs(procs.
begin(), procs.
end());
343 BCP_pvm_environment::start_processes(
const BCP_string& exe,
350 for (
int i = 0; i != proc_num; ++i)
351 procs.
push_back(start_process(exe, machines[i%machines.
size()], debug));
352 BCP_proc_array* pa =
new BCP_proc_array;
353 pa->add_procs(procs.
begin(), procs.
end());
BCP_message_tag
This enumerative constant describes the message tags different processes of BCP understand.
BCP_buffer & pack(const T &value)
Pack a single object of type T.
Used when receiving, message with any message tag will be received.
void send(OSCommandLine *oscommandline, OSnl2OS *osnl2os)
Used to indicate that there is no message in the buffer of a process.
BCP_buffer & unpack(T &value)
Unpack a single object of type T.
int _sender
The process id of the sender of the last received message.
const char * c_str() const
iterator begin()
Return an iterator to the beginning of the object.
void reserve(const size_t n)
Reallocate the object to make space for n entries.
This class is a very simple impelementation of a constant length string.
void push_back(const_reference x)
Append x to the end of the vector.
This class is an abstract base class for the initializer class the user has to provide.
char * _data
Pointer to the buffer itself.
void clear()
Completely clear the buffer.
Currently there isn't any error handling in BCP.
size_t size() const
Return the current number of entries.
iterator end()
Return an iterator to the end of the object.
The class BCP_vec serves the same purpose as the vector class in the standard template library...
size_t _size
The current size of the message (the first _size bytes of the buffer).
This class describes the message buffer used for all processes of BCP.
void make_fit(const int add_size)
Reallocate the buffer if necessary so that at least add_size number of additional bytes will fit into...
const char * data() const
Return a const pointer to the data stored in the buffer.
BCP_message_tag _msgtag
The message tag of the last received message.
int size() const
Return the size of the current message in the buffer.