Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Better coverage of SIMIX_process_suspend and resume.
[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.kill_time,
310           simcall->process_create.argc,
311           simcall->process_create.argv,
312           simcall->process_create.properties);
313       SIMIX_simcall_answer(simcall);
314       break;
315
316     case SIMCALL_PROCESS_KILL:
317       SIMIX_process_kill(simcall->process_kill.process);
318       SIMIX_simcall_answer(simcall);
319       break;
320
321     case SIMCALL_PROCESS_KILLALL:
322       SIMIX_process_killall(simcall->issuer);
323       SIMIX_simcall_answer(simcall);
324       break;
325
326     case SIMCALL_PROCESS_CLEANUP:
327       SIMIX_process_cleanup(simcall->process_cleanup.process);
328       SIMIX_simcall_answer(simcall);
329       break;
330
331     case SIMCALL_PROCESS_CHANGE_HOST:
332       SIMIX_pre_process_change_host(
333           simcall->process_change_host.process,
334           simcall->process_change_host.dest);
335       SIMIX_simcall_answer(simcall);
336       break;
337
338     case SIMCALL_PROCESS_SUSPEND:
339       SIMIX_pre_process_suspend(simcall);
340       break;
341
342     case SIMCALL_PROCESS_RESUME:
343       SIMIX_process_resume(simcall->process_resume.process, simcall->issuer);
344       SIMIX_simcall_answer(simcall);
345       break;
346
347     case SIMCALL_PROCESS_COUNT:
348       simcall->process_count.result = SIMIX_process_count();
349       SIMIX_simcall_answer(simcall);
350       break;
351
352     case SIMCALL_PROCESS_GET_DATA:
353       simcall->process_get_data.result =
354         SIMIX_process_get_data(simcall->process_get_data.process);
355       SIMIX_simcall_answer(simcall);
356       break;
357
358     case SIMCALL_PROCESS_SET_DATA:
359       SIMIX_process_set_data(
360           simcall->process_set_data.process,
361           simcall->process_set_data.data);
362       SIMIX_simcall_answer(simcall);
363       break;
364
365     case SIMCALL_PROCESS_GET_HOST:
366       simcall->process_get_host.result = SIMIX_process_get_host(simcall->process_get_host.process);
367       SIMIX_simcall_answer(simcall);
368       break;
369
370     case SIMCALL_PROCESS_GET_NAME:
371       simcall->process_get_name.result = SIMIX_process_get_name(simcall->process_get_name.process);
372       SIMIX_simcall_answer(simcall);
373       break;
374
375     case SIMCALL_PROCESS_IS_SUSPENDED:
376       simcall->process_is_suspended.result =
377         SIMIX_process_is_suspended(simcall->process_is_suspended.process);
378       SIMIX_simcall_answer(simcall);
379       break;
380
381     case SIMCALL_PROCESS_GET_PROPERTIES:
382       simcall->process_get_properties.result =
383         SIMIX_process_get_properties(simcall->process_get_properties.process);
384       SIMIX_simcall_answer(simcall);
385       break;
386
387     case SIMCALL_PROCESS_SLEEP:
388       SIMIX_pre_process_sleep(simcall);
389       break;
390
391 #ifdef HAVE_TRACING
392     case SIMCALL_SET_CATEGORY:
393       SIMIX_set_category(
394           simcall->set_category.action,
395           simcall->set_category.category);
396       SIMIX_simcall_answer(simcall);
397       break;
398 #endif
399
400     case SIMCALL_MUTEX_INIT:
401       simcall->mutex_init.result = SIMIX_mutex_init();
402       SIMIX_simcall_answer(simcall);
403       break;
404
405     case SIMCALL_MUTEX_DESTROY:
406       SIMIX_mutex_destroy(simcall->mutex_destroy.mutex);
407       SIMIX_simcall_answer(simcall);
408       break;
409
410     case SIMCALL_MUTEX_LOCK:
411       SIMIX_pre_mutex_lock(simcall);
412       break;
413
414     case SIMCALL_MUTEX_TRYLOCK:
415       simcall->mutex_trylock.result =
416               SIMIX_mutex_trylock(simcall->mutex_trylock.mutex, simcall->issuer);
417       SIMIX_simcall_answer(simcall);
418       break;
419
420     case SIMCALL_MUTEX_UNLOCK:
421       SIMIX_mutex_unlock(simcall->mutex_unlock.mutex, simcall->issuer);
422       SIMIX_simcall_answer(simcall);
423       break;
424
425     case SIMCALL_COND_INIT:
426       simcall->cond_init.result = SIMIX_cond_init();
427       SIMIX_simcall_answer(simcall);
428       break;
429
430     case SIMCALL_COND_DESTROY:
431       SIMIX_cond_destroy(simcall->cond_destroy.cond);
432       SIMIX_simcall_answer(simcall);
433       break;
434
435     case SIMCALL_COND_SIGNAL:
436       SIMIX_cond_signal(simcall->cond_signal.cond);
437       SIMIX_simcall_answer(simcall);
438       break;
439
440     case SIMCALL_COND_WAIT:
441       SIMIX_pre_cond_wait(simcall);
442       break;
443
444     case SIMCALL_COND_WAIT_TIMEOUT:
445       SIMIX_pre_cond_wait_timeout(simcall);
446       break;
447
448     case SIMCALL_COND_BROADCAST:
449       SIMIX_cond_broadcast(simcall->cond_broadcast.cond);
450       SIMIX_simcall_answer(simcall);
451       break;
452
453     case SIMCALL_SEM_INIT:
454       simcall->sem_init.result = SIMIX_sem_init(simcall->sem_init.capacity);
455       SIMIX_simcall_answer(simcall);
456       break;
457
458     case SIMCALL_SEM_DESTROY:
459       SIMIX_sem_destroy(simcall->sem_destroy.sem);
460       SIMIX_simcall_answer(simcall);
461       break;
462
463     case SIMCALL_SEM_RELEASE:
464       SIMIX_sem_release(simcall->sem_release.sem);
465       SIMIX_simcall_answer(simcall);
466       break;
467
468     case SIMCALL_SEM_WOULD_BLOCK:
469       simcall->sem_would_block.result =
470         SIMIX_sem_would_block(simcall->sem_would_block.sem);
471       SIMIX_simcall_answer(simcall);
472       break;
473
474     case SIMCALL_SEM_ACQUIRE:
475       SIMIX_pre_sem_acquire(simcall);
476       break;
477
478     case SIMCALL_SEM_ACQUIRE_TIMEOUT:
479       SIMIX_pre_sem_acquire_timeout(simcall);
480       break;
481
482     case SIMCALL_SEM_GET_CAPACITY:
483       simcall->sem_get_capacity.result = 
484         SIMIX_sem_get_capacity(simcall->sem_get_capacity.sem);
485       SIMIX_simcall_answer(simcall);
486       break;
487
488     case SIMCALL_FILE_READ:
489       SIMIX_pre_file_read(simcall);
490       break;
491
492     case SIMCALL_FILE_WRITE:
493       SIMIX_pre_file_write(simcall);
494       break;
495
496     case SIMCALL_FILE_OPEN:
497       SIMIX_pre_file_open(simcall);
498       break;
499
500     case SIMCALL_FILE_CLOSE:
501       SIMIX_pre_file_close(simcall);
502       break;
503
504     case SIMCALL_FILE_STAT:
505       SIMIX_pre_file_stat(simcall);
506       break;
507
508     case SIMCALL_NONE:
509       THROWF(arg_error,0,"Asked to do the noop syscall on %s@%s",
510           SIMIX_process_get_name(simcall->issuer),
511           SIMIX_host_get_name(SIMIX_process_get_host(simcall->issuer))
512           );
513       break;
514   }
515 }
516
517 void SIMIX_simcall_post(smx_action_t action)
518 {
519   switch (action->type) {
520
521     case SIMIX_ACTION_EXECUTE:
522     case SIMIX_ACTION_PARALLEL_EXECUTE:
523       SIMIX_post_host_execute(action);
524       break;
525
526     case SIMIX_ACTION_COMMUNICATE:
527       SIMIX_post_comm(action);
528       break;
529
530     case SIMIX_ACTION_SLEEP:
531       SIMIX_post_process_sleep(action);
532       break;
533
534     case SIMIX_ACTION_SYNCHRO:
535       SIMIX_post_synchro(action);
536       break;
537
538     case SIMIX_ACTION_IO:
539       SIMIX_post_io(action);
540       break;
541   }
542 }