Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add suport for TestAny and WaitAny requests to the model-checker.
[simgrid.git] / src / mc / mc_state.c
1 #include "../simix/private.h"
2 #include "xbt/fifo.h"
3 #include "private.h"
4
5 /**
6  * \brief Creates a state data structure used by the exploration algorithm
7  */
8 mc_state_t MC_state_new(void)
9 {
10   mc_state_t state = NULL;
11   
12   state = xbt_new0(s_mc_state_t, 1);
13   state->max_pid = simix_process_maxpid;
14   state->proc_status = xbt_new0(s_mc_procstate_t, state->max_pid);
15   
16   mc_stats->expanded_states++;
17   return state;
18 }
19
20 /**
21  * \brief Deletes a state data structure
22  * \param trans The state to be deleted
23  */
24 void MC_state_delete(mc_state_t state)
25 {
26   xbt_free(state->proc_status);
27   xbt_free(state);
28 }
29
30 void MC_state_interleave_process(mc_state_t state, smx_process_t process)
31 {
32   state->proc_status[process->pid].state = MC_INTERLEAVE;
33   state->proc_status[process->pid].interleave_count = 0;
34 }
35
36 unsigned int MC_state_interleave_size(mc_state_t state)
37 {
38   unsigned int i, size=0;
39
40   for(i=0; i < state->max_pid; i++){
41     if(state->proc_status[i].state == MC_INTERLEAVE)
42       size++;
43   }
44
45   return size;
46 }
47
48 int MC_state_process_is_done(mc_state_t state, smx_process_t process){
49   return state->proc_status[process->pid].state == MC_DONE ? TRUE : FALSE;
50 }
51
52 void MC_state_set_executed_request(mc_state_t state, smx_req_t req, unsigned int value)
53 {
54   state->executed_value = value;
55   state->executed = *req;
56 }
57
58 smx_req_t MC_state_get_executed_request(mc_state_t state, unsigned int *value)
59 {
60   *value = state->executed_value;
61   return &state->executed;
62 }
63
64 smx_req_t MC_state_get_request(mc_state_t state, unsigned int *value)
65 {
66   smx_process_t process = NULL;
67   mc_procstate_t procstate = NULL;
68
69
70   xbt_swag_foreach(process, simix_global->process_list){
71     procstate = &state->proc_status[process->pid];
72
73     if(procstate->state == MC_INTERLEAVE){
74       if(SIMIX_process_is_enabled(process)){
75         switch(process->request.call){
76           case REQ_COMM_WAITANY:
77             while(procstate->interleave_count < xbt_dynar_length(process->request.comm_waitany.comms)){
78               if(SIMIX_request_is_enabled_by_idx(&process->request, procstate->interleave_count++)){
79                 *value = procstate->interleave_count - 1;
80                 return &process->request;
81               }
82             }
83             procstate->state = MC_DONE;
84             break;
85
86           case REQ_COMM_TESTANY:
87             if(MC_request_testany_fail(&process->request)){
88               procstate->state = MC_DONE;
89               *value = (unsigned int)-1;
90               return &process->request;
91             }
92
93             while(procstate->interleave_count < xbt_dynar_length(process->request.comm_waitany.comms)){
94               if(SIMIX_request_is_enabled_by_idx(&process->request, procstate->interleave_count++)){
95                 *value = procstate->interleave_count - 1;
96                 return &process->request;
97               }
98             }
99             procstate->state = MC_DONE;
100             break;
101
102           default:
103             procstate->state = MC_DONE;
104             *value = 0;
105             return &process->request;
106             break;
107         }
108       }
109     }
110   }
111
112   return NULL;
113 }