Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid
[simgrid.git] / src / simix / smx_smurf.c
1 #include "smx_private.h"
2 #include "xbt/fifo.h"
3 #include "xbt/xbt_os_thread.h"
4
5 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_smurf, simix,
6                                 "Logging specific to SIMIX (SMURF)");
7
8 XBT_INLINE smx_simcall_t SIMIX_simcall_mine()
9 {
10   smx_process_t issuer = SIMIX_process_self();
11   return &issuer->simcall;
12 }
13
14 /**
15  * \brief Makes the current process do a simcall to the kernel and yields
16  * until completion.
17  * \param self the current process
18  */
19 void SIMIX_simcall_push(smx_process_t self)
20 {
21   if (self != simix_global->maestro_process) {
22     XBT_DEBUG("Yield process '%s' on simcall %s (%d)", self->name,
23               SIMIX_simcall_name(self->simcall.call), (int)self->simcall.call);
24     SIMIX_process_yield(self);
25   } else {
26     SIMIX_simcall_pre(&self->simcall, 0);
27   }
28 }
29
30 void SIMIX_simcall_answer(smx_simcall_t simcall)
31 {
32   if (simcall->issuer != simix_global->maestro_process){
33     XBT_DEBUG("Answer simcall %s (%d) issued by %s (%p)", SIMIX_simcall_name(simcall->call), (int)simcall->call,
34         simcall->issuer->name, simcall->issuer);
35     simcall->issuer->simcall.call = SIMCALL_NONE;
36     if(!xbt_dynar_member(simix_global->process_to_run, &(simcall->issuer)))
37       xbt_dynar_push_as(simix_global->process_to_run, smx_process_t, simcall->issuer);
38     else
39       DIE_IMPOSSIBLE;
40   }
41 }
42
43 void SIMIX_simcall_pre(smx_simcall_t simcall, int value)
44 {
45   XBT_DEBUG("Handling simcall %p: %s", simcall, SIMIX_simcall_name(simcall->call));
46
47   switch (simcall->call) {
48     case SIMCALL_COMM_TEST:
49       SIMIX_pre_comm_test(simcall);
50       break;
51
52     case SIMCALL_COMM_TESTANY:
53       SIMIX_pre_comm_testany(simcall, value);
54       break;
55
56     case SIMCALL_COMM_WAIT:
57       SIMIX_pre_comm_wait(simcall,
58           simcall->comm_wait.comm,
59           simcall->comm_wait.timeout,
60           value);
61       break;
62
63     case SIMCALL_COMM_WAITANY:
64       SIMIX_pre_comm_waitany(simcall, value);
65       break;
66
67     case SIMCALL_COMM_SEND:
68     {
69       smx_action_t comm = SIMIX_comm_isend(
70           simcall->issuer,
71           simcall->comm_send.rdv,
72           simcall->comm_send.task_size,
73           simcall->comm_send.rate,
74           simcall->comm_send.src_buff,
75           simcall->comm_send.src_buff_size,
76           simcall->comm_send.match_fun,
77           NULL, /* no clean function since it's not detached */
78           simcall->comm_send.data,
79           0);
80       SIMIX_pre_comm_wait(simcall, comm, simcall->comm_send.timeout, 0);
81       break;
82     }
83
84     case SIMCALL_COMM_ISEND:
85       simcall->comm_isend.result = SIMIX_comm_isend(
86           simcall->issuer,
87           simcall->comm_isend.rdv,
88           simcall->comm_isend.task_size,
89           simcall->comm_isend.rate,
90           simcall->comm_isend.src_buff,
91           simcall->comm_isend.src_buff_size,
92           simcall->comm_isend.match_fun,
93           simcall->comm_isend.clean_fun,
94           simcall->comm_isend.data,
95           simcall->comm_isend.detached);
96       SIMIX_simcall_answer(simcall);
97       break;
98
99     case SIMCALL_COMM_RECV:
100     {
101       smx_action_t comm = SIMIX_comm_irecv(
102           simcall->issuer,
103           simcall->comm_recv.rdv,
104           simcall->comm_recv.dst_buff,
105           simcall->comm_recv.dst_buff_size,
106           simcall->comm_recv.match_fun,
107           simcall->comm_recv.data);
108       SIMIX_pre_comm_wait(simcall, comm, simcall->comm_recv.timeout, 0);
109       break;
110     }
111
112     case SIMCALL_COMM_IRECV:
113       simcall->comm_irecv.result = SIMIX_comm_irecv(
114           simcall->issuer,
115           simcall->comm_irecv.rdv,
116           simcall->comm_irecv.dst_buff,
117           simcall->comm_irecv.dst_buff_size,
118           simcall->comm_irecv.match_fun,
119           simcall->comm_irecv.data);
120       SIMIX_simcall_answer(simcall);
121       break;
122
123     case SIMCALL_COMM_DESTROY:
124       SIMIX_comm_destroy(simcall->comm_destroy.comm);
125       SIMIX_simcall_answer(simcall);
126       break;
127
128     case SIMCALL_COMM_CANCEL:
129       SIMIX_comm_cancel(simcall->comm_cancel.comm);
130       SIMIX_simcall_answer(simcall);
131       break;
132
133     case SIMCALL_COMM_GET_REMAINS:
134       simcall->comm_get_remains.result =
135           SIMIX_comm_get_remains(simcall->comm_get_remains.comm);
136       SIMIX_simcall_answer(simcall);
137       break;
138
139     case SIMCALL_COMM_GET_STATE:
140       simcall->comm_get_state.result =
141           SIMIX_comm_get_state(simcall->comm_get_state.comm);
142       SIMIX_simcall_answer(simcall);
143       break;
144
145     case SIMCALL_COMM_GET_SRC_DATA:
146       simcall->comm_get_src_data.result = SIMIX_comm_get_src_data(simcall->comm_get_src_data.comm);
147       SIMIX_simcall_answer(simcall);
148       break;
149
150     case SIMCALL_COMM_GET_DST_DATA:
151       simcall->comm_get_dst_data.result = SIMIX_comm_get_dst_data(simcall->comm_get_dst_data.comm);
152       SIMIX_simcall_answer(simcall);
153       break;
154
155     case SIMCALL_COMM_GET_SRC_PROC:
156       simcall->comm_get_src_proc.result =
157           SIMIX_comm_get_src_proc(simcall->comm_get_src_proc.comm);
158       SIMIX_simcall_answer(simcall);
159       break;
160
161     case SIMCALL_COMM_GET_DST_PROC:
162       simcall->comm_get_dst_proc.result =
163           SIMIX_comm_get_dst_proc(simcall->comm_get_dst_proc.comm);
164       SIMIX_simcall_answer(simcall);
165       break;
166
167 #ifdef HAVE_LATENCY_BOUND_TRACKING
168     case SIMCALL_COMM_IS_LATENCY_BOUNDED:
169       simcall->comm_is_latency_bounded.result =
170           SIMIX_comm_is_latency_bounded(simcall->comm_is_latency_bounded.comm);
171       SIMIX_simcall_answer(simcall);
172       break;
173 #endif
174
175     case SIMCALL_RDV_CREATE:
176       simcall->rdv_create.result = SIMIX_rdv_create(simcall->rdv_create.name);
177       SIMIX_simcall_answer(simcall);
178       break;
179
180     case SIMCALL_RDV_DESTROY:
181       SIMIX_rdv_destroy(simcall->rdv_destroy.rdv);
182       SIMIX_simcall_answer(simcall);
183       break;
184
185     case SIMCALL_RDV_GEY_BY_NAME:
186       simcall->rdv_get_by_name.result =
187         SIMIX_rdv_get_by_name(simcall->rdv_get_by_name.name);
188       SIMIX_simcall_answer(simcall);
189       break;
190
191     case SIMCALL_RDV_COMM_COUNT_BY_HOST:
192       simcall->rdv_comm_count_by_host.result = SIMIX_rdv_comm_count_by_host(
193           simcall->rdv_comm_count_by_host.rdv,
194           simcall->rdv_comm_count_by_host.host);
195       SIMIX_simcall_answer(simcall);
196       break;
197
198     case SIMCALL_RDV_GET_HEAD:
199       simcall->rdv_get_head.result = SIMIX_rdv_get_head(simcall->rdv_get_head.rdv);
200       SIMIX_simcall_answer(simcall);
201       break;
202
203     case SIMCALL_HOST_GET_BY_NAME:
204       simcall->host_get_by_name.result =
205         SIMIX_host_get_by_name(simcall->host_get_by_name.name);
206       SIMIX_simcall_answer(simcall);
207       break;
208
209     case SIMCALL_HOST_GET_NAME:
210       simcall->host_get_name.result =   SIMIX_host_get_name(simcall->host_get_name.host);
211       SIMIX_simcall_answer(simcall);
212       break;
213
214     case SIMCALL_HOST_GET_PROPERTIES:
215       simcall->host_get_properties.result =
216         SIMIX_host_get_properties(simcall->host_get_properties.host);
217       SIMIX_simcall_answer(simcall);
218       break;
219
220     case SIMCALL_HOST_GET_SPEED:
221       simcall->host_get_speed.result = 
222         SIMIX_host_get_speed(simcall->host_get_speed.host);
223       SIMIX_simcall_answer(simcall);
224       break;
225
226     case SIMCALL_HOST_GET_AVAILABLE_SPEED:
227       simcall->host_get_available_speed.result =
228         SIMIX_host_get_available_speed(simcall->host_get_available_speed.host);
229       SIMIX_simcall_answer(simcall);
230       break;
231
232     case SIMCALL_HOST_GET_STATE:
233       simcall->host_get_state.result = 
234         SIMIX_host_get_state(simcall->host_get_state.host);
235       SIMIX_simcall_answer(simcall);
236       break;
237
238     case SIMCALL_HOST_GET_DATA:
239       simcall->host_get_data.result =   SIMIX_host_get_data(simcall->host_get_data.host);
240       SIMIX_simcall_answer(simcall);
241       break;
242
243     case SIMCALL_HOST_SET_DATA:
244       SIMIX_host_set_data(simcall->host_set_data.host, simcall->host_set_data.data);
245       SIMIX_simcall_answer(simcall);
246       break;
247
248     case SIMCALL_HOST_EXECUTE:
249       simcall->host_execute.result = SIMIX_host_execute(
250           simcall->host_execute.name,
251           simcall->host_execute.host,
252           simcall->host_execute.computation_amount,
253           simcall->host_execute.priority);
254       SIMIX_simcall_answer(simcall);
255       break;
256
257     case SIMCALL_HOST_PARALLEL_EXECUTE:
258       simcall->host_parallel_execute.result = SIMIX_host_parallel_execute(
259           simcall->host_parallel_execute.name,
260           simcall->host_parallel_execute.host_nb,
261           simcall->host_parallel_execute.host_list,
262           simcall->host_parallel_execute.computation_amount,
263           simcall->host_parallel_execute.communication_amount,
264           simcall->host_parallel_execute.amount,
265           simcall->host_parallel_execute.rate);
266       SIMIX_simcall_answer(simcall);
267       break;
268
269     case SIMCALL_HOST_EXECUTION_DESTROY:
270       SIMIX_host_execution_destroy(simcall->host_execution_destroy.execution);
271       SIMIX_simcall_answer(simcall);
272       break;
273
274     case SIMCALL_HOST_EXECUTION_CANCEL:
275       SIMIX_host_execution_cancel(simcall->host_execution_cancel.execution);
276       SIMIX_simcall_answer(simcall);
277       break;
278
279     case SIMCALL_HOST_EXECUTION_GET_REMAINS:
280       simcall->host_execution_get_remains.result =
281         SIMIX_host_execution_get_remains(simcall->host_execution_get_remains.execution);
282       SIMIX_simcall_answer(simcall);
283       break;
284
285     case SIMCALL_HOST_EXECUTION_GET_STATE:
286       simcall->host_execution_get_state.result =
287         SIMIX_host_execution_get_state(simcall->host_execution_get_state.execution);
288       SIMIX_simcall_answer(simcall);
289       break;
290
291     case SIMCALL_HOST_EXECUTION_SET_PRIORITY:
292       SIMIX_host_execution_set_priority(
293           simcall->host_execution_set_priority.execution,
294           simcall->host_execution_set_priority.priority);
295       SIMIX_simcall_answer(simcall);
296       break;
297
298     case SIMCALL_HOST_EXECUTION_WAIT:
299       SIMIX_pre_host_execution_wait(simcall);
300       break;
301
302     case SIMCALL_PROCESS_CREATE:
303       SIMIX_process_create(
304           simcall->process_create.process,
305           simcall->process_create.name,
306           simcall->process_create.code,
307           simcall->process_create.data,
308           simcall->process_create.hostname,
309           simcall->process_create.argc,
310           simcall->process_create.argv,
311           simcall->process_create.properties);
312       SIMIX_simcall_answer(simcall);
313       break;
314
315     case SIMCALL_PROCESS_KILL:
316       SIMIX_process_kill(simcall->process_kill.process);
317       SIMIX_simcall_answer(simcall);
318       break;
319
320     case SIMCALL_PROCESS_KILLALL:
321       SIMIX_process_killall(simcall->issuer);
322       SIMIX_simcall_answer(simcall);
323       break;
324
325     case SIMCALL_PROCESS_CLEANUP:
326       SIMIX_process_cleanup(simcall->process_cleanup.process);
327       SIMIX_simcall_answer(simcall);
328       break;
329
330     case SIMCALL_PROCESS_CHANGE_HOST:
331       SIMIX_pre_process_change_host(
332           simcall->process_change_host.process,
333           simcall->process_change_host.dest);
334       SIMIX_simcall_answer(simcall);
335       break;
336
337     case SIMCALL_PROCESS_SUSPEND:
338       SIMIX_pre_process_suspend(simcall);
339       break;
340
341     case SIMCALL_PROCESS_RESUME:
342       SIMIX_process_resume(simcall->process_resume.process, simcall->issuer);
343       SIMIX_simcall_answer(simcall);
344       break;
345
346     case SIMCALL_PROCESS_COUNT:
347       simcall->process_count.result = SIMIX_process_count();
348       SIMIX_simcall_answer(simcall);
349       break;
350
351     case SIMCALL_PROCESS_GET_DATA:
352       simcall->process_get_data.result =
353         SIMIX_process_get_data(simcall->process_get_data.process);
354       SIMIX_simcall_answer(simcall);
355       break;
356
357     case SIMCALL_PROCESS_SET_DATA:
358       SIMIX_process_set_data(
359           simcall->process_set_data.process,
360           simcall->process_set_data.data);
361       SIMIX_simcall_answer(simcall);
362       break;
363
364     case SIMCALL_PROCESS_GET_HOST:
365       simcall->process_get_host.result = SIMIX_process_get_host(simcall->process_get_host.process);
366       SIMIX_simcall_answer(simcall);
367       break;
368
369     case SIMCALL_PROCESS_GET_NAME:
370       simcall->process_get_name.result = SIMIX_process_get_name(simcall->process_get_name.process);
371       SIMIX_simcall_answer(simcall);
372       break;
373
374     case SIMCALL_PROCESS_IS_SUSPENDED:
375       simcall->process_is_suspended.result =
376         SIMIX_process_is_suspended(simcall->process_is_suspended.process);
377       SIMIX_simcall_answer(simcall);
378       break;
379
380     case SIMCALL_PROCESS_GET_PROPERTIES:
381       simcall->process_get_properties.result =
382         SIMIX_process_get_properties(simcall->process_get_properties.process);
383       SIMIX_simcall_answer(simcall);
384       break;
385
386     case SIMCALL_PROCESS_SLEEP:
387       SIMIX_pre_process_sleep(simcall);
388       break;
389
390 #ifdef HAVE_TRACING
391     case SIMCALL_SET_CATEGORY:
392       SIMIX_set_category(
393           simcall->set_category.action,
394           simcall->set_category.category);
395       SIMIX_simcall_answer(simcall);
396       break;
397 #endif
398
399     case SIMCALL_MUTEX_INIT:
400       simcall->mutex_init.result = SIMIX_mutex_init();
401       SIMIX_simcall_answer(simcall);
402       break;
403
404     case SIMCALL_MUTEX_DESTROY:
405       SIMIX_mutex_destroy(simcall->mutex_destroy.mutex);
406       SIMIX_simcall_answer(simcall);
407       break;
408
409     case SIMCALL_MUTEX_LOCK:
410       SIMIX_pre_mutex_lock(simcall);
411       break;
412
413     case SIMCALL_MUTEX_TRYLOCK:
414       simcall->mutex_trylock.result =
415               SIMIX_mutex_trylock(simcall->mutex_trylock.mutex, simcall->issuer);
416       SIMIX_simcall_answer(simcall);
417       break;
418
419     case SIMCALL_MUTEX_UNLOCK:
420       SIMIX_mutex_unlock(simcall->mutex_unlock.mutex, simcall->issuer);
421       SIMIX_simcall_answer(simcall);
422       break;
423
424     case SIMCALL_COND_INIT:
425       simcall->cond_init.result = SIMIX_cond_init();
426       SIMIX_simcall_answer(simcall);
427       break;
428
429     case SIMCALL_COND_DESTROY:
430       SIMIX_cond_destroy(simcall->cond_destroy.cond);
431       SIMIX_simcall_answer(simcall);
432       break;
433
434     case SIMCALL_COND_SIGNAL:
435       SIMIX_cond_signal(simcall->cond_signal.cond);
436       SIMIX_simcall_answer(simcall);
437       break;
438
439     case SIMCALL_COND_WAIT:
440       SIMIX_pre_cond_wait(simcall);
441       break;
442
443     case SIMCALL_COND_WAIT_TIMEOUT:
444       SIMIX_pre_cond_wait_timeout(simcall);
445       break;
446
447     case SIMCALL_COND_BROADCAST:
448       SIMIX_cond_broadcast(simcall->cond_broadcast.cond);
449       SIMIX_simcall_answer(simcall);
450       break;
451
452     case SIMCALL_SEM_INIT:
453       simcall->sem_init.result = SIMIX_sem_init(simcall->sem_init.capacity);
454       SIMIX_simcall_answer(simcall);
455       break;
456
457     case SIMCALL_SEM_DESTROY:
458       SIMIX_sem_destroy(simcall->sem_destroy.sem);
459       SIMIX_simcall_answer(simcall);
460       break;
461
462     case SIMCALL_SEM_RELEASE:
463       SIMIX_sem_release(simcall->sem_release.sem);
464       SIMIX_simcall_answer(simcall);
465       break;
466
467     case SIMCALL_SEM_WOULD_BLOCK:
468       simcall->sem_would_block.result =
469         SIMIX_sem_would_block(simcall->sem_would_block.sem);
470       SIMIX_simcall_answer(simcall);
471       break;
472
473     case SIMCALL_SEM_ACQUIRE:
474       SIMIX_pre_sem_acquire(simcall);
475       break;
476
477     case SIMCALL_SEM_ACQUIRE_TIMEOUT:
478       SIMIX_pre_sem_acquire_timeout(simcall);
479       break;
480
481     case SIMCALL_SEM_GET_CAPACITY:
482       simcall->sem_get_capacity.result = 
483         SIMIX_sem_get_capacity(simcall->sem_get_capacity.sem);
484       SIMIX_simcall_answer(simcall);
485       break;
486
487     case SIMCALL_FILE_READ:
488       SIMIX_pre_file_read(simcall);
489       break;
490
491     case SIMCALL_FILE_WRITE:
492       SIMIX_pre_file_write(simcall);
493       break;
494
495     case SIMCALL_FILE_OPEN:
496       SIMIX_pre_file_open(simcall);
497       break;
498
499     case SIMCALL_FILE_CLOSE:
500       SIMIX_pre_file_close(simcall);
501       break;
502
503     case SIMCALL_FILE_STAT:
504       SIMIX_pre_file_stat(simcall);
505       break;
506
507     case SIMCALL_NONE:
508       THROWF(arg_error,0,"Asked to do the noop syscall on %s@%s",
509           SIMIX_process_get_name(simcall->issuer),
510           SIMIX_host_get_name(SIMIX_process_get_host(simcall->issuer))
511           );
512       break;
513   }
514 }
515
516 void SIMIX_simcall_post(smx_action_t action)
517 {
518   switch (action->type) {
519
520     case SIMIX_ACTION_EXECUTE:
521     case SIMIX_ACTION_PARALLEL_EXECUTE:
522       SIMIX_post_host_execute(action);
523       break;
524
525     case SIMIX_ACTION_COMMUNICATE:
526       SIMIX_post_comm(action);
527       break;
528
529     case SIMIX_ACTION_SLEEP:
530       SIMIX_post_process_sleep(action);
531       break;
532
533     case SIMIX_ACTION_SYNCHRO:
534       SIMIX_post_synchro(action);
535       break;
536
537     case SIMIX_ACTION_IO:
538       SIMIX_post_io(action);
539       break;
540   }
541 }