Logo AND Algorithmique Numérique Distribuée

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