Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
6163c7c1d4532886125bf6635be38cf957a5df64
[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, int value)
53 {
54   /* The waitany and testany request are transformed into a wait or test request over the
55    * corresponding communication action so it can be treated later by the dependence
56    * function. */
57   switch(req->call){
58     case REQ_COMM_WAITANY:
59       state->internal_req.call = REQ_COMM_WAIT;
60       state->internal_req.issuer = req->issuer;
61       state->internal_req.comm_wait.comm =
62         xbt_dynar_get_as(req->comm_waitany.comms, value, smx_action_t);
63       state->internal_req.comm_wait.timeout = 0;
64       break;
65
66     case REQ_COMM_TESTANY:
67       state->internal_req.call = REQ_COMM_TEST;
68       state->internal_req.issuer = req->issuer;
69
70       if(value > 0)
71         state->internal_req.comm_test.comm =
72           xbt_dynar_get_as(req->comm_testany.comms, value, smx_action_t);
73       else
74         state->internal_req.comm_test.comm = NULL;
75
76       state->internal_req.comm_test.result = value;
77       break;
78
79     default:
80       state->internal_req = *req;
81       break;
82   }
83
84   state->executed_req = *req;
85   state->req_num = value;
86 }
87
88 smx_req_t MC_state_get_executed_request(mc_state_t state, int *value)
89 {
90   *value = state->req_num;
91   return &state->executed_req;
92 }
93
94 smx_req_t MC_state_get_internal_request(mc_state_t state)
95 {
96   return &state->internal_req;
97 }
98
99 smx_req_t MC_state_get_request(mc_state_t state, int *value)
100 {
101   smx_process_t process = NULL;
102   mc_procstate_t procstate = NULL;
103
104
105   xbt_swag_foreach(process, simix_global->process_list){
106     procstate = &state->proc_status[process->pid];
107
108     if(procstate->state == MC_INTERLEAVE){
109       if(SIMIX_process_is_enabled(process)){
110         switch(process->request.call){
111           case REQ_COMM_WAITANY:
112             while(procstate->interleave_count < xbt_dynar_length(process->request.comm_waitany.comms)){
113               if(SIMIX_request_is_enabled_by_idx(&process->request, procstate->interleave_count++)){
114                 *value = procstate->interleave_count - 1;
115                 return &process->request;
116               }
117             }
118             procstate->state = MC_DONE;
119             break;
120
121           case REQ_COMM_TESTANY:
122             if(MC_request_testany_fail(&process->request)){
123               procstate->state = MC_DONE;
124               *value = -1;
125               return &process->request;
126             }
127
128             while(procstate->interleave_count < xbt_dynar_length(process->request.comm_waitany.comms)){
129               if(SIMIX_request_is_enabled_by_idx(&process->request, procstate->interleave_count++)){
130                 *value = procstate->interleave_count - 1;
131                 return &process->request;
132               }
133             }
134             procstate->state = MC_DONE;
135             break;
136
137           default:
138             procstate->state = MC_DONE;
139             *value = 0;
140             return &process->request;
141             break;
142         }
143       }
144     }
145   }
146
147   return NULL;
148 }