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) {
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;
/* 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()
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());
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);
+ }
}
}
}