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