goto_symext::symex_resultt * reachability_treet::generate_schedule_formula() { int total_states = 0; while (has_more_states()) { total_states++; while ((!get_cur_state().has_cswitch_point_occured() || get_cur_state().check_if_ileaves_blocked()) && get_cur_state().can_execution_continue()) { get_cur_state().symex_step(*this); } if (state_hashing) { if (check_for_hash_collision()) { post_hash_collision_cleanup(); go_next_state(); continue; } else { update_hash_collision_set(); } } next_thread_id = decide_ileave_direction(get_cur_state()); create_next_state(); go_next_state(); } return new goto_symext::symex_resultt(schedule_target, schedule_total_claims, schedule_remaining_claims); }
void reachability_treet::post_hash_collision_cleanup(void) { for (std::vector<bool>::iterator it = get_cur_state().DFS_traversed.begin(); it != get_cur_state().DFS_traversed.end(); it++ ) *it = true; return; }
int reachability_treet::get_ileave_direction_from_user(void) const { std::string input; unsigned int tid; if (get_cur_state().get_active_state().guard.is_false()) std::cout << "This trace's guard is false; it will not be evaulated." << std::endl; // First of all, are there actually any valid context switch targets? for (tid = 0; tid < get_cur_state().threads_state.size(); tid++) { if (check_thread_viable(tid, true)) break; } // If no threads were viable, don't present a choice. if (tid == get_cur_state().threads_state.size()) return get_cur_state().threads_state.size(); std::cout << "Context switch point encountered; please select a thread to run" << std::endl; std::cout << "Current thread states:" << std::endl; execution_states.back()->print_stack_traces(4); while (std::cout << "Input: ", std::getline(std::cin, input)) { if (input == "b") { std::cout << "Back unimplemented" << std::endl; } else if (input == "q") { exit(1); } else if (input.size() <= 0) { ; } else { const char *start; char *end; start = input.c_str(); tid = strtol(start, &end, 10); if (start == end) { std::cout << "Not a valid input" << std::endl; } else if (tid >= get_cur_state().threads_state.size()) { std::cout << "Number out of range"; } else { if (check_thread_viable(tid, false)) break; } } } if (std::cin.eof()) { std::cout << std::endl; exit(1); } return tid; }
bool reachability_treet::step_next_state(void) { next_thread_id = decide_ileave_direction(get_cur_state()); if (next_thread_id != get_cur_state().threads_state.size()) { create_next_state(); return true; } return false; }
void reachability_treet::create_next_state(void) { execution_statet &ex_state = get_cur_state(); if (next_thread_id != ex_state.threads_state.size()) { auto new_state = ex_state.clone(); execution_states.push_back(new_state); //begin - H.Savino if (round_robin) { if(next_thread_id == ex_state.active_thread) new_state->increment_time_slice(); else new_state->reset_time_slice(); } //end - H.Savino /* Make it active, make it follow on from previous state... */ if (new_state->get_active_state_number() != next_thread_id) new_state->increment_context_switch(); new_state->switch_to_thread(next_thread_id); new_state->update_after_switch_point(); } return; }
void reachability_treet::update_hash_collision_set(void) { execution_statet &ex_state = get_cur_state(); crypto_hash hash; hash = ex_state.generate_hash(); hit_hashes.insert(hash); return; }
std::shared_ptr<goto_symext::symex_resultt> reachability_treet::get_next_formula() { assert(execution_states.size() > 0 && "Must setup RT before exploring"); while(!is_has_complete_formula()) { while ((!get_cur_state().has_cswitch_point_occured() || get_cur_state().check_if_ileaves_blocked()) && get_cur_state().can_execution_continue()) get_cur_state().symex_step(*this); if (state_hashing) { if (check_for_hash_collision()) { post_hash_collision_cleanup(); break; } else { update_hash_collision_set(); } } if (por) { get_cur_state().calculate_mpor_constraints(); if (get_cur_state().is_transition_blocked_by_mpor()) break; } next_thread_id = decide_ileave_direction(get_cur_state()); create_next_state(); switch_to_next_execution_state(); if (get_cur_state().interleaving_unviable) break; } (*cur_state_it)->finish_formula(); has_complete_formula = false; return get_cur_state().get_symex_result(); }
bool reachability_treet::check_for_hash_collision(void) const { const execution_statet &ex_state = get_cur_state(); crypto_hash hash; hash = ex_state.generate_hash(); if (hit_hashes.find(hash) != hit_hashes.end()) return true; return false; }
bool reachability_treet::check_thread_viable(unsigned int tid, bool quiet) const { const execution_statet &ex = get_cur_state(); if (ex.DFS_traversed.at(tid) == true) { if (!quiet) std::cout << "Thread unschedulable as it's already been explored" << std::endl; return false; } if (ex.threads_state.at(tid).call_stack.empty()) { if (!quiet) std::cout << "Thread unschedulable due to empty call stack" << std::endl; return false; } if (ex.threads_state.at(tid).thread_ended) { if (!quiet) std::cout << "That thread has ended" << std::endl; return false; } #if 0 if (por && !ex.is_thread_mpor_schedulable(tid)) { if (!quiet) std::cout << "Thread unschedulable due to POR" << std::endl; return false; } #endif if (ex.tid_is_set && ex.monitor_tid == tid) { if (!quiet) std::cout << "Can't context switch to a monitor thread" << std::endl; return false; } return true; }
//begin - H.Savino int reachability_treet::get_ileave_direction_from_scheduling(void) const { unsigned int tid; // If the guard on this execution trace is false, no context switches are // going to be run over in the future and just general randomness is going to // occur. So there's absolutely no reason exploring further. if (get_cur_state().get_active_state().guard.is_false()) { std::cout << "This trace's guard is false; it will not be evaulated." << std::endl; exit(1); } // First of all, are there actually any valid context switch targets? for (tid = 0; tid < get_cur_state().threads_state.size(); tid++) { if (check_thread_viable(tid, true)) break; } // If no threads were viable, don't present a choice. if (tid == get_cur_state().threads_state.size()) return get_cur_state().threads_state.size(); tid=get_cur_state().active_thread; if(get_cur_state().TS_number < this->TS_slice-1){ if (check_thread_viable(tid, true)) return tid; } while(1){ tid=(tid + 1)%get_cur_state().threads_state.size(); if (check_thread_viable(tid, true)){ break; } } return tid; }
int main (int argc, char* argv[]) { ll_lrm_t* lrm; lrm_rsc_t* rsc = NULL; lrm_op_t* op = NULL; const char* rid = "ip248"; GHashTable* param = NULL; GList* classes; int i; cl_log_set_entity("apitest"); cl_log_set_facility(LOG_USER); lrm = ll_lrm_new("lrm"); if(NULL == lrm) { printf("lrm==NULL\n"); return 1; } puts("sigon..."); lrm->lrm_ops->signon(lrm,"apitest"); classes = lrm->lrm_ops->get_rsc_class_supported(lrm); lrm_free_str_list(classes); param = g_hash_table_new(g_str_hash,g_str_equal); g_hash_table_insert(param, strdup("1"), strdup("192.168.192.100")); puts("add_rsc..."); lrm->lrm_ops->add_rsc(lrm, rid, "heartbeat", "IPaddr", "heartbeat", param); puts("get_rsc..."); rsc = lrm->lrm_ops->get_rsc(lrm, rid); printf_rsc(rsc); puts("perform_op(start)..."); op = lrm_op_new(); op->op_type = g_strdup("start"); op->params = param; op->timeout = 0; op->user_data = strdup("It is a start op!"); if ( op->user_data == NULL ) { fprintf(stderr, "No enough memory.\n"); return -1; } op->user_data_len = strlen(op->user_data)+1; op->interval = 0; op->target_rc = EVERYTIME; rsc->ops->perform_op(rsc,op); printf_op(op); lrm_free_op(op); puts("perform_op(status)..."); param = g_hash_table_new(g_str_hash,g_str_equal); g_hash_table_insert(param, strdup("1"), strdup("192.168.192.100")); op = lrm_op_new(); op->op_type = g_strdup("status"); op->params = param; op->timeout = 0; op->user_data = strdup("It is a status op!"); if ( op->user_data == NULL ) { fprintf(stderr, "No enough memory.\n"); return -1; } op->user_data_len = strlen(op->user_data)+1; op->interval = 1000; op->target_rc=EVERYTIME; rsc->ops->perform_op(rsc,op); printf_op(op); lrm_free_op(op); puts("perform_op(stop)..."); param = g_hash_table_new(g_str_hash,g_str_equal); g_hash_table_insert(param, strdup("1"), strdup("192.168.192.100")); op = lrm_op_new(); op->op_type = g_strdup("stop"); op->params = param; op->timeout = 0; op->user_data = strdup("It is a stop op!"); if ( op->user_data == NULL ) { fprintf(stderr, "No enough memory.\n"); return -1; } op->user_data_len = strlen(op->user_data)+1; op->interval = 0; op->target_rc=EVERYTIME; rsc->ops->perform_op(rsc,op); printf_op(op); lrm_free_op(op); puts("perform_op(status)..."); param = g_hash_table_new(g_str_hash,g_str_equal); g_hash_table_insert(param, strdup("1"), strdup("192.168.192.100")); op = lrm_op_new(); op->op_type = g_strdup("status"); op->params = param; op->timeout = 0; op->user_data = strdup("It is a status op!"); if ( op->user_data == NULL ) { fprintf(stderr, "No enough memory.\n"); return -1; } op->user_data_len = strlen(op->user_data)+1; op->interval = 2000; op->target_rc=EVERYTIME; rsc->ops->perform_op(rsc,op); printf_op(op); lrm_free_op(op); puts("perform_op(start)..."); param = g_hash_table_new(g_str_hash,g_str_equal); g_hash_table_insert(param, strdup("1"), strdup("192.168.192.100")); op = lrm_op_new(); op->op_type = g_strdup("start"); op->params = param; op->timeout = 0; op->user_data = strdup("It is a start op!"); if ( op->user_data == NULL ) { fprintf(stderr, "No enough memory.\n"); return -1; } op->user_data_len = strlen(op->user_data)+1; op->interval = 0; op->target_rc = EVERYTIME; rsc->ops->perform_op(rsc,op); printf_op(op); lrm_free_op(op); puts("perform_op(status)..."); param = g_hash_table_new(g_str_hash,g_str_equal); g_hash_table_insert(param, strdup("1"), strdup("192.168.192.100")); op = lrm_op_new(); op->op_type = g_strdup("status"); op->params = param; op->timeout = 0; op->user_data = strdup("It is a status op!"); if ( op->user_data == NULL ) { fprintf(stderr, "No enough memory.\n"); return -1; } op->user_data_len = strlen(op->user_data)+1; op->interval = 3000; op->target_rc=EVERYTIME; rsc->ops->perform_op(rsc,op); printf_op(op); lrm_free_op(op); puts("perform_op(stop)..."); param = g_hash_table_new(g_str_hash,g_str_equal); g_hash_table_insert(param, strdup("1"), strdup("192.168.192.100")); op = lrm_op_new(); op->op_type = g_strdup("stop"); op->params = param; op->timeout = 0; op->user_data = strdup("It is a stop op!"); if ( op->user_data == NULL ) { fprintf(stderr, "No enough memory.\n"); return -1; } op->user_data_len = strlen(op->user_data)+1; op->interval = 0; op->target_rc=EVERYTIME; rsc->ops->perform_op(rsc,op); printf_op(op); lrm_free_op(op); for(i = 0; i < 5; i++) { puts("get_cur_state..."); get_cur_state(rsc); puts("sleep a while..."); sleep(1); } puts("delete_rsc..."); lrm->lrm_ops->delete_rsc(lrm, rid); lrm_free_rsc(rsc); puts("signoff..."); lrm->lrm_ops->signoff(lrm); return 0; }