Logo AND Algorithmique Numérique Distribuée

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