Logo AND Algorithmique Numérique Distribuée

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