From b6b9cfcc5428d3b6f42a7f1d83f512658cd83a74 Mon Sep 17 00:00:00 2001 From: weiyu Date: Tue, 15 Oct 2019 17:38:18 -0700 Subject: [PATCH] Final fix; needs to be careful about the side effect of NewFuzzer::find_threads --- newfuzzer.cc | 66 +++++++++++++++++++++++++++++++++++----------------- newfuzzer.h | 2 +- predicate.h | 2 +- 3 files changed, 47 insertions(+), 23 deletions(-) diff --git a/newfuzzer.cc b/newfuzzer.cc index cb25d763..6eb57d88 100644 --- a/newfuzzer.cc +++ b/newfuzzer.cc @@ -65,24 +65,28 @@ int NewFuzzer::selectWrite(ModelAction *read, SnapVector * rf_set while ( rf_set->size() == 0 ) { Thread * read_thread = execution->get_thread(tid); Predicate * selected_branch = get_selected_child_branch(tid); + bool should_sleep = should_conditional_sleep(selected_branch); bool should_reselect_predicate = false; + //model_print("the %d read action of thread %d at %p is unsuccessful\n", read->get_seq_number(), read_thread->get_id(), read->get_location()); - if (!find_threads(read)) { + if ( find_threads(read, should_sleep) ) { + if (should_sleep) { + // reset thread pending action and revert sequence numbers + read_thread->set_pending(read); + read->reset_seq_number(); + execution->restore_last_seq_num(); + + conditional_sleep(read_thread); + // Returning -1 stops the while loop of ModelExecution::process_read + return -1; + } else { + update_predicate_score(selected_branch, SLEEP_FAIL_TYPE2); + should_reselect_predicate = true; + } + } else { update_predicate_score(selected_branch, SLEEP_FAIL_TYPE1); should_reselect_predicate = true; - } else if (!should_conditional_sleep(selected_branch)) { - update_predicate_score(selected_branch, SLEEP_FAIL_TYPE2); - should_reselect_predicate = true; - } else { - // reset thread pending action and revert sequence numbers - read_thread->set_pending(read); - read->reset_seq_number(); - execution->restore_last_seq_num(); - - conditional_sleep(read_thread); - // Returning -1 stops the while loop of ModelExecution::process_read - return -1; } if (should_reselect_predicate) { @@ -271,9 +275,9 @@ bool NewFuzzer::prune_writes(thread_id_t tid, Predicate * pred, break; case NULLITY: equality = ((void*)write_val == NULL); - if (equality != expression->value) - satisfy_predicate = false; - break; + if (equality != expression->value) + satisfy_predicate = false; + break; default: model_print("unknown predicate token\n"); break; @@ -322,9 +326,23 @@ void NewFuzzer::conditional_sleep(Thread * thread) /* history->add_waiting_thread is already called in find_threads */ } -bool NewFuzzer::should_conditional_sleep(Predicate *) +/** + * Decides whether a thread should condition sleep based on + * the sleep score of the chosen predicate. + * + * sleep_score = 100: never sleeps + * sleep_score = 0: always sleeps + **/ +bool NewFuzzer::should_conditional_sleep(Predicate * predicate) { - return true; + int sleep_score = predicate->get_sleep_score(); + int random_num = random() % 100; + + /* should sleep if random_num falls within [sleep_score, 100] */ + if (random_num >= sleep_score) + return true; + + return false; } bool NewFuzzer::has_paused_threads() @@ -397,10 +415,13 @@ void NewFuzzer::notify_paused_thread(Thread * thread) model_print("** thread %d is woken up\n", tid); } -/* Find threads that may write values that the pending read action is waiting for +/* Find threads that may write values that the pending read action is waiting for. + * Side effect: waiting threads are added if should_sleep is true + * + * @param should_sleep Indicate whether waiting threads should be added or not * @return True if any thread is found */ -bool NewFuzzer::find_threads(ModelAction * pending_read) +bool NewFuzzer::find_threads(ModelAction * pending_read, bool should_sleep) { ASSERT(pending_read->is_read()); @@ -423,9 +444,12 @@ bool NewFuzzer::find_threads(ModelAction * pending_read) int distance = node->compute_distance(target_node); if (distance != -1) { - history->add_waiting_thread(self_id, tid, target_node, distance); finds_waiting_for = true; //model_print("thread: %d; distance from node %d to node %d: %d\n", tid, node->get_func_id(), target_node->get_func_id(), distance); + + if (should_sleep) { + history->add_waiting_thread(self_id, tid, target_node, distance); + } } } } diff --git a/newfuzzer.h b/newfuzzer.h index ecab8f21..eea752f4 100644 --- a/newfuzzer.h +++ b/newfuzzer.h @@ -48,7 +48,7 @@ private: bool should_conditional_sleep(Predicate * predicate); void wake_up_paused_threads(int * threadlist, int * numthreads); - bool find_threads(ModelAction * pending_read); + bool find_threads(ModelAction * pending_read, bool should_sleep); void update_predicate_score(Predicate * predicate, sleep_result_t type); }; diff --git a/predicate.h b/predicate.h index 413b2cd8..5c634fbc 100644 --- a/predicate.h +++ b/predicate.h @@ -41,7 +41,7 @@ public: uint32_t get_expl_count() { return exploration_count; } uint32_t get_fail_count() { return failure_count; } - uint32_t get_scleep_score() { return sleep_score; } + uint32_t get_sleep_score() { return sleep_score; } void incr_expl_count(); void incr_fail_count(); void incr_sleep_score(uint32_t amount); -- 2.34.1