Logo AND Algorithmique Numérique Distribuée

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