Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
a4dab1a5889de43e7119d6751ecfddaa0656c43c
[simgrid.git] / src / cxx / Process.cxx
1 #include <Process.hpp>\r
2 \r
3 namespace SimGrid\r
4 {\r
5         namespace Msg\r
6         {\r
7                 Process* Process::currentProcess = NULL;\r
8                 \r
9                 // Default constructor.\r
10                 Process::Process()\r
11                 {\r
12                         this->nativeProcess = NULL;\r
13                 }\r
14                 \r
15                 Process::Process(const char* hostName, const char* name)\r
16                 throw(InvalidArgumentException, HostNotFoundException)\r
17                 {\r
18                         // check the parameters\r
19                         \r
20                         if(!name)\r
21                                 throw NullPointerException("name");\r
22                                 \r
23                         if(!hostName)\r
24                                 throw NullPointerException("hostName");\r
25                         \r
26                         Host host = Host::getByName(hostName);\r
27                                 \r
28                         create(host, name, 0, NULL);    \r
29                 }\r
30                 \r
31                 Process::Process(const Host& rHost, const char* name)\r
32                 throw(NullPointerException)\r
33                 {\r
34                         if(!name)\r
35                                 throw NullPointerException("name");\r
36                                 \r
37                         create(rHost, name, 0, NULL);   \r
38                 }\r
39                 \r
40                 Process::Process(const Host& rHost, const char* name, int argc, char** argv)\r
41                 throw(NullPointerException, InvalidArgumentException, LogicException)\r
42                 {\r
43                         \r
44                         // check the parameters\r
45                         \r
46                         if(!name)\r
47                                 throw NullPointerException("name");\r
48                                 \r
49                         if(!hostName)\r
50                                 throw NullPointerException("hostName");\r
51                                 \r
52                         if(argc < 0)\r
53                                 throw InvalidArgument("argc (must be positive)");\r
54                                 \r
55                         if(!argc && argv)\r
56                                 throw LogicException("argv is not NULL but argc is zero");\r
57                         \r
58                         if(argc && !argv)\r
59                                 throw LogicException("argv is NULL but argc is not zero");\r
60                         \r
61                         create(rHost, name, argc, argv);        \r
62                 }\r
63                 \r
64                 Process::Process(const char* hostname, const char* name, int argc, char** argv)\r
65                 throw(NullPointerException, InvalidArgumentException, LogicException, HostNotFoundException)\r
66                 {\r
67                         // check the parameters\r
68                         \r
69                         if(!name)\r
70                                 throw NullPointerException("name");\r
71                                 \r
72                         if(!hostName)\r
73                                 throw NullPointerException("hostName");\r
74                                 \r
75                         if(argc < 0)\r
76                                 throw InvalidArgument("argc (must be positive)");\r
77                                 \r
78                         if(!argc && argv)\r
79                                 throw LogicException("argv is not NULL but argc is zero");\r
80                         \r
81                         if(argc && !argv)\r
82                                 throw LogicException("argv is NULL but argc is not zero");\r
83                                 \r
84                         Host host = Host::getByName(hostname);\r
85                                 \r
86                         create(host, name, argc, argv); \r
87                 }\r
88                 \r
89                 int Process::killAll(int resetPID) \r
90                 {\r
91                     return MSG_process_killall(resetPID);\r
92                 }\r
93                 \r
94                 void Process::suspend(void)\r
95                 throw(MsgException)\r
96                 {\r
97                     if(MSG_OK != MSG_process_suspend(nativeProcess)) \r
98                         throw MsgException("MSG_process_suspend() failed");\r
99                 }\r
100                 \r
101                 void Process::resume(void) \r
102                 throw(MsgException)\r
103                 {\r
104                         if(MSG_OK != MSG_process_resume(nativeProcess))\r
105                                 throw MsgException("MSG_process_resume() failed");\r
106                 }\r
107                 \r
108                 bool Process::isSuspended(void)\r
109                 {\r
110                    return (bool)MSG_process_is_suspended(nativeProcess);\r
111                 }  \r
112                 \r
113                 Host& Process::getHost(void) \r
114                 {\r
115                   m_host_t nativeHost = MSG_process_get_host(nativeProcess);\r
116                         \r
117                   // return the reference to the Host object\r
118                   return (*((Host*)nativeHost->data));\r
119                 }\r
120                 \r
121                 Process& Process::fromPID(int PID) \r
122                 throw(ProcessNotFoundException, InvalidArgumentException, MsgException)\r
123                 {\r
124                         // check the parameters\r
125                         \r
126                         if(PID < 1)\r
127                                 throw InvalidArgumentException("PID (the PID of the process to retrieve is not less than 1)");\r
128                                 \r
129                         Process* process = NULL;\r
130                         m_process_t nativeProcess = MSG_process_from_PID(PID);\r
131                         \r
132                         if(!nativeProcess) \r
133                                 throw ProcessNotFoundException(PID);\r
134                         \r
135                         process = Process::fromNativeProcess(nativeProcess);\r
136                                 \r
137                         if(!process) \r
138                                 throw MsgException("Process::fromNativeProcess() failed");\r
139                         \r
140                         return (*process);   \r
141                 } \r
142                 \r
143                 int Process::getPID(void)\r
144                 {\r
145                     return MSG_process_get_PID(nativeProcess);\r
146                 }\r
147                 \r
148                 int Process::getPPID(void)\r
149                 {\r
150                         return MSG_process_get_PPID(nativeProcess);\r
151                 }\r
152                 \r
153                 const char* Process::getName(void) const\r
154                 {\r
155                         return nativeProcess->name;\r
156                 }\r
157                 \r
158                 Process& Process::currentProcess(void)\r
159                 throw(MsgException)\r
160                 {\r
161                         Process* currentProcess = NULL;\r
162                     m_process_t currentNativeProcess = MSG_process_self();\r
163                 \r
164                 \r
165                         if(!currentNativeProcess) \r
166                                 throw MsgException("MSG_process_self() failed");\r
167                         \r
168                         currentProcess = Process::fromNativeProcess(currentNativeProcess);\r
169                                 \r
170                         if(!currentProcess) \r
171                                 throw MsgException("Process::fromNativeProcess() failed");\r
172                         \r
173                         return (*currentProcess);  \r
174                 }\r
175                 \r
176                 int Process::currentProcessPID(void)\r
177                 {\r
178                          return MSG_process_self_PID();\r
179                 }\r
180                 \r
181                 \r
182                 int Process::currentProcessPPID(void)\r
183                 {\r
184                         return MSG_process_self_PPID();\r
185                 }\r
186                 \r
187                 void Process::migrate(const Host& rHost)\r
188                 throw(MsgException)\r
189                 {\r
190                         if(MSG_OK != MSG_process_change_host(nativeProcess, rHost.nativeHost))\r
191                                 throw MsgException("MSG_process_change_host()");\r
192                         \r
193                 }\r
194                 \r
195                 void Process::sleep(double seconds)\r
196                 throw(throw(InvalidArgumentException, MsgException))\r
197                 {\r
198                         // check the parameters.\r
199                         if(seconds <= 0)\r
200                                 throw InvalidArgumentException("seconds (must not be less or equals to zero");\r
201                                 \r
202                         if(MSG_OK != MSG_process_sleep(seconds))\r
203                                 throw MsgException("MSG_process_sleep()");\r
204                         \r
205                 }\r
206                 \r
207                 void Process::putTask(const Host& rHost, int channel, const Task& rTask)\r
208                 throw(InvalidArgumentException, MsgException)\r
209                 {\r
210                         // check the parameters\r
211                         \r
212                         if(channel < 0)\r
213                                 throw InvalidArgumentException("channel (must not be negative)");\r
214                                 \r
215                         if(MSG_OK != MSG_task_put_with_timeout(rTask.nativeTask, rHost.nativeHost, channel, -1.0))\r
216                                 throw MsgException("MSG_task_put_with_timeout()");\r
217                 }\r
218                 \r
219                 void Process::putTask(const Host& rHost, int channel, const Task& rTask, double timeout) \r
220                 throw(InvalidArgumentException, MsgException)\r
221                 {\r
222                         // check the parameters\r
223                         if(channel < 0)\r
224                                 throw InvalidArgumentException("channel (must not be negative)");\r
225                                 \r
226                         if(timeout < 0 && timeout != -1.0)\r
227                                 throw InvalidArgumentException("timeout (must not be less than zero an different of -1.0)");\r
228                                 \r
229                         if(MSG_OK != MSG_task_put_with_timeout(rTask.nativeTask, rHost.nativeHost, channel, timeout))\r
230                                 throw MsgException("MSG_task_put_with_timeout() failed");\r
231                 }\r
232                 \r
233                 Task& Process::getTask(int channel) \r
234                 throw(InvalidArgumentException, MsgException)\r
235                 {\r
236                         // check the parameters\r
237                         \r
238                         if(channel < 0)\r
239                                 throw InvalidArgumentException("channel (must not be negative)");\r
240                         \r
241                         m_task_t nativeTask = NULL;\r
242                         \r
243                         if (MSG_OK != MSG_task_get_ext(&nativeTask, channel, -1.0, NULL)) \r
244                                 throw MsgException("MSG_task_get_ext() failed");\r
245                         \r
246                         return (*((Task*)(nativeTask->data)));\r
247                 }\r
248                 \r
249                 Task& Process::getTask(int channel, double timeout) \r
250                 throw(InvalidArgumentException, MsgException)\r
251                 {\r
252                         // check the parameters\r
253                         if(channel < 0)\r
254                                 throw InvalidArgumentException("channel (must not be negative)");\r
255                                 \r
256                         if(timeout < 0 && timeout != -1.0)\r
257                                 throw InvalidArgumentException("timeout (must not be less than zero an different of -1.0)");\r
258                         \r
259                         m_task_t nativeTask = NULL;\r
260                         \r
261                         if (MSG_OK != MSG_task_get_ext(&nativeTask, channel, timeout, NULL)) \r
262                                 throw MsgException("MSG_task_get_ext() failed");\r
263                         \r
264                         return (*((Task*)(nativeTask->data)));\r
265                 }\r
266                 \r
267                 Task& Process::getTask(int channel, const Host& rHost) \r
268                 throw(InvalidArgumentException, MsgException)\r
269                 {\r
270                         // check the parameters\r
271                         if(channel < 0)\r
272                                 throw InvalidArgumentException("channel (must not be negative)");\r
273                                 \r
274                         m_task_t nativeTask = NULL;\r
275                         \r
276                         if (MSG_OK != MSG_task_get_ext(&nativeTask, channel, -1.0, rHost.nativeHost)) \r
277                                 throw MsgException("MSG_task_get_ext() failed");\r
278                         \r
279                         return (*((Task*)(nativeTask->data)));\r
280                 }\r
281                 \r
282                 Task& Process::getTask(int channel, double timeout, const Host& rHost)\r
283                 throw(InvalidArgumentException, MsgException)\r
284                 {\r
285                         // check the parameters\r
286                         if(channel < 0)\r
287                                 throw InvalidArgumentException("channel (must not be negative)");\r
288                                 \r
289                         if(timeout < 0 && timeout != -1.0)\r
290                                 throw InvalidArgumentException("timeout (must not be less than zero an different of -1.0)");\r
291                         \r
292                         m_task_t nativeTask = NULL;     \r
293                         \r
294                         if (MSG_OK != MSG_task_get_ext(&nativeTask, channel, timeout, rHost.nativeHost)) \r
295                                 throw MsgException("MSG_task_get_ext() failed");\r
296                         \r
297                         return (*((Task*)(nativeTask->data)));\r
298                 }\r
299                 \r
300                 void Process::sendTask(const char* alias, const Task& rTask, double timeout) \r
301                 throw(NullPointerException, InvalidArgumentException, MsgException)\r
302                 {\r
303                         // check the parameters\r
304                         \r
305                         if(!alias)\r
306                                 throw NullPointerException("alias");\r
307                         \r
308                         if(timeout < 0 && timeout !=-1.0)\r
309                                 throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)");\r
310                         \r
311                         if(MSG_OK != MSG_task_send_with_timeout(rTask.nativeTask, alias ,timeout))\r
312                                 throw MsgException("MSG_task_send_with_timeout()");\r
313                                 \r
314                 }\r
315                 \r
316                 void Process::sendTask(const char* alias, const Task& rTask) \r
317                 throw(NullPointerException, MsgException)\r
318                 {\r
319                         // check the parameters\r
320                         \r
321                         if(!alias)\r
322                                 throw NullPointerException("alias");\r
323                                 \r
324                         if(MSG_OK != MSG_task_send_with_timeout(rTask.nativeTask, alias ,-1.0))\r
325                                 throw MsgException("MSG_task_send_with_timeout()");\r
326                 }\r
327                 \r
328                 void Process::sendTask(const Task& rTask) \r
329                 throw(BadAllocException, MsgException)\r
330                 {\r
331                         char* alias = (char*)calloc(strlen(Host::currentHost().getName() + strlen(nativeProcess->name) + 2);\r
332                                 \r
333                         if(!alias)\r
334                                 throw BadAllocException("alias");\r
335                                 \r
336                         sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name);\r
337                         \r
338                         MSG_error_t rv = MSG_task_send_with_timeout(rTask.nativeTask, alias ,-1.0);\r
339                         \r
340                         free(alias);\r
341                         \r
342                         if(MSG_OK != rv)\r
343                                 throw MsgException("MSG_task_send_with_timeout()");\r
344                 }\r
345                 \r
346                 void Process::sendTask(const Task& rTask, double timeout) \r
347                 throw(BadAllocException, InvalidArgumentException, MsgException)\r
348                 {\r
349                         // check the parameters\r
350                         \r
351                         if(timeout < 0 && timeout !=-1.0)\r
352                                 throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)");\r
353                         \r
354                         char* alias = (char*)calloc(strlen(Host::currentHost().getName() + strlen(nativeProcess->name) + 2);\r
355                                 \r
356                         if(!alias)\r
357                                 throw BadAllocException("alias");\r
358                                 \r
359                         sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name);\r
360                         \r
361                         MSG_error_t rv = MSG_task_send_with_timeout(rTask.nativeTask, alias ,timeout);\r
362                         \r
363                         free(alias);\r
364                         \r
365                         if(MSG_OK != rv)\r
366                                 throw MsgException("MSG_task_send_with_timeout()");     \r
367                 }\r
368                 \r
369                 Task& Process::receiveTask(const char* alias) \r
370                 throw(NullPointerException, MsgException)\r
371                 {\r
372                         // check the parameters\r
373                         \r
374                         if(!alias)\r
375                                 throw NullPointerException(alias);\r
376                                 \r
377                         m_task_t nativeTask = NULL;\r
378                         \r
379                         if (MSG_OK !=  MSG_task_receive_ext(&nativeTask,alias, -1.0, NULL)) \r
380                                 throw MsgException("MSG_task_receive_ext() failed");\r
381                 \r
382                         return (*((Task*)nativeTask->data));\r
383                 }\r
384                 \r
385                 \r
386                 Task& Process::receiveTask(void) \r
387                 throw(BadAllocException, MsgException)\r
388                 {\r
389                         \r
390                         char* alias = (char*)calloc(strlen(Host::currentHost().getName() + strlen(nativeProcess->name) + 2);\r
391                         \r
392                         if(!alias)\r
393                                 throw BadAllocException("alias");       \r
394                         \r
395                         sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name);\r
396                         \r
397                         m_task_t nativeTask = NULL;\r
398                         \r
399                         MSG_error_t rv = MSG_task_receive_ext(&nativeTask, alias, -1.0, NULL);\r
400                         \r
401                         free(alias);\r
402                         \r
403                         if(MSG_OK !=  rv) \r
404                                 throw MsgException("MSG_task_receive_ext() failed");    \r
405                 \r
406                         return (*((Task*)nativeTask->data));\r
407                 }\r
408                 \r
409                 \r
410                 Task& Process::receiveTask(const char* alias, double timeout) \r
411                 throw(NullPointerException, InvalidArgumentException, MsgException)\r
412                 {\r
413                         // check the parameters\r
414                         \r
415                         if(!alias)\r
416                                 throw NullPointerException("alias");\r
417                                 \r
418                         if(timeout < 0 && timeout !=-1.0)\r
419                                 throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)");\r
420                                 \r
421                         m_task_t nativeTask = NULL;\r
422                         \r
423                         if(MSG_OK !=  MSG_task_receive_ext(&nativeTask, alias, timeout, NULL)) \r
424                                 throw MsgException("MSG_task_receive_ext() failed");            \r
425                 \r
426                         return (*((Task*)nativeTask->data));\r
427                 }\r
428                 \r
429                 \r
430                 Task& Process::receiveTask(double timeout) \r
431                 throw(InvalidArgumentException, BadAllocException, MsgException)\r
432                 {\r
433                         // check the parameters\r
434                         \r
435                         if(timeout < 0 && timeout !=-1.0)\r
436                                 throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)");\r
437                                 \r
438                         \r
439                         char* alias = (char*)calloc(strlen(Host::currentHost().getName() + strlen(nativeProcess->name) + 2);\r
440                         \r
441                         if(!alias)\r
442                                 throw BadAllocException("alias");\r
443                         \r
444                         sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name);\r
445                         \r
446                         m_task_t nativeTask = NULL;\r
447                         \r
448                         MSG_error_t rv = MSG_task_receive_ext(&nativeTask, alias, timeout, NULL);\r
449                         \r
450                         free(alias);\r
451                         \r
452                         if(MSG_OK !=  rv) \r
453                                 throw MsgException("MSG_task_receive_ext() failed");    \r
454                 \r
455                         return (*((Task*)nativeTask->data));\r
456                 }\r
457                 \r
458                 \r
459                 Task& Process::receiveTask(const char* alias, double timeout, const Host& rHost) \r
460                 throw(NullPointerException, InvalidArgumentException, MsgException)\r
461                 {\r
462                         // check the parameters\r
463                         \r
464                         if(!alias)\r
465                                 throw NullPointerException("alias");\r
466                         \r
467                         if(timeout < 0 && timeout !=-1.0)\r
468                                 throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)");\r
469                                 \r
470                         m_task_t nativeTask = NULL;\r
471                         \r
472                         if(MSG_OK !=  MSG_task_receive_ext(&nativeTask, alias, timeout, rHost.nativeHost)) \r
473                                 throw MsgException("MSG_task_receive_ext() failed");\r
474                 \r
475                         return (*((Task*)nativeTask->data));\r
476                 }\r
477                 \r
478                 \r
479                 Task& Process::receiveTask(double timeout, const Host& rHost) \r
480                 throw(BadAllocException, InvalidArgumentException, MsgException)\r
481                 {\r
482                         // check the parameters\r
483                         \r
484                         if(timeout < 0 && timeout !=-1.0)\r
485                                 throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)");\r
486                         \r
487                         char* alias = (char*)calloc(strlen(Host::currentHost().getName() + strlen(nativeProcess->name) + 2);\r
488                         \r
489                         if(!alias)\r
490                                 throw BadAllocException("alias");\r
491                                 \r
492                         sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name);\r
493                         \r
494                         m_task_t nativeTask = NULL;\r
495                         \r
496                         MSG_error_t rv = MSG_task_receive_ext(&nativeTask, alias, timeout, rHost.nativeHost);\r
497                         \r
498                         free(alias);\r
499                         \r
500                         if(MSG_OK !=  rv) \r
501                                 throw MsgException("MSG_task_receive_ext() failed");\r
502                 \r
503                         return (*((Task*)nativeTask->data));\r
504                 }\r
505                 \r
506                 \r
507                 Task& Process::receiveTask(const char* alias, const Host& rHost) \r
508                 throw(NullPointerException, MsgException)\r
509                 {\r
510                         \r
511                         // check the parameters\r
512                         \r
513                         if(!alias)\r
514                                 throw NullPointerException("alias");\r
515                         \r
516                         m_task_t nativeTask = NULL;\r
517                         \r
518                         if(MSG_OK !=   MSG_task_receive_ext(&nativeTask, alias, -1.0, rHost.nativeHost)) \r
519                                 throw MsgException("MSG_task_receive_ext() failed");\r
520                 \r
521                         return (*((Task*)nativeTask->data));\r
522                 }\r
523                 \r
524                 Task& Process::receiveTask(const Host& rHost) \r
525                 throw(BadAllocException, MsgException)\r
526                 {\r
527                         char* alias = (char*)calloc(strlen(Host::currentHost().getName() + strlen(nativeProcess->name) + 2);\r
528                         \r
529                         if(!alias)\r
530                                 throw BadAllocException("alias");\r
531                         \r
532                         sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name);\r
533                         \r
534                         m_task_t nativeTask = NULL;\r
535                         \r
536                         MSG_error_t rv = MSG_task_receive_ext(&nativeTask, alias, -1.0, rHost.nativeHost);\r
537                         \r
538                         free(alias);\r
539                         \r
540                         if(MSG_OK !=  rv) \r
541                                 throw MsgException("MSG_task_receive_ext() failed");\r
542                 \r
543                         return (*((Task*)nativeTask->data));\r
544                 }\r
545                 \r
546                 void Process::create(const Host& rHost, const char* name, int argc, char** argv)\r
547                 throw(HostNotFoundException)\r
548                 {\r
549                         smx_process_t nativeCurrentProcess = NULL;\r
550                         nativeProcess = xbt_new0(s_smx_process_t, 1);\r
551                         smx_simdata_process_t simdata = xbt_new0(s_smx_simdata_process_t, 1);\r
552                         smx_host_t nativeHost = SIMIX_host_get_by_name(rHost.getName());\r
553                         \r
554                         throw HostNotFoundException(rHost.getName());\r
555                         \r
556                         argv = (char**)realloc(argc + 1, sizeo(char*));\r
557                         \r
558                         argv[argc] = (char*)this;\r
559                         \r
560                         // Simulator Data\r
561                         simdata->smx_host = nativeHost;\r
562                         simdata->mutex = NULL;\r
563                         simdata->cond = NULL;\r
564                         simdata->argc = argc;\r
565                         simdata->argv = argv;\r
566                         simdata->context = xbt_context_new(name, Process::run, NULL, NULL, simix_global->cleanup_process_function, nativeProcess, simdata->argc, simdata->argv);\r
567                         \r
568                         /* Process structure */\r
569                         nativeProcess->name = xbt_strdup(name);\r
570                         nativeProcess->simdata = simdata;\r
571                         \r
572                         // Set process data\r
573                         nativeProcess->data = NULL;\r
574                         \r
575                         // Set process properties\r
576                         simdata->properties = NULL;\r
577                         \r
578                         xbt_swag_insert(nativeProcess, nativeHost->simdata->process_list);\r
579                         \r
580                         /* fix current_process, about which xbt_context_start mocks around */\r
581                         nativeCurrentProcess = simix_global->current_process;\r
582                         xbt_context_start(nativeProcess->simdata->context);\r
583                         simix_global->current_process = nativeCurrentProcess;\r
584                         \r
585                         xbt_swag_insert(nativeProcess, simix_global->process_list);\r
586                         DEBUG2("Inserting %s(%s) in the to_run list", nativeProcess->name, nativeHost->name);\r
587                         xbt_swag_insert(nativeProcess, simix_global->process_to_run);\r
588                 }\r
589                 \r
590                 Process& Process::fromNativeProcess(m_process_t nativeProcess)\r
591                 {\r
592                         return (*((Process*)(nativeProcess->simdata->arg[nativeProcess->argc])));\r
593                 }\r
594                 \r
595                 int Process::run(int argc, char** argv)\r
596                 {\r
597                         Process* process =(Process*)argv[argc];\r
598                         \r
599                         return process->main(argc, argv);\r
600                 }\r
601                 \r
602         } // namespace Msg\r
603 \r
604 } // namespace SimGrid