Logo AND Algorithmique Numérique Distribuée

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