Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Bugfix: protect SIMIX_context_self() in the case that SIMIX is not initialized.
[simgrid.git] / src / simix / smx_smurf.c
1 #include "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 static xbt_dynar_t req_vector;
9 static xbt_os_mutex_t sync_req_vector;
10
11 void SIMIX_request_init(void)
12 {
13   sync_req_vector = xbt_os_mutex_init();
14   req_vector = xbt_dynar_new(sizeof(void *), NULL);
15 }
16
17 void SIMIX_request_destroy(void)
18 {
19   xbt_os_mutex_destroy(sync_req_vector);
20   xbt_dynar_free(&req_vector);
21 }
22
23 void SIMIX_request_push(smx_req_t req)
24 {
25   req->issuer = SIMIX_process_self();
26   if (req->issuer != simix_global->maestro_process){
27     xbt_os_mutex_acquire(sync_req_vector);
28     xbt_dynar_set_as(req_vector, req->issuer->pid, smx_req_t, req);
29     xbt_os_mutex_release(sync_req_vector);
30     req->issuer->request = req;
31     DEBUG2("Yield process '%s' on request of type %d", req->issuer->name, req->call);
32     SIMIX_process_yield();
33   } else {
34     SIMIX_request_pre(req);
35   }
36 }
37
38 smx_req_t SIMIX_request_pop(void)
39 {
40   smx_req_t request = NULL;
41   xbt_os_mutex_acquire(sync_req_vector);
42   while (xbt_dynar_length(req_vector)){
43     request = xbt_dynar_pop_as(req_vector, smx_req_t);
44     if (request)
45       break;
46   }
47   xbt_os_mutex_release(sync_req_vector);
48   return request;
49 }
50
51 void SIMIX_request_answer(smx_req_t req)
52 {
53   if (req->issuer != simix_global->maestro_process){
54     req->issuer->request = NULL;    
55     xbt_swag_insert(req->issuer, simix_global->process_to_run);
56   }
57 }
58
59 int SIMIX_request_is_visible(smx_req_t req)
60 {
61   return req->call == REQ_COMM_ISEND
62      || req->call == REQ_COMM_IRECV
63      || req->call == REQ_COMM_WAIT
64      || req->call == REQ_COMM_WAITANY
65      || req->call == REQ_COMM_TEST;
66 }
67
68 int SIMIX_request_is_enabled(smx_req_t req)
69 {
70   unsigned int index = 0;
71   smx_action_t act;
72
73   switch (req->call) {
74
75     case REQ_COMM_WAIT:
76       /* FIXME: check also that src and dst processes are not suspended */
77       if (req->comm_wait.comm->comm.src_proc 
78          && req->comm_wait.comm->comm.dst_proc)
79         return TRUE;
80       return FALSE;
81       break;
82
83     case REQ_COMM_WAITANY:
84       xbt_dynar_foreach(req->comm_waitany.comms, index, act) {
85         if (act->comm.src_proc && act->comm.dst_proc){
86           return TRUE;
87         }
88       }
89       return FALSE;
90       break;
91
92     default:    
93       return TRUE;
94   }
95 }
96
97
98 void SIMIX_request_pre(smx_req_t req)
99 {
100   switch (req->call) {
101
102     case REQ_HOST_GET_BY_NAME:
103       req->host_get_by_name.result =
104         SIMIX_host_get_by_name(req->host_get_by_name.name);
105       SIMIX_request_answer(req);
106       break;
107
108     case REQ_HOST_GET_NAME:
109       req->host_get_name.result =       SIMIX_host_get_name(req->host_get_name.host);
110       SIMIX_request_answer(req);
111       break;
112
113     case REQ_HOST_GET_PROPERTIES:
114       req->host_get_properties.result =
115         SIMIX_host_get_properties(req->host_get_properties.host);
116       SIMIX_request_answer(req);
117       break;
118
119     case REQ_HOST_GET_SPEED:
120       req->host_get_speed.result = 
121         SIMIX_host_get_speed(req->host_get_speed.host);
122       SIMIX_request_answer(req);
123       break;
124
125     case REQ_HOST_GET_AVAILABLE_SPEED:
126       req->host_get_available_speed.result =
127         SIMIX_host_get_available_speed(req->host_get_available_speed.host);
128       SIMIX_request_answer(req);
129       break;
130
131     case REQ_HOST_GET_STATE:
132       req->host_get_state.result = 
133         SIMIX_host_get_state(req->host_get_state.host);
134       SIMIX_request_answer(req);
135       break;
136
137     case REQ_HOST_GET_DATA:
138       req->host_get_data.result =       SIMIX_host_get_data(req->host_get_data.host);
139       SIMIX_request_answer(req);
140       break;
141
142     case REQ_HOST_SET_DATA:
143       SIMIX_host_set_data(req->host_set_data.host, req->host_set_data.data);
144       SIMIX_request_answer(req);
145       break;
146
147     case REQ_HOST_EXECUTE:
148       req->host_execute.result = SIMIX_host_execute(
149           req->host_execute.name,
150           req->host_execute.host,
151           req->host_execute.computation_amount);
152       SIMIX_request_answer(req);
153       break;
154
155     case REQ_HOST_PARALLEL_EXECUTE:
156       req->host_parallel_execute.result = SIMIX_host_parallel_execute(
157           req->host_parallel_execute.name,
158           req->host_parallel_execute.host_nb,
159           req->host_parallel_execute.host_list,
160           req->host_parallel_execute.computation_amount,
161           req->host_parallel_execute.communication_amount,
162           req->host_parallel_execute.amount,
163           req->host_parallel_execute.rate);
164       SIMIX_request_answer(req);
165       break;
166
167     case REQ_HOST_EXECUTION_DESTROY:
168       SIMIX_host_execution_destroy(req->host_execution_destroy.execution);
169       SIMIX_request_answer(req);
170       break;
171
172     case REQ_HOST_EXECUTION_CANCEL:
173       SIMIX_host_execution_cancel(req->host_execution_cancel.execution);
174       SIMIX_request_answer(req);
175       break;
176
177     case REQ_HOST_EXECUTION_GET_REMAINS:
178       req->host_execution_get_remains.result =
179         SIMIX_host_execution_get_remains(req->host_execution_get_remains.execution);
180       SIMIX_request_answer(req);
181       break;
182
183     case REQ_HOST_EXECUTION_GET_STATE:
184       req->host_execution_get_state.result =
185         SIMIX_host_execution_get_state(req->host_execution_get_state.execution);
186       SIMIX_request_answer(req);
187       break;
188
189     case REQ_HOST_EXECUTION_SET_PRIORITY:
190       SIMIX_host_execution_set_priority(
191           req->host_execution_set_priority.execution,
192           req->host_execution_set_priority.priority);
193       SIMIX_request_answer(req);
194       break;
195
196     case REQ_HOST_EXECUTION_WAIT:
197       SIMIX_pre_host_execution_wait(req);
198       break;
199
200     case REQ_PROCESS_CREATE:
201       req->process_create.result = SIMIX_process_create(
202           req->process_create.name,
203           req->process_create.code,
204           req->process_create.data,
205           req->process_create.hostname,
206           req->process_create.argc,
207           req->process_create.argv,
208           req->process_create.properties);
209       SIMIX_request_answer(req);
210       break;
211
212     case REQ_PROCESS_KILL:
213       SIMIX_process_kill(req->process_kill.process, req->issuer);
214       SIMIX_request_answer(req);
215       break;
216
217     case REQ_PROCESS_CHANGE_HOST:
218       SIMIX_process_change_host(
219           req->process_change_host.process,
220           req->process_change_host.source,
221           req->process_change_host.dest);
222       SIMIX_request_answer(req);
223       break;
224
225     case REQ_PROCESS_SUSPEND:
226       SIMIX_pre_process_suspend(req);
227       break;
228
229     case REQ_PROCESS_RESUME:
230       SIMIX_process_resume(req->process_resume.process, req->issuer);
231       SIMIX_request_answer(req);
232       break;
233
234     case REQ_PROCESS_COUNT:
235       req->process_count.result = SIMIX_process_count();
236       SIMIX_request_answer(req);
237       break;
238
239     case REQ_PROCESS_GET_DATA:
240       req->process_get_data.result =
241         SIMIX_process_get_data(req->process_get_data.process);
242       SIMIX_request_answer(req);
243       break;
244
245     case REQ_PROCESS_SET_DATA:
246       SIMIX_process_set_data(
247           req->process_set_data.process,
248           req->process_set_data.data);
249       SIMIX_request_answer(req);
250       break;
251
252     case REQ_PROCESS_GET_HOST:
253       req->process_get_host.result = SIMIX_process_get_host(req->process_get_host.process);
254       SIMIX_request_answer(req);
255       break;
256
257     case REQ_PROCESS_GET_NAME:
258       req->process_get_name.result = SIMIX_process_get_name(req->process_get_name.process);
259       SIMIX_request_answer(req);
260       break;
261
262     case REQ_PROCESS_IS_SUSPENDED:
263       req->process_is_suspended.result =
264         SIMIX_process_is_suspended(req->process_is_suspended.process);
265       SIMIX_request_answer(req);
266       break;
267
268     case REQ_PROCESS_GET_PROPERTIES:
269       req->process_get_properties.result =
270         SIMIX_process_get_properties(req->process_get_properties.process);
271       SIMIX_request_answer(req);
272       break;
273
274     case REQ_PROCESS_SLEEP:
275       SIMIX_pre_process_sleep(req);
276       break;
277
278     case REQ_RDV_CREATE:
279       req->rdv_create.result = SIMIX_rdv_create(req->rdv_create.name);
280       SIMIX_request_answer(req);
281       break;
282
283     case REQ_RDV_DESTROY:
284       SIMIX_rdv_destroy(req->rdv_destroy.rdv);
285       SIMIX_request_answer(req);
286       break;
287
288     case REQ_RDV_GEY_BY_NAME:
289       req->rdv_get_by_name.result = 
290         SIMIX_rdv_get_by_name(req->rdv_get_by_name.name);
291       SIMIX_request_answer(req);
292       break;
293
294     case REQ_RDV_COMM_COUNT_BY_HOST:
295       req->rdv_comm_count_by_host.result = SIMIX_rdv_comm_count_by_host(
296           req->rdv_comm_count_by_host.rdv,
297           req->rdv_comm_count_by_host.host);
298       SIMIX_request_answer(req);
299       break;
300
301     case REQ_RDV_GET_HEAD:
302       req->rdv_get_head.result =        SIMIX_rdv_get_head(req->rdv_get_head.rdv);
303       SIMIX_request_answer(req);
304       break;
305
306     case REQ_COMM_ISEND:
307       req->comm_isend.result = SIMIX_comm_isend(
308           req->issuer,
309           req->comm_isend.rdv,
310           req->comm_isend.task_size,
311           req->comm_isend.rate,
312           req->comm_isend.src_buff,
313           req->comm_isend.src_buff_size,
314           req->comm_isend.data);
315       SIMIX_request_answer(req);
316       break;
317
318     case REQ_COMM_IRECV:
319       req->comm_irecv.result = SIMIX_comm_irecv(
320           req->issuer,
321           req->comm_irecv.rdv,
322           req->comm_irecv.dst_buff,
323           req->comm_irecv.dst_buff_size);
324       SIMIX_request_answer(req);
325       break;
326
327     case REQ_COMM_DESTROY:
328       SIMIX_comm_destroy(req->comm_destroy.comm);
329       SIMIX_request_answer(req);
330       break;
331
332     case REQ_COMM_CANCEL:
333       SIMIX_comm_cancel(req->comm_cancel.comm);
334       SIMIX_request_answer(req);
335       break;
336
337     case REQ_COMM_WAITANY:
338       SIMIX_pre_comm_waitany(req);
339       break;
340
341     case REQ_COMM_WAIT:
342       SIMIX_pre_comm_wait(req);
343       break;
344
345     case REQ_COMM_TEST:
346       SIMIX_pre_comm_test(req);
347       break;
348
349     case REQ_COMM_GET_REMAINS:
350       req->comm_get_remains.result = 
351         SIMIX_comm_get_remains(req->comm_get_remains.comm);
352       SIMIX_request_answer(req);
353       break;
354
355     case REQ_COMM_GET_STATE:
356       req->comm_get_state.result = 
357         SIMIX_comm_get_state(req->comm_get_state.comm);
358       SIMIX_request_answer(req);
359       break;
360
361     case REQ_COMM_GET_DATA:
362       req->comm_get_data.result = SIMIX_comm_get_data(req->comm_get_data.comm);
363       SIMIX_request_answer(req);
364       break;
365
366     case REQ_COMM_GET_SRC_BUFF:
367       req->comm_get_src_buff.result =
368         SIMIX_comm_get_src_buff(req->comm_get_src_buff.comm);
369       SIMIX_request_answer(req);
370       break;
371
372     case REQ_COMM_GET_DST_BUFF:
373       req->comm_get_dst_buff.result =
374         SIMIX_comm_get_dst_buff(req->comm_get_dst_buff.comm);
375       SIMIX_request_answer(req);
376       break;
377
378     case REQ_COMM_GET_SRC_BUFF_SIZE:
379       req->comm_get_src_buff_size.result = 
380         SIMIX_comm_get_src_buff_size(req->comm_get_src_buff_size.comm);
381       SIMIX_request_answer(req);
382       break;
383
384     case REQ_COMM_GET_DST_BUFF_SIZE:
385       req->comm_get_dst_buff_size.result =
386         SIMIX_comm_get_dst_buff_size(req->comm_get_dst_buff_size.comm);
387       SIMIX_request_answer(req);
388       break;
389
390     case REQ_COMM_GET_SRC_PROC:
391       req->comm_get_src_proc.result = 
392         SIMIX_comm_get_src_proc(req->comm_get_src_proc.comm);
393       SIMIX_request_answer(req);
394       break;
395
396     case REQ_COMM_GET_DST_PROC:
397       req->comm_get_dst_proc.result =
398         SIMIX_comm_get_dst_proc(req->comm_get_dst_proc.comm);
399       SIMIX_request_answer(req);
400       break;
401
402 #ifdef HAVE_LATENCY_BOUND_TRACKING
403     case REQ_COMM_IS_LATENCY_BOUNDED:
404       req->comm_is_latency_bounded.result =
405         SIMIX_comm_is_latency_bounded(req->comm_is_latency_bounded.comm);
406       SIMIX_request_answer(req);
407       break;
408 #endif
409
410     case REQ_MUTEX_INIT:
411       req->mutex_init.result = SIMIX_mutex_init();
412       SIMIX_request_answer(req);
413       break;
414
415     case REQ_MUTEX_DESTROY:
416       SIMIX_mutex_destroy(req->mutex_destroy.mutex);
417       SIMIX_request_answer(req);
418       break;
419
420     case REQ_MUTEX_LOCK:
421       SIMIX_pre_mutex_lock(req);
422       break;
423
424     case REQ_MUTEX_TRYLOCK:
425       req->mutex_trylock.result =
426               SIMIX_mutex_trylock(req->mutex_trylock.mutex, req->issuer);
427       SIMIX_request_answer(req);
428       break;
429
430     case REQ_MUTEX_UNLOCK:
431       SIMIX_mutex_unlock(req->mutex_unlock.mutex, req->issuer);
432       SIMIX_request_answer(req);
433       break;
434
435     case REQ_COND_INIT:
436       req->cond_init.result = SIMIX_cond_init();
437       SIMIX_request_answer(req);
438       break;
439
440     case REQ_COND_DESTROY:
441       SIMIX_cond_destroy(req->cond_destroy.cond);
442       SIMIX_request_answer(req);
443       break;
444
445     case REQ_COND_SIGNAL:
446       SIMIX_cond_signal(req->cond_signal.cond);
447       SIMIX_request_answer(req);
448       break;
449
450     case REQ_COND_WAIT:
451       SIMIX_pre_cond_wait(req);
452       break;
453
454     case REQ_COND_WAIT_TIMEOUT:
455       SIMIX_pre_cond_wait_timeout(req);
456       break;
457
458     case REQ_COND_BROADCAST:
459       SIMIX_cond_broadcast(req->cond_broadcast.cond);
460       SIMIX_request_answer(req);
461       break;
462
463     case REQ_SEM_INIT:
464       req->sem_init.result = SIMIX_sem_init(req->sem_init.capacity);
465       SIMIX_request_answer(req);
466       break;
467
468     case REQ_SEM_DESTROY:
469       SIMIX_sem_destroy(req->sem_destroy.sem);
470       SIMIX_request_answer(req);
471       break;
472
473     case REQ_SEM_RELEASE:
474       SIMIX_sem_release(req->sem_release.sem);
475       SIMIX_request_answer(req);
476       break;
477
478     case REQ_SEM_WOULD_BLOCK:
479       req->sem_would_block.result =
480         SIMIX_sem_would_block(req->sem_would_block.sem);
481       SIMIX_request_answer(req);
482       break;
483
484     case REQ_SEM_ACQUIRE:
485       SIMIX_pre_sem_acquire(req);
486       break;
487
488     case REQ_SEM_ACQUIRE_TIMEOUT:
489       SIMIX_pre_sem_acquire_timeout(req);
490       break;
491
492     case REQ_SEM_GET_CAPACITY:
493       req->sem_get_capacity.result = 
494         SIMIX_sem_get_capacity(req->sem_get_capacity.sem);
495       SIMIX_request_answer(req);
496       break;
497   }
498 }
499
500 void SIMIX_request_post(smx_action_t action)
501 {
502   switch (action->type) {
503
504     case SIMIX_ACTION_EXECUTE:
505     case SIMIX_ACTION_PARALLEL_EXECUTE:
506       SIMIX_post_host_execute(action);
507       break;
508
509     case SIMIX_ACTION_COMMUNICATE:
510       SIMIX_post_comm(action);
511       break;
512
513     case SIMIX_ACTION_SLEEP:
514       SIMIX_post_process_sleep(action);
515       break;
516
517     case SIMIX_ACTION_SYNCHRO:
518       SIMIX_post_synchro(action);
519       break;
520
521     case SIMIX_ACTION_IO:
522       break;
523   }
524 }