1 /* Copyright (c) 2008 Martin Quinson, Cristian Rosa.
2 All rights reserved. */
4 /* This program is free software; you can redistribute it and/or modify it
5 * under the terms of the license (GNU LGPL) which comes with this package. */
9 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_dpor, mc,
10 "Logging specific to MC DPOR exploration");
13 * \brief Initialize the DPOR exploration algorithm
17 mc_state_t initial_state = NULL;
18 smx_process_t process;
20 /* Create the initial state and push it into the exploration stack */
22 initial_state = MC_state_new();
23 xbt_fifo_unshift(mc_stack, initial_state);
26 DEBUG0("**************************************************");
27 DEBUG0("Initial state");
29 /* Wait for requests (schedules processes) */
30 MC_wait_for_requests();
33 /* Get an enabled process and insert it in the interleave set of the initial state */
34 xbt_swag_foreach(process, simix_global->process_list){
35 if(MC_process_is_enabled(process)){
36 MC_state_interleave_process(initial_state, process);
42 /* FIXME: Update Statistics
43 mc_stats->state_size +=
44 xbt_setset_set_size(initial_state->enabled_transitions); */
49 * \brief Perform the model-checking operation using a depth-first search exploration
50 * with Dynamic Partial Order Reductions
56 smx_req_t req = NULL, prev_req = NULL;
57 mc_state_t state = NULL, prev_state = NULL, next_state = NULL;
58 smx_process_t process = NULL;
59 xbt_fifo_item_t item = NULL;
61 while (xbt_fifo_size(mc_stack) > 0) {
63 /* Get current state */
65 xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack));
67 DEBUG0("**************************************************");
68 DEBUG3("Exploration detph=%d (state=%p)(%u interleave)",
69 xbt_fifo_size(mc_stack), state,
70 MC_state_interleave_size(state));
72 /* Update statistics */
73 mc_stats->visited_states++;
75 /* If there are processes to interleave and the maximum depth has not been reached
76 then perform one step of the exploration algorithm */
77 if (xbt_fifo_size(mc_stack) < MAX_DEPTH &&
78 (req = MC_state_get_request(state, &value))) {
80 /* Debug information */
81 if(XBT_LOG_ISENABLED(mc_dpor, xbt_log_priority_debug)){
82 req_str = MC_request_to_string(req, value);
83 if(req->call == REQ_COMM_WAITANY)
84 DEBUG3("Execute: %s (%u of %lu)", req_str, value, xbt_dynar_length(req->comm_waitany.comms));
85 else if(req->call == REQ_COMM_TESTANY)
86 DEBUG3("Execute: %s (%u of %lu)", req_str, value, xbt_dynar_length(req->comm_testany.comms));
88 DEBUG1("Execute: %s", req_str);
92 MC_state_set_executed_request(state, req, value);
93 mc_stats->executed_transitions++;
95 /* Answer the request */
96 SIMIX_request_pre(req, value); /* After this call req is no longer usefull */
98 /* Wait for requests (schedules processes) */
99 MC_wait_for_requests();
101 /* Create the new expanded state */
103 next_state = MC_state_new();
104 xbt_fifo_unshift(mc_stack, next_state);
106 /* Get an enabled process and insert it in the interleave set of the next state */
107 xbt_swag_foreach(process, simix_global->process_list){
108 if(MC_process_is_enabled(process)){
109 MC_state_interleave_process(next_state, process);
115 /* FIXME: Update Statistics
116 mc_stats->state_size +=
117 xbt_setset_set_size(next_state->enabled_transitions);*/
119 /* Let's loop again */
121 /* The interleave set is empty or the maximum depth is reached, let's back-track */
123 DEBUG0("There are no more processes to interleave.");
125 /* Trash the current state, no longer needed */
127 xbt_fifo_shift(mc_stack);
128 MC_state_delete(state);
131 /* Check for deadlocks */
132 if(MC_deadlock_check()){
133 MC_show_deadlock(NULL);
138 /* Traverse the stack backwards until a state with a non empty interleave
139 set is found, deleting all the states that have it empty in the way.
140 For each deleted state, check if the request that has generated it
141 (from it's predecesor state), depends on any other previous request
142 executed before it. If it does then add it to the interleave set of the
143 state that executed that previous request. */
144 while ((state = xbt_fifo_shift(mc_stack)) != NULL) {
145 req = MC_state_get_internal_request(state);
146 xbt_fifo_foreach(mc_stack, item, prev_state, mc_state_t) {
147 if(MC_request_depend(req, MC_state_get_internal_request(prev_state))){
148 if(XBT_LOG_ISENABLED(mc_dpor, xbt_log_priority_debug)){
149 DEBUG0("Dependent Transitions:");
150 prev_req = MC_state_get_executed_request(prev_state, &value);
151 req_str = MC_request_to_string(prev_req, value);
152 DEBUG2("%s (state=%p)", req_str, prev_state);
154 prev_req = MC_state_get_executed_request(state, &value);
155 req_str = MC_request_to_string(prev_req, value);
156 DEBUG2("%s (state=%p)", req_str, state);
160 if(!MC_state_process_is_done(prev_state, req->issuer))
161 MC_state_interleave_process(prev_state, req->issuer);
163 DEBUG1("Process %p is in done set", req->issuer);
168 if (MC_state_interleave_size(state)) {
169 /* We found a back-tracking point, let's loop */
170 xbt_fifo_unshift(mc_stack, state);
171 DEBUG1("Back-tracking to depth %d", xbt_fifo_size(mc_stack));
176 MC_state_delete(state);