Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
mv src/mc/private.h src/mc/mc_private.h
[simgrid.git] / src / mc / mc_state.c
1
2
3 #include "../simix/smx_private.h"
4 #include "xbt/fifo.h"
5 #include "mc_private.h"
6
7 /**
8  * \brief Creates a state data structure used by the exploration algorithm
9  */
10 mc_state_t MC_state_new(void)
11 {
12   mc_state_t state = NULL;
13   
14   state = xbt_new0(s_mc_state_t, 1);
15   state->max_pid = simix_process_maxpid;
16   state->proc_status = xbt_new0(s_mc_procstate_t, state->max_pid);
17   
18   mc_stats->expanded_states++;
19   return state;
20 }
21
22 mc_state_t MC_state_pair_new(void)
23 {
24   mc_state_t state = NULL;
25   
26   state = xbt_new0(s_mc_state_t, 1);
27   state->max_pid = simix_process_maxpid;
28   state->proc_status = xbt_new0(s_mc_procstate_t, state->max_pid);
29   
30   //mc_stats->expanded_states++;
31   return state;
32 }
33
34 /**
35  * \brief Deletes a state data structure
36  * \param trans The state to be deleted
37  */
38 void MC_state_delete(mc_state_t state)
39 {
40   xbt_free(state->proc_status);
41   xbt_free(state);
42 }
43
44 void MC_state_interleave_process(mc_state_t state, smx_process_t process)
45 {
46   state->proc_status[process->pid].state = MC_INTERLEAVE;
47   state->proc_status[process->pid].interleave_count = 0;
48 }
49
50 unsigned int MC_state_interleave_size(mc_state_t state)
51 {
52   unsigned int i, size=0;
53
54   for(i=0; i < state->max_pid; i++){
55     if(state->proc_status[i].state == MC_INTERLEAVE)
56       size++;
57   }
58
59   return size;
60 }
61
62 int MC_state_process_is_done(mc_state_t state, smx_process_t process){
63   return state->proc_status[process->pid].state == MC_DONE ? TRUE : FALSE;
64 }
65
66 void MC_state_set_executed_request(mc_state_t state, smx_simcall_t req, int value)
67 {
68   state->executed_req = *req;
69   state->req_num = value;
70
71   /* The waitany and testany request are transformed into a wait or test request over the
72    * corresponding communication action so it can be treated later by the dependence
73    * function. */
74   switch(req->call){
75     case SIMCALL_COMM_WAITANY:
76       state->internal_req.call = SIMCALL_COMM_WAIT;
77       state->internal_req.issuer = req->issuer;
78       state->internal_comm = *xbt_dynar_get_as(req->comm_waitany.comms, value, smx_action_t);
79       state->internal_req.comm_wait.comm = &state->internal_comm;
80       state->internal_req.comm_wait.timeout = 0;
81       break;
82
83     case SIMCALL_COMM_TESTANY:
84       state->internal_req.call = SIMCALL_COMM_TEST;
85       state->internal_req.issuer = req->issuer;
86
87       if(value > 0)
88         state->internal_comm = *xbt_dynar_get_as(req->comm_testany.comms, value, smx_action_t);
89
90       state->internal_req.comm_wait.comm = &state->internal_comm;
91       state->internal_req.comm_test.result = value;
92       break;
93
94     case SIMCALL_COMM_WAIT:
95       state->internal_req = *req;
96       state->internal_comm = *(req->comm_wait.comm);
97       state->executed_req.comm_wait.comm = &state->internal_comm;
98       state->internal_req.comm_wait.comm = &state->internal_comm;
99       break;
100
101     case SIMCALL_COMM_TEST:
102       state->internal_req = *req;
103       state->internal_comm = *req->comm_test.comm;
104       state->executed_req.comm_test.comm = &state->internal_comm;
105       state->internal_req.comm_test.comm = &state->internal_comm;
106       break;
107
108     default:
109       state->internal_req = *req;
110       break;
111   }
112 }
113
114 smx_simcall_t MC_state_get_executed_request(mc_state_t state, int *value)
115 {
116   *value = state->req_num;
117   return &state->executed_req;
118 }
119
120 smx_simcall_t MC_state_get_internal_request(mc_state_t state)
121 {
122   return &state->internal_req;
123 }
124
125 smx_simcall_t MC_state_get_request(mc_state_t state, int *value)
126 {
127   smx_process_t process = NULL;
128   mc_procstate_t procstate = NULL;
129   unsigned int start_count;
130
131   xbt_swag_foreach(process, simix_global->process_list){
132     procstate = &state->proc_status[process->pid];
133
134     if(procstate->state == MC_INTERLEAVE){
135       if(MC_process_is_enabled(process)){
136         switch(process->simcall.call){
137           case SIMCALL_COMM_WAITANY:
138             *value = -1;
139             while(procstate->interleave_count < xbt_dynar_length(process->simcall.comm_waitany.comms)){
140               if(MC_request_is_enabled_by_idx(&process->simcall, procstate->interleave_count++)){
141                 *value = procstate->interleave_count-1;
142                 break;
143               }
144             }
145
146             if(procstate->interleave_count >= xbt_dynar_length(process->simcall.comm_waitany.comms))
147               procstate->state = MC_DONE;
148
149             if(*value != -1)
150               return &process->simcall;
151
152             break;
153
154           case SIMCALL_COMM_TESTANY:
155             start_count = procstate->interleave_count;
156             *value = -1;
157             while(procstate->interleave_count < xbt_dynar_length(process->simcall.comm_testany.comms)){
158               if(MC_request_is_enabled_by_idx(&process->simcall, procstate->interleave_count++)){
159                 *value = procstate->interleave_count - 1;
160                 break;
161               }
162             }
163
164             if(procstate->interleave_count >= xbt_dynar_length(process->simcall.comm_testany.comms))
165               procstate->state = MC_DONE;
166
167             if(*value != -1 || start_count == 0)
168               return &process->simcall;
169
170             break;
171
172           case SIMCALL_COMM_WAIT:
173             if(process->simcall.comm_wait.comm->comm.src_proc
174                && process->simcall.comm_wait.comm->comm.dst_proc){
175               *value = 0;
176             }else{
177               *value = -1;
178             }
179             procstate->state = MC_DONE;
180             return &process->simcall;
181
182             break;
183
184           default:
185             procstate->state = MC_DONE;
186             *value = 0;
187             return &process->simcall;
188             break;
189         }
190       }
191     }
192   }
193
194   return NULL;
195 }