4 * Copyright 2006,2007 Martin Quinson, Malek Cherier
\r
5 * All right reserved.
\r
7 * This program is free software; you can redistribute
\r
8 * it and/or modify it under the terms of the license
\r
9 *(GNU LGPL) which comes with this package.
\r
13 /* Process member functions implementation.
\r
16 #include <Process.hpp>
\r
19 #include <ApplicationHandler.hpp>
\r
26 #include <msg/msg.h>
\r
27 #include <msg/private.h>
\r
28 #include <msg/mailbox.h>
\r
37 MSG_IMPLEMENT_DYNAMIC(Process, Object);
\r
39 // Default constructor.
\r
42 this->nativeProcess = NULL;
\r
45 Process::Process(const char* hostName, const char* name)
\r
46 throw(NullPointerException, HostNotFoundException, BadAllocException)
\r
48 // check the parameters
\r
51 throw NullPointerException("name");
\r
54 throw NullPointerException("hostName");
\r
56 Host host = Host::getByName(hostName);
\r
58 create(host, name, 0, NULL);
\r
61 Process::Process(const Host& rHost, const char* name)
\r
62 throw(NullPointerException)
\r
65 throw NullPointerException("name");
\r
67 create(rHost, name, 0, NULL);
\r
70 Process::Process(const Host& rHost, const char* name, int argc, char** argv)
\r
71 throw(NullPointerException, InvalidArgumentException, LogicException)
\r
74 // check the parameters
\r
77 throw NullPointerException("name");
\r
80 throw InvalidArgumentException("argc (must be positive)");
\r
83 throw LogicException("argv is not NULL but argc is zero");
\r
86 throw LogicException("argv is NULL but argc is not zero");
\r
88 create(rHost, name, argc, argv);
\r
91 Process::Process(const char* hostName, const char* name, int argc, char** argv)
\r
92 throw(NullPointerException, InvalidArgumentException, LogicException, HostNotFoundException, BadAllocException)
\r
94 // check the parameters
\r
97 throw NullPointerException("name");
\r
100 throw NullPointerException("hostName");
\r
103 throw InvalidArgumentException("argc (must be positive)");
\r
106 throw LogicException("argv is not NULL but argc is zero");
\r
109 throw LogicException("argv is NULL but argc is not zero");
\r
111 Host host = Host::getByName(hostName);
\r
113 create(host, name, argc, argv);
\r
116 int Process::killAll(int resetPID)
\r
118 return MSG_process_killall(resetPID);
\r
121 void Process::suspend(void)
\r
122 throw(MsgException)
\r
124 if(MSG_OK != MSG_process_suspend(nativeProcess))
\r
125 throw MsgException("MSG_process_suspend() failed");
\r
128 void Process::resume(void)
\r
129 throw(MsgException)
\r
131 if(MSG_OK != MSG_process_resume(nativeProcess))
\r
132 throw MsgException("MSG_process_resume() failed");
\r
135 int Process::isSuspended(void)
\r
137 return MSG_process_is_suspended(nativeProcess);
\r
140 Host& Process::getHost(void)
\r
142 m_host_t nativeHost = MSG_process_get_host(nativeProcess);
\r
144 // return the reference to the Host object
\r
145 return (*((Host*)nativeHost->data));
\r
148 Process& Process::fromPID(int PID)
\r
149 throw(ProcessNotFoundException, InvalidArgumentException, MsgException)
\r
151 // check the parameters
\r
154 throw InvalidArgumentException("PID (the PID of the process to retrieve is not less than 1)");
\r
156 Process* process = NULL;
\r
157 m_process_t nativeProcess = MSG_process_from_PID(PID);
\r
159 if(!nativeProcess)
\r
160 throw ProcessNotFoundException(PID);
\r
162 process = Process::fromNativeProcess(nativeProcess);
\r
165 throw MsgException("Process::fromNativeProcess() failed");
\r
167 return (*process);
\r
170 int Process::getPID(void)
\r
172 return MSG_process_get_PID(nativeProcess);
\r
175 int Process::getPPID(void)
\r
177 return MSG_process_get_PPID(nativeProcess);
\r
180 const char* Process::getName(void) const
\r
182 return nativeProcess->name;
\r
185 Process& Process::currentProcess(void)
\r
186 throw(MsgException)
\r
188 Process* currentProcess = NULL;
\r
189 m_process_t currentNativeProcess = MSG_process_self();
\r
192 if(!currentNativeProcess)
\r
193 throw MsgException("MSG_process_self() failed");
\r
195 currentProcess = Process::fromNativeProcess(currentNativeProcess);
\r
197 if(!currentProcess)
\r
198 throw MsgException("Process::fromNativeProcess() failed");
\r
200 return (*currentProcess);
\r
203 int Process::currentProcessPID(void)
\r
205 return MSG_process_self_PID();
\r
209 int Process::currentProcessPPID(void)
\r
211 return MSG_process_self_PPID();
\r
214 void Process::migrate(const Host& rHost)
\r
215 throw(MsgException)
\r
217 if(MSG_OK != MSG_process_change_host(rHost.nativeHost))
\r
218 throw MsgException("MSG_process_change_host()");
\r
222 void Process::sleep(double seconds)
\r
223 throw(InvalidArgumentException, MsgException)
\r
225 // check the parameters.
\r
227 throw InvalidArgumentException("seconds (must not be less or equals to zero");
\r
229 if(MSG_OK != MSG_process_sleep(seconds))
\r
230 throw MsgException("MSG_process_sleep()");
\r
234 void Process::putTask(const Host& rHost, int channel, Task* task)
\r
235 throw(InvalidArgumentException, MsgException)
\r
237 // check the parameters
\r
240 throw InvalidArgumentException("channel (must not be negative)");
\r
242 if(MSG_OK != MSG_task_put_with_timeout(task->nativeTask, rHost.nativeHost, channel, -1.0))
\r
243 throw MsgException("MSG_task_put_with_timeout()");
\r
246 void Process::putTask(const Host& rHost, int channel, Task* task, double timeout)
\r
247 throw(InvalidArgumentException, MsgException)
\r
249 // check the parameters
\r
251 throw InvalidArgumentException("channel (must not be negative)");
\r
253 if(timeout < 0 && timeout != -1.0)
\r
254 throw InvalidArgumentException("timeout (must not be less than zero an different of -1.0)");
\r
256 if(MSG_OK != MSG_task_put_with_timeout(task->nativeTask, rHost.nativeHost, channel, timeout))
\r
257 throw MsgException("MSG_task_put_with_timeout() failed");
\r
260 Task* Process::getTask(int channel)
\r
261 throw(InvalidArgumentException, MsgException)
\r
263 // check the parameters
\r
266 throw InvalidArgumentException("channel (must not be negative)");
\r
268 m_task_t nativeTask = NULL;
\r
270 if (MSG_OK != MSG_task_get_ext(&nativeTask, channel, -1.0, NULL))
\r
271 throw MsgException("MSG_task_get_ext() failed");
\r
273 return (Task*)(nativeTask->data);
\r
276 Task* Process::getTask(int channel, double timeout)
\r
277 throw(InvalidArgumentException, MsgException)
\r
279 // check the parameters
\r
281 throw InvalidArgumentException("channel (must not be negative)");
\r
283 if(timeout < 0 && timeout != -1.0)
\r
284 throw InvalidArgumentException("timeout (must not be less than zero an different of -1.0)");
\r
286 m_task_t nativeTask = NULL;
\r
288 if (MSG_OK != MSG_task_get_ext(&nativeTask, channel, timeout, NULL))
\r
289 throw MsgException("MSG_task_get_ext() failed");
\r
291 return (Task*)(nativeTask->data);
\r
294 Task* Process::getTask(int channel, const Host& rHost)
\r
295 throw(InvalidArgumentException, MsgException)
\r
297 // check the parameters
\r
299 throw InvalidArgumentException("channel (must not be negative)");
\r
301 m_task_t nativeTask = NULL;
\r
303 if (MSG_OK != MSG_task_get_ext(&nativeTask, channel, -1.0, rHost.nativeHost))
\r
304 throw MsgException("MSG_task_get_ext() failed");
\r
306 return (Task*)(nativeTask->data);
\r
309 Task* Process::getTask(int channel, double timeout, const Host& rHost)
\r
310 throw(InvalidArgumentException, MsgException)
\r
312 // check the parameters
\r
314 throw InvalidArgumentException("channel (must not be negative)");
\r
316 if(timeout < 0 && timeout != -1.0)
\r
317 throw InvalidArgumentException("timeout (must not be less than zero an different of -1.0)");
\r
319 m_task_t nativeTask = NULL;
\r
321 if (MSG_OK != MSG_task_get_ext(&nativeTask, channel, timeout, rHost.nativeHost))
\r
322 throw MsgException("MSG_task_get_ext() failed");
\r
324 return (Task*)(nativeTask->data);
\r
327 void Process::sendTask(const char* alias, Task* task, double timeout)
\r
328 throw(NullPointerException, InvalidArgumentException, MsgException)
\r
330 // check the parameters
\r
333 throw NullPointerException("alias");
\r
335 if(timeout < 0 && timeout !=-1.0)
\r
336 throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)");
\r
338 if(MSG_OK != MSG_task_send_with_timeout(task->nativeTask, alias ,timeout))
\r
339 throw MsgException("MSG_task_send_with_timeout()");
\r
343 void Process::sendTask(const char* alias, Task* task)
\r
344 throw(NullPointerException, MsgException)
\r
346 // check the parameters
\r
349 throw NullPointerException("alias");
\r
351 if(MSG_OK != MSG_task_send_with_timeout(task->nativeTask, alias ,-1.0))
\r
352 throw MsgException("MSG_task_send_with_timeout()");
\r
355 void Process::sendTask(Task* task)
\r
356 throw(BadAllocException, MsgException)
\r
358 char* alias = (char*)calloc( strlen(this->getHost().getName()) + strlen(nativeProcess->name) + 2, sizeof(char));
\r
361 throw BadAllocException("alias");
\r
363 sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name);
\r
365 MSG_error_t rv = MSG_task_send_with_timeout(task->nativeTask, alias ,-1.0);
\r
370 throw MsgException("MSG_task_send_with_timeout()");
\r
373 void Process::sendTask(Task* task, double timeout)
\r
374 throw(BadAllocException, InvalidArgumentException, MsgException)
\r
376 // check the parameters
\r
378 if(timeout < 0 && timeout !=-1.0)
\r
379 throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)");
\r
381 char* alias = (char*)calloc( strlen(this->getHost().getName()) + strlen(nativeProcess->name) + 2, sizeof(char));
\r
384 throw BadAllocException("alias");
\r
386 sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name);
\r
388 MSG_error_t rv = MSG_task_send_with_timeout(task->nativeTask, alias ,timeout);
\r
393 throw MsgException("MSG_task_send_with_timeout()");
\r
396 Task* Process::receiveTask(const char* alias)
\r
397 throw(NullPointerException, MsgException)
\r
399 // check the parameters
\r
402 throw NullPointerException(alias);
\r
404 m_task_t nativeTask = NULL;
\r
406 if (MSG_OK != MSG_task_receive_ext(&nativeTask,alias, -1.0, NULL))
\r
407 throw MsgException("MSG_task_receive_ext() failed");
\r
409 return (Task*)(nativeTask->data);
\r
413 Task* Process::receiveTask(void)
\r
414 throw(BadAllocException, MsgException)
\r
417 char* alias = (char*)calloc( strlen(this->getHost().getName()) + strlen(nativeProcess->name) + 2, sizeof(char));
\r
420 throw BadAllocException("alias");
\r
422 sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name);
\r
424 m_task_t nativeTask = NULL;
\r
426 MSG_error_t rv = MSG_task_receive_ext(&nativeTask, alias, -1.0, NULL);
\r
431 throw MsgException("MSG_task_receive_ext() failed");
\r
433 return (Task*)(nativeTask->data);
\r
437 Task* Process::receiveTask(const char* alias, double timeout)
\r
438 throw(NullPointerException, InvalidArgumentException, MsgException)
\r
440 // check the parameters
\r
443 throw NullPointerException("alias");
\r
445 if(timeout < 0 && timeout !=-1.0)
\r
446 throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)");
\r
448 m_task_t nativeTask = NULL;
\r
450 if(MSG_OK != MSG_task_receive_ext(&nativeTask, alias, timeout, NULL))
\r
451 throw MsgException("MSG_task_receive_ext() failed");
\r
453 return (Task*)(nativeTask->data);
\r
457 Task* Process::receiveTask(double timeout)
\r
458 throw(InvalidArgumentException, BadAllocException, MsgException)
\r
460 // check the parameters
\r
462 if(timeout < 0 && timeout !=-1.0)
\r
463 throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)");
\r
466 char* alias = (char*)calloc( strlen(this->getHost().getName()) + strlen(nativeProcess->name) + 2, sizeof(char));
\r
469 throw BadAllocException("alias");
\r
471 sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name);
\r
473 m_task_t nativeTask = NULL;
\r
475 MSG_error_t rv = MSG_task_receive_ext(&nativeTask, alias, timeout, NULL);
\r
480 throw MsgException("MSG_task_receive_ext() failed");
\r
482 return (Task*)(nativeTask->data);
\r
486 Task* Process::receiveTask(const char* alias, double timeout, const Host& rHost)
\r
487 throw(NullPointerException, InvalidArgumentException, MsgException)
\r
489 // check the parameters
\r
492 throw NullPointerException("alias");
\r
494 if(timeout < 0 && timeout !=-1.0)
\r
495 throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)");
\r
497 m_task_t nativeTask = NULL;
\r
499 if(MSG_OK != MSG_task_receive_ext(&nativeTask, alias, timeout, rHost.nativeHost))
\r
500 throw MsgException("MSG_task_receive_ext() failed");
\r
502 return (Task*)(nativeTask->data);
\r
506 Task* Process::receiveTask(double timeout, const Host& rHost)
\r
507 throw(BadAllocException, InvalidArgumentException, MsgException)
\r
509 // check the parameters
\r
511 if(timeout < 0 && timeout !=-1.0)
\r
512 throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)");
\r
514 char* alias = (char*)calloc( strlen(this->getHost().getName()) + strlen(nativeProcess->name) + 2, sizeof(char));
\r
517 throw BadAllocException("alias");
\r
519 sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name);
\r
521 m_task_t nativeTask = NULL;
\r
523 MSG_error_t rv = MSG_task_receive_ext(&nativeTask, alias, timeout, rHost.nativeHost);
\r
528 throw MsgException("MSG_task_receive_ext() failed");
\r
530 return (Task*)(nativeTask->data);
\r
534 Task* Process::receiveTask(const char* alias, const Host& rHost)
\r
535 throw(NullPointerException, MsgException)
\r
538 // check the parameters
\r
541 throw NullPointerException("alias");
\r
543 m_task_t nativeTask = NULL;
\r
545 if(MSG_OK != MSG_task_receive_ext(&nativeTask, alias, -1.0, rHost.nativeHost))
\r
546 throw MsgException("MSG_task_receive_ext() failed");
\r
548 return (Task*)(nativeTask->data);
\r
551 Task* Process::receiveTask(const Host& rHost)
\r
552 throw(BadAllocException, MsgException)
\r
554 char* alias = (char*)calloc( strlen(this->getHost().getName()) + strlen(nativeProcess->name) + 2, sizeof(char));
\r
557 throw BadAllocException("alias");
\r
559 sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name);
\r
561 m_task_t nativeTask = NULL;
\r
563 MSG_error_t rv = MSG_task_receive_ext(&nativeTask, alias, -1.0, rHost.nativeHost);
\r
568 throw MsgException("MSG_task_receive_ext() failed");
\r
570 return (Task*)(nativeTask->data);
\r
573 void Process::create(const Host& rHost, const char* name, int argc, char** argv)
\r
574 throw(InvalidArgumentException)
\r
576 char alias[MAX_ALIAS_NAME + 1] = {0};
\r
577 msg_mailbox_t mailbox;
\r
580 // try to retrieve the host where to createt the process from its name
\r
581 m_host_t nativeHost = rHost.nativeHost;
\r
584 throw InvalidArgumentException("rHost");
\r
586 /* allocate the data of the simulation */
\r
587 this->nativeProcess = xbt_new0(s_m_process_t,1);
\r
588 this->nativeProcess->simdata = xbt_new0(s_simdata_process_t,1);
\r
589 this->nativeProcess->name = _strdup(name);
\r
590 this->nativeProcess->simdata->m_host = nativeHost;
\r
591 this->nativeProcess->simdata->PID = msg_global->PID++;
\r
593 // realloc the list of the argument to add the pointer to this process instance at the end
\r
595 argv = (char**)realloc(argv , (argc + 1) * sizeof(char*));
\r
597 argv = (char**)calloc(1 ,sizeof(char*));
\r
599 // add the pointer to this instance at the end of the list of the arguments of the process
\r
600 // so the static method Process::run() (passed as argument of the MSG function xbt_context_new())
\r
601 // can retrieve the concerned process object by the run
\r
602 // so Process::run() can call the method main() of the good process
\r
603 // for more detail see Process::run() method
\r
604 argv[argc] = (char*)this;
\r
606 this->nativeProcess->simdata->argc = argc;
\r
607 this->nativeProcess->simdata->argv = argv;
\r
609 this->nativeProcess->simdata->s_process = SIMIX_process_create(
\r
610 this->nativeProcess->name,
\r
612 (void*)this->nativeProcess,
\r
618 if (SIMIX_process_self())
\r
619 {/* someone created me */
\r
620 this->nativeProcess->simdata->PPID = MSG_process_get_PID((m_process_t)SIMIX_process_self()->data);
\r
624 this->nativeProcess->simdata->PPID = -1;
\r
627 this->nativeProcess->simdata->last_errno = MSG_OK;
\r
629 /* add the process to the list of the processes of the simulation */
\r
630 xbt_fifo_unshift(msg_global->process_list, this->nativeProcess);
\r
632 sprintf(alias,"%s:%s",(this->nativeProcess->simdata->m_host->simdata->smx_host)->name,this->nativeProcess->name);
\r
634 mailbox = MSG_mailbox_new(alias);
\r
636 MSG_mailbox_set_hostname(mailbox, this->nativeProcess->simdata->m_host->simdata->smx_host->name);
\r
639 Process* Process::fromNativeProcess(m_process_t nativeProcess)
\r
641 return ((Process*)(nativeProcess->simdata->argv[nativeProcess->simdata->argc]));
\r
644 int Process::run(int argc, char** argv)
\r
647 // the last argument of the process is the pointer to the process to run
\r
648 // for more detail see Process::create() method
\r
649 return ((Process*)argv[argc])->main(argc, argv);
\r
652 int Process::main(int argc, char** argv)
\r
654 throw LogicException("Process::main() not implemented");
\r
657 /*void* Process::operator new(size_t size)
\r
662 void Process::operator delete(void* p)
\r
669 } // namespace SimGrid
\r