Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Do not traverse the whole array of request to find non-null ones, use a heap instead
[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 /* Array storing all requests to be handled in this scheduling round */
9 static smx_req_t* req_vector=NULL;
10 /* Positions of the previous array with non-null data */
11 static xbt_heap_t req_positions;
12 /* to protect the write actions in the heap */
13 static xbt_os_mutex_t sync_req_positions;
14
15 void SIMIX_request_init(void)
16 {
17   req_vector = xbt_new0(smx_req_t,1);/* enough room for maestro's requests */
18   req_positions = xbt_heap_new(5,NULL);
19   sync_req_positions = xbt_os_mutex_init();
20 }
21
22 void SIMIX_request_destroy(void)
23 {
24   free(req_vector);
25   req_vector = NULL;
26   xbt_heap_free(req_positions);
27   xbt_os_mutex_destroy(sync_req_positions);
28 }
29
30 void SIMIX_request_push(smx_req_t req)
31 {
32   req->issuer = SIMIX_process_self();
33   if (req->issuer != simix_global->maestro_process){
34     req_vector[req->issuer->pid] = req;
35     req->issuer->request = req;
36
37     if (_surf_parallel_contexts)
38       xbt_os_mutex_acquire(sync_req_positions);
39     xbt_heap_push(req_positions,req,req->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", req->issuer->name, req->call);
44     SIMIX_process_yield();
45   } else {
46     SIMIX_request_pre(req);
47   }
48 }
49
50 smx_req_t SIMIX_request_pop(void)
51 {
52   return xbt_heap_pop(req_positions);
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_vector = xbt_realloc(req_vector,sizeof(smx_req_t)*(SIMIX_process_get_maxpid()+2));
206       req->process_create.result = SIMIX_process_create(
207           req->process_create.name,
208           req->process_create.code,
209           req->process_create.data,
210           req->process_create.hostname,
211           req->process_create.argc,
212           req->process_create.argv,
213           req->process_create.properties);
214       SIMIX_request_answer(req);
215       break;
216
217     case REQ_PROCESS_KILL:
218       SIMIX_process_kill(req->process_kill.process, req->issuer);
219       SIMIX_request_answer(req);
220       break;
221
222     case REQ_PROCESS_CHANGE_HOST:
223       SIMIX_process_change_host(
224           req->process_change_host.process,
225           req->process_change_host.source,
226           req->process_change_host.dest);
227       SIMIX_request_answer(req);
228       break;
229
230     case REQ_PROCESS_SUSPEND:
231       SIMIX_pre_process_suspend(req);
232       break;
233
234     case REQ_PROCESS_RESUME:
235       SIMIX_process_resume(req->process_resume.process, req->issuer);
236       SIMIX_request_answer(req);
237       break;
238
239     case REQ_PROCESS_COUNT:
240       req->process_count.result = SIMIX_process_count();
241       SIMIX_request_answer(req);
242       break;
243
244     case REQ_PROCESS_GET_DATA:
245       req->process_get_data.result =
246         SIMIX_process_get_data(req->process_get_data.process);
247       SIMIX_request_answer(req);
248       break;
249
250     case REQ_PROCESS_SET_DATA:
251       SIMIX_process_set_data(
252           req->process_set_data.process,
253           req->process_set_data.data);
254       SIMIX_request_answer(req);
255       break;
256
257     case REQ_PROCESS_GET_HOST:
258       req->process_get_host.result = SIMIX_process_get_host(req->process_get_host.process);
259       SIMIX_request_answer(req);
260       break;
261
262     case REQ_PROCESS_GET_NAME:
263       req->process_get_name.result = SIMIX_process_get_name(req->process_get_name.process);
264       SIMIX_request_answer(req);
265       break;
266
267     case REQ_PROCESS_IS_SUSPENDED:
268       req->process_is_suspended.result =
269         SIMIX_process_is_suspended(req->process_is_suspended.process);
270       SIMIX_request_answer(req);
271       break;
272
273     case REQ_PROCESS_GET_PROPERTIES:
274       req->process_get_properties.result =
275         SIMIX_process_get_properties(req->process_get_properties.process);
276       SIMIX_request_answer(req);
277       break;
278
279     case REQ_PROCESS_SLEEP:
280       SIMIX_pre_process_sleep(req);
281       break;
282
283     case REQ_RDV_CREATE:
284       req->rdv_create.result = SIMIX_rdv_create(req->rdv_create.name);
285       SIMIX_request_answer(req);
286       break;
287
288     case REQ_RDV_DESTROY:
289       SIMIX_rdv_destroy(req->rdv_destroy.rdv);
290       SIMIX_request_answer(req);
291       break;
292
293     case REQ_RDV_GEY_BY_NAME:
294       req->rdv_get_by_name.result = 
295         SIMIX_rdv_get_by_name(req->rdv_get_by_name.name);
296       SIMIX_request_answer(req);
297       break;
298
299     case REQ_RDV_COMM_COUNT_BY_HOST:
300       req->rdv_comm_count_by_host.result = SIMIX_rdv_comm_count_by_host(
301           req->rdv_comm_count_by_host.rdv,
302           req->rdv_comm_count_by_host.host);
303       SIMIX_request_answer(req);
304       break;
305
306     case REQ_RDV_GET_HEAD:
307       req->rdv_get_head.result =        SIMIX_rdv_get_head(req->rdv_get_head.rdv);
308       SIMIX_request_answer(req);
309       break;
310
311     case REQ_COMM_ISEND:
312       req->comm_isend.result = SIMIX_comm_isend(
313           req->issuer,
314           req->comm_isend.rdv,
315           req->comm_isend.task_size,
316           req->comm_isend.rate,
317           req->comm_isend.src_buff,
318           req->comm_isend.src_buff_size,
319           req->comm_isend.match_fun,
320           req->comm_isend.data);
321       SIMIX_request_answer(req);
322       break;
323
324     case REQ_COMM_IRECV:
325       req->comm_irecv.result = SIMIX_comm_irecv(
326           req->issuer,
327           req->comm_irecv.rdv,
328           req->comm_irecv.dst_buff,
329           req->comm_irecv.dst_buff_size,
330           req->comm_irecv.match_fun,
331           req->comm_irecv.data);
332       SIMIX_request_answer(req);
333       break;
334
335     case REQ_COMM_DESTROY:
336       SIMIX_comm_destroy(req->comm_destroy.comm);
337       SIMIX_request_answer(req);
338       break;
339
340     case REQ_COMM_CANCEL:
341       SIMIX_comm_cancel(req->comm_cancel.comm);
342       SIMIX_request_answer(req);
343       break;
344
345     case REQ_COMM_WAITANY:
346       SIMIX_pre_comm_waitany(req);
347       break;
348
349     case REQ_COMM_WAIT:
350       SIMIX_pre_comm_wait(req);
351       break;
352
353     case REQ_COMM_TEST:
354       SIMIX_pre_comm_test(req);
355       break;
356
357     case REQ_COMM_TESTANY:
358       SIMIX_pre_comm_testany(req);
359       break;
360
361     case REQ_COMM_GET_REMAINS:
362       req->comm_get_remains.result = 
363         SIMIX_comm_get_remains(req->comm_get_remains.comm);
364       SIMIX_request_answer(req);
365       break;
366
367     case REQ_COMM_GET_STATE:
368       req->comm_get_state.result = 
369         SIMIX_comm_get_state(req->comm_get_state.comm);
370       SIMIX_request_answer(req);
371       break;
372
373     case REQ_COMM_GET_SRC_DATA:
374       req->comm_get_src_data.result = SIMIX_comm_get_src_data(req->comm_get_src_data.comm);
375       SIMIX_request_answer(req);
376       break;
377
378     case REQ_COMM_GET_DST_DATA:
379       req->comm_get_dst_data.result = SIMIX_comm_get_dst_data(req->comm_get_dst_data.comm);
380       SIMIX_request_answer(req);
381       break;
382
383     case REQ_COMM_GET_SRC_BUFF:
384       req->comm_get_src_buff.result =
385         SIMIX_comm_get_src_buff(req->comm_get_src_buff.comm);
386       SIMIX_request_answer(req);
387       break;
388
389     case REQ_COMM_GET_DST_BUFF:
390       req->comm_get_dst_buff.result =
391         SIMIX_comm_get_dst_buff(req->comm_get_dst_buff.comm);
392       SIMIX_request_answer(req);
393       break;
394
395     case REQ_COMM_GET_SRC_BUFF_SIZE:
396       req->comm_get_src_buff_size.result = 
397         SIMIX_comm_get_src_buff_size(req->comm_get_src_buff_size.comm);
398       SIMIX_request_answer(req);
399       break;
400
401     case REQ_COMM_GET_DST_BUFF_SIZE:
402       req->comm_get_dst_buff_size.result =
403         SIMIX_comm_get_dst_buff_size(req->comm_get_dst_buff_size.comm);
404       SIMIX_request_answer(req);
405       break;
406
407     case REQ_COMM_GET_SRC_PROC:
408       req->comm_get_src_proc.result = 
409         SIMIX_comm_get_src_proc(req->comm_get_src_proc.comm);
410       SIMIX_request_answer(req);
411       break;
412
413     case REQ_COMM_GET_DST_PROC:
414       req->comm_get_dst_proc.result =
415         SIMIX_comm_get_dst_proc(req->comm_get_dst_proc.comm);
416       SIMIX_request_answer(req);
417       break;
418
419 #ifdef HAVE_LATENCY_BOUND_TRACKING
420     case REQ_COMM_IS_LATENCY_BOUNDED:
421       req->comm_is_latency_bounded.result =
422         SIMIX_comm_is_latency_bounded(req->comm_is_latency_bounded.comm);
423       SIMIX_request_answer(req);
424       break;
425 #endif
426
427 #ifdef HAVE_TRACING
428     case REQ_SET_CATEGORY:
429       SIMIX_set_category(
430           req->set_category.action,
431           req->set_category.category);
432       SIMIX_request_answer(req);
433       break;
434 #endif
435
436     case REQ_MUTEX_INIT:
437       req->mutex_init.result = SIMIX_mutex_init();
438       SIMIX_request_answer(req);
439       break;
440
441     case REQ_MUTEX_DESTROY:
442       SIMIX_mutex_destroy(req->mutex_destroy.mutex);
443       SIMIX_request_answer(req);
444       break;
445
446     case REQ_MUTEX_LOCK:
447       SIMIX_pre_mutex_lock(req);
448       break;
449
450     case REQ_MUTEX_TRYLOCK:
451       req->mutex_trylock.result =
452               SIMIX_mutex_trylock(req->mutex_trylock.mutex, req->issuer);
453       SIMIX_request_answer(req);
454       break;
455
456     case REQ_MUTEX_UNLOCK:
457       SIMIX_mutex_unlock(req->mutex_unlock.mutex, req->issuer);
458       SIMIX_request_answer(req);
459       break;
460
461     case REQ_COND_INIT:
462       req->cond_init.result = SIMIX_cond_init();
463       SIMIX_request_answer(req);
464       break;
465
466     case REQ_COND_DESTROY:
467       SIMIX_cond_destroy(req->cond_destroy.cond);
468       SIMIX_request_answer(req);
469       break;
470
471     case REQ_COND_SIGNAL:
472       SIMIX_cond_signal(req->cond_signal.cond);
473       SIMIX_request_answer(req);
474       break;
475
476     case REQ_COND_WAIT:
477       SIMIX_pre_cond_wait(req);
478       break;
479
480     case REQ_COND_WAIT_TIMEOUT:
481       SIMIX_pre_cond_wait_timeout(req);
482       break;
483
484     case REQ_COND_BROADCAST:
485       SIMIX_cond_broadcast(req->cond_broadcast.cond);
486       SIMIX_request_answer(req);
487       break;
488
489     case REQ_SEM_INIT:
490       req->sem_init.result = SIMIX_sem_init(req->sem_init.capacity);
491       SIMIX_request_answer(req);
492       break;
493
494     case REQ_SEM_DESTROY:
495       SIMIX_sem_destroy(req->sem_destroy.sem);
496       SIMIX_request_answer(req);
497       break;
498
499     case REQ_SEM_RELEASE:
500       SIMIX_sem_release(req->sem_release.sem);
501       SIMIX_request_answer(req);
502       break;
503
504     case REQ_SEM_WOULD_BLOCK:
505       req->sem_would_block.result =
506         SIMIX_sem_would_block(req->sem_would_block.sem);
507       SIMIX_request_answer(req);
508       break;
509
510     case REQ_SEM_ACQUIRE:
511       SIMIX_pre_sem_acquire(req);
512       break;
513
514     case REQ_SEM_ACQUIRE_TIMEOUT:
515       SIMIX_pre_sem_acquire_timeout(req);
516       break;
517
518     case REQ_SEM_GET_CAPACITY:
519       req->sem_get_capacity.result = 
520         SIMIX_sem_get_capacity(req->sem_get_capacity.sem);
521       SIMIX_request_answer(req);
522       break;
523   }
524 }
525
526 void SIMIX_request_post(smx_action_t action)
527 {
528   switch (action->type) {
529
530     case SIMIX_ACTION_EXECUTE:
531     case SIMIX_ACTION_PARALLEL_EXECUTE:
532       SIMIX_post_host_execute(action);
533       break;
534
535     case SIMIX_ACTION_COMMUNICATE:
536       SIMIX_post_comm(action);
537       break;
538
539     case SIMIX_ACTION_SLEEP:
540       SIMIX_post_process_sleep(action);
541       break;
542
543     case SIMIX_ACTION_SYNCHRO:
544       SIMIX_post_synchro(action);
545       break;
546
547     case SIMIX_ACTION_IO:
548       break;
549   }
550 }