Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
db4722bf4508d75f9115780f306e8363b7946437
[simgrid.git] / src / cxx / Host.cxx
1 /*\r
2  * Host.cxx\r
3  *\r
4  * Copyright 2006,2007 Martin Quinson, Malek Cherier           \r
5  * All right reserved. \r
6  *\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
10  *\r
11  */\r
12  \r
13  /* Host class member functions implementation.\r
14   */  \r
15 #include <Host.hpp>\r
16 \r
17 #include <InvalidArgumentException.hpp>\r
18 #include <BadAllocException.hpp>\r
19 #include <HostNotFoundException.hpp>\r
20 #include <MsgException.hpp>\r
21 \r
22 #include <Task.hpp>\r
23 #include <Process.hpp>\r
24 \r
25 #include <stdlib.h>\r
26 #include <stdio.h>\r
27 \r
28 #include <msg/msg.h>\r
29 #include <msg/private.h>\r
30 \r
31 #include <xbt/fifo.h>\r
32 \r
33 namespace SimGrid\r
34 {\r
35         namespace Msg\r
36         {\r
37                 Host::Host()\r
38                 {\r
39                         nativeHost = NULL;\r
40                         data = NULL;\r
41                 }\r
42                 \r
43                 Host::Host(const Host& rHost)\r
44                 {\r
45                         this->nativeHost = rHost.nativeHost;\r
46                         this->data = rHost.getData();   \r
47                 }\r
48                 \r
49                 Host::~Host()\r
50                 {\r
51                         // NOTHING TODO\r
52                 }\r
53                 \r
54                 \r
55                 Host& Host::getByName(const char* hostName)\r
56                 throw(HostNotFoundException, InvalidArgumentException, BadAllocException)\r
57                 {\r
58                         // check the parameters\r
59                         if(!hostName)\r
60                                 throw InvalidArgumentException("hostName");\r
61                                 \r
62                         m_host_t nativeHost = NULL;     // native host.\r
63                         Host* host = NULL;                      // wrapper host.\r
64                         \r
65                         if(!(nativeHost = MSG_get_host_by_name(hostName))) \r
66                                 throw HostNotFoundException(hostName);\r
67                         \r
68                         if(!nativeHost->data) \r
69                         { // native host not associated yet with  its wrapper\r
70                         \r
71                                 // instanciate a new wrapper \r
72                                 if(!(host = new Host()))\r
73                                         throw BadAllocException(hostName);\r
74                                 \r
75                                 host->nativeHost = nativeHost; \r
76                         \r
77                                 // the native host data field is set with its wrapper returned \r
78                                 nativeHost->data = (void*)host;\r
79                         }\r
80                         \r
81                         // return the reference to cxx wrapper\r
82                         return *((Host*)nativeHost->data);                              \r
83                 }\r
84                 \r
85                 int Host::getNumber(void)\r
86                 {\r
87                         return MSG_get_host_number();\r
88                 }\r
89                 \r
90                 Host& Host::currentHost(void)\r
91                 {\r
92                         Host* host = NULL;\r
93                         m_host_t nativeHost = MSG_host_self();\r
94                         \r
95                         if(!nativeHost->data) \r
96                         {\r
97                                 // the native host not yet associated with its wrapper\r
98                         \r
99                                 // instanciate a new wrapper\r
100                                 host = new Host();\r
101                         \r
102                                 host->nativeHost = nativeHost;\r
103                         \r
104                                 nativeHost->data = (void*)host;\r
105                         } \r
106                         else \r
107                         {\r
108                                 host = (Host*)nativeHost->data;\r
109                         }\r
110                         \r
111                         return *host;\r
112                 }\r
113                 \r
114                 void Host::all(Host*** hosts, int* len) \r
115                 throw(InvalidArgumentException, BadAllocException) \r
116                 {\r
117                         // check the parameters\r
118                         if(!hosts)\r
119                                 throw InvalidArgumentException("hosts");\r
120                                 \r
121                         if(len < 0)\r
122                                 throw InvalidArgumentException("len parameter must be positive");\r
123                         \r
124                         int count = xbt_fifo_size(msg_global->host);\r
125                         \r
126                         if(*len < count)\r
127                                 throw InvalidArgumentException("len parameter must be more than the number of installed host\n (use Host::getNumber() to get the number of hosts)");\r
128                         \r
129                         int index;\r
130                         m_host_t nativeHost;\r
131                         Host* host;\r
132                 \r
133                         m_host_t* table = (m_host_t *)xbt_fifo_to_array(msg_global->host);\r
134                         \r
135                         for(index = 0; index < count; index++) \r
136                         {\r
137                                 nativeHost = table[index];\r
138                                 host = (Host*)(nativeHost->data);\r
139                         \r
140                                 if(!host) \r
141                                 {\r
142                                         if(!(host = new Host()))\r
143                                         {\r
144                                                 // release all allocated memory.\r
145                                                 for(int i = 0; i < index; i++)\r
146                                                         delete (*(hosts)[i]);\r
147                                                 \r
148                                                 throw BadAllocException("to fill the table of the hosts installed on your platform");\r
149                                         }\r
150                                         \r
151                                         host->nativeHost = nativeHost;\r
152                                         nativeHost->data = (void*)host;\r
153                                 }\r
154                                 \r
155                                 (*hosts)[index] = host;\r
156                   }\r
157                 \r
158                   *len = count;  \r
159                 }\r
160                 \r
161                 const char* Host::getName(void) const\r
162                 {\r
163                         return nativeHost->name;\r
164                 }\r
165                 \r
166                 void Host::setData(void* data)\r
167                 {\r
168                         this->data = data;\r
169                 }\r
170                 \r
171                 void* Host::getData(void) const\r
172                 {\r
173                         return this->data;\r
174                 }\r
175                 \r
176                 int Host::getRunningTaskNumber(void) const\r
177                 {\r
178                         return MSG_get_host_msgload(nativeHost); \r
179                 }\r
180                 \r
181                 double Host::getSpeed(void) const\r
182                 {\r
183                         return MSG_get_host_speed(nativeHost);\r
184                 }\r
185                 \r
186                 bool Host::hasData(void) const\r
187                 {\r
188                         return (NULL != this->data);\r
189                 }\r
190                 \r
191                 int Host::isAvailable(void) const\r
192                 {\r
193                         return SIMIX_host_get_state(nativeHost->simdata->smx_host);\r
194                 }\r
195                 \r
196                 void Host::put(int channel, const Task& rTask) \r
197                 throw(MsgException, InvalidArgumentException)\r
198                 {\r
199                         // checks the parameters\r
200                         if(channel < 0)\r
201                                 throw InvalidArgumentException("channel (must be more or equal to zero)");\r
202                                 \r
203                         if(MSG_OK != MSG_task_put_with_timeout(rTask.nativeTask, nativeHost, channel , -1.0))\r
204                                 throw MsgException("MSG_task_put_with_timeout() failed");\r
205                 } \r
206 \r
207                 void Host::put(int channel, Task* task) \r
208                 throw(MsgException, InvalidArgumentException)\r
209                 {\r
210                         // checks the parameters\r
211                         if(channel < 0)\r
212                                 throw InvalidArgumentException("channel (must be more or equal to zero)");\r
213                                 \r
214                         if(MSG_OK != MSG_task_put_with_timeout(task->nativeTask, nativeHost, channel , -1.0))\r
215                                 throw MsgException("MSG_task_put_with_timeout() failed");\r
216                 } \r
217                 \r
218                 void Host::put(int channel, const Task& rTask, double timeout) \r
219                 throw(MsgException, InvalidArgumentException) \r
220                 {\r
221                         // checks the parameters\r
222                         if(channel < 0)\r
223                                 throw InvalidArgumentException("channel (must be more or equal to zero)");\r
224                                 \r
225                         if(timeout < 0.0 && timeout != -1.0)\r
226                                 throw InvalidArgumentException("timeout (must be more or equal to zero or equal to -1.0)");     \r
227                                 \r
228                                 \r
229                     if(MSG_OK != MSG_task_put_with_timeout(rTask.nativeTask, nativeHost, channel , timeout))\r
230                                 throw MsgException("MSG_task_put_with_timeout() failed");\r
231                 }\r
232                 \r
233                 void Host::putBounded(int channel, const Task& rTask, double maxRate) \r
234                 throw(MsgException, InvalidArgumentException)\r
235                 {\r
236                     // checks the parameters\r
237                         if(channel < 0)\r
238                                 throw InvalidArgumentException("channel (must be more or equal to zero)");\r
239                                 \r
240                         if(maxRate < 0.0 && maxRate != -1.0)\r
241                                 throw InvalidArgumentException("maxRate (must be more or equal to zero or equal to -1.0)");     \r
242                     \r
243                         if(MSG_OK != MSG_task_put_bounded(rTask.nativeTask, nativeHost, channel, maxRate))\r
244                                 throw MsgException("MSG_task_put_bounded() failed");\r
245                 }\r
246                 \r
247                 void Host::send(const Task& rTask) \r
248                 throw(MsgException)  \r
249                 {       \r
250                         MSG_error_t rv;\r
251                         \r
252                         char* alias = (char*)calloc(strlen(this->getName())+ strlen(Process::currentProcess().getName()) + 2, sizeof(char));\r
253                                 \r
254                         if(!alias)\r
255                                 throw BadAllocException("alias");\r
256                                 \r
257                         sprintf(alias,"%s:%s", this->getName(),Process::currentProcess().getName());\r
258                                 \r
259                         rv = MSG_task_send_with_timeout(rTask.nativeTask, alias, -1.0);\r
260                         \r
261                         free(alias);\r
262                         \r
263                         if(MSG_OK != rv)\r
264                                 throw MsgException("MSG_task_send_with_timeout() failed");\r
265                 } \r
266                 \r
267                 void Host::send(const char* alias, const Task& rTask) \r
268                 throw(InvalidArgumentException, MsgException) \r
269                 {\r
270                         // check the parameters\r
271                         if(!alias)\r
272                                 throw InvalidArgumentException("alias (must not be NULL)");\r
273                         \r
274                         if(MSG_OK != MSG_task_send_with_timeout(rTask.nativeTask, alias, -1.0))\r
275                                 throw MsgException("MSG_task_send_with_timeout() failed");\r
276                 }\r
277                 \r
278                 void Host::send(const Task& rTask, double timeout) \r
279                 throw(InvalidArgumentException, BadAllocException, MsgException) \r
280                 {\r
281                         // check the parameters\r
282                         if(timeout < 0 && timeout != -1.0)\r
283                                 throw InvalidArgumentException("timeout (must be positive or equal to zero or equal to -1.0)");\r
284                         \r
285                         MSG_error_t rv;\r
286                         \r
287                         char* alias = (char*)calloc(strlen(this->getName()) + strlen(Process::currentProcess().getName()) + 2, sizeof(char));\r
288                                 \r
289                         if(!alias)\r
290                                 throw BadAllocException("alias");\r
291                                 \r
292                         sprintf(alias,"%s:%s", this->getName(),Process::currentProcess().getName());\r
293                                 \r
294                                 \r
295                         rv = MSG_task_send_with_timeout(rTask.nativeTask, alias, timeout);\r
296                         \r
297                         free(alias);\r
298                         \r
299                         if(MSG_OK != rv)\r
300                                 throw MsgException("MSG_task_send_with_timeout() failed");\r
301                 }\r
302                 \r
303                 void Host::send(const char* alias, const Task& rTask, double timeout) \r
304                 throw(InvalidArgumentException, MsgException) \r
305                 {\r
306                         // check the parameter\r
307                         \r
308                         if(!alias)\r
309                                 throw InvalidArgumentException("alias (must not be NULL)");\r
310                                 \r
311                         if(timeout < 0 && timeout != -1.0)\r
312                                 throw InvalidArgumentException("timeout (must be positive or equal to zero or equal to -1.0)");\r
313                                         \r
314                         if(MSG_OK != MSG_task_send_with_timeout(rTask.nativeTask, alias, timeout))\r
315                                 throw MsgException("MSG_task_send_with_timeout() failed");\r
316                 }\r
317                 \r
318                 \r
319                 void Host::sendBounded(const Task& rTask, double maxRate) \r
320                 throw(InvalidArgumentException, BadAllocException, MsgException) \r
321                 {\r
322                         if(maxRate < 0 && maxRate != -1.0)\r
323                                 throw InvalidArgumentException("maxRate (must be positive or equal to zero or equal to -1.0)");\r
324                         \r
325                         MSG_error_t rv;\r
326                         \r
327                         char* alias = (char*)calloc(strlen(this->getName()) + strlen(Process::currentProcess().getName()) + 2, sizeof(char));\r
328                         \r
329                         if(!alias)\r
330                                 throw BadAllocException("alias");\r
331                                 \r
332                         sprintf(alias,"%s:%s", this->getName(),Process::currentProcess().getName());\r
333                                 \r
334                         rv = MSG_task_send_bounded(rTask.nativeTask, alias, maxRate);\r
335                         \r
336                         free(alias);\r
337                         \r
338                         if(MSG_OK != rv)\r
339                                 throw MsgException("MSG_task_send_bounded() failed");\r
340                 }  \r
341                 \r
342                 void Host::sendBounded(const char* alias, const Task& rTask, double maxRate) \r
343                 throw(InvalidArgumentException, MsgException) \r
344                 {\r
345                         // check the parameters\r
346                         if(!alias)\r
347                                 throw InvalidArgumentException("alias (must not be NULL)");\r
348                         \r
349                         if(maxRate < 0 && maxRate != -1)\r
350                                 throw InvalidArgumentException("maxRate (must be positive or equal to zero or equal to -1.0)");\r
351                         \r
352                         if(MSG_OK != MSG_task_send_bounded(rTask.nativeTask, alias, maxRate))\r
353                                 throw MsgException("MSG_task_send_bounded() failed");\r
354                         \r
355                 }\r
356         } // namspace Msg\r
357 } // namespace SimGrid