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;
}
Beispiel #11
0
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;
}