return;
HashTable<void *, value_set_t *, uintptr_t, 0> * write_history = history->getWriteHistory();
+ HashSet<ModelAction *, uintptr_t, 2> write_actions;
/* build inst_list from act_list for later processing */
func_inst_list_t inst_list;
for (sllnode<ModelAction *> * it = act_list->begin();it != NULL;it = it->getNext()) {
ModelAction * act = it->getVal();
+
+ // Use the original action type and decrement ref count
+ // so that actions may be deleted by Execution::collectActions
+ if (act->get_original_type() != ATOMIC_NOP && act->get_swap_flag() == false)
+ act->use_original_type();
+
+ act->decr_read_ref_count();
+
+ if (act->is_read()) {
+ // For every read or rmw actions in this list, the reads_from was marked, and not deleted.
+ // So it is safe to call get_reads_from
+ ModelAction * rf = act->get_reads_from();
+ if (rf->get_original_type() != ATOMIC_NOP && rf->get_swap_flag() == false)
+ rf->use_original_type();
+
+ rf->decr_read_ref_count();
+ }
+
FuncInst * func_inst = get_inst(act);
void * loc = act->get_location();
}
}
-// model_print("function %s\n", func_name);
-// print_val_loc_map();
-
update_inst_tree(&inst_list);
update_predicate_tree(&rw_act_list);
+ // Revert back action types and free
+ for (sllnode<ModelAction *> * it = act_list->begin(); it != NULL;) {
+ ModelAction * act = it->getVal();
+ // Do iteration early in case we delete read actions
+ it = it->getNext();
+
+ // Collect write actions and reads_froms
+ if (act->is_read()) {
+ if (act->is_rmw()) {
+ write_actions.add(act);
+ }
+
+ ModelAction * rf = act->get_reads_from();
+ write_actions.add(rf);
+ } else if (act->is_write()) {
+ write_actions.add(act);
+ }
+
+ // Revert back action types
+ if (act->is_read()) {
+ ModelAction * rf = act->get_reads_from();
+ if (rf->get_swap_flag() == true)
+ rf->use_original_type();
+ }
+
+ if (act->get_swap_flag() == true)
+ act->use_original_type();
+
+ // Free read actions
+ if (act->is_read()) {
+ if (act->is_rmw()) {
+ // Do nothing. Its reads_from can not be READY_FREE
+ } else {
+ ModelAction *rf = act->get_reads_from();
+ if (rf->is_free()) {
+ model_print("delete read %d; %p\n", act->get_seq_number(), act);
+ delete act;
+ }
+ }
+ }
+ }
+
+ // Free write actions if possible
+ HSIterator<ModelAction *, uintptr_t, 2> * it = write_actions.iterator();
+ while (it->hasNext()) {
+ ModelAction * act = it->next();
+
+ if (act->is_free() && act->get_read_ref_count() == 0)
+ delete act;
+ }
+ delete it;
+
// print_predicate_tree();
}
* @return true if branch found, false otherwise.
*/
bool FuncNode::follow_branch(Predicate ** curr_pred, FuncInst * next_inst,
-ModelAction * next_act, Predicate ** unset_predicate)
+ ModelAction * next_act, Predicate ** unset_predicate)
{
/* Check if a branch with func_inst and corresponding predicate exists */
bool branch_found = false;
bool equality;
switch(pred_expression->token) {
- case NOPREDICATE:
- predicate_correct = true;
- break;
- case EQUALITY:
- FuncInst * to_be_compared;
- ModelAction * last_act;
+ case NOPREDICATE:
+ predicate_correct = true;
+ break;
+ case EQUALITY:
+ FuncInst * to_be_compared;
+ ModelAction * last_act;
- to_be_compared = pred_expression->func_inst;
- last_act = to_be_compared->get_associated_act(marker);
+ to_be_compared = pred_expression->func_inst;
+ last_act = to_be_compared->get_associated_act(marker);
- last_read = last_act->get_reads_from_value();
- next_read = next_act->get_reads_from_value();
- equality = (last_read == next_read);
- if (equality != pred_expression->value)
- predicate_correct = false;
+ last_read = last_act->get_reads_from_value();
+ next_read = next_act->get_reads_from_value();
+ equality = (last_read == next_read);
+ if (equality != pred_expression->value)
+ predicate_correct = false;
- break;
- case NULLITY:
- next_read = next_act->get_reads_from_value();
- // TODO: implement likely to be null
- equality = ( (void*) (next_read & 0xffffffff) == NULL);
- if (equality != pred_expression->value)
- predicate_correct = false;
- break;
- default:
+ break;
+ case NULLITY:
+ next_read = next_act->get_reads_from_value();
+ // TODO: implement likely to be null
+ equality = ( (void*) (next_read & 0xffffffff) == NULL);
+ if (equality != pred_expression->value)
predicate_correct = false;
- model_print("unkown predicate token\n");
- break;
+ break;
+ default:
+ predicate_correct = false;
+ model_print("unkown predicate token\n");
+ break;
}
}
/* Infer predicate expressions, which are generated in FuncNode::generate_predicates */
void FuncNode::infer_predicates(FuncInst * next_inst, ModelAction * next_act,
-SnapVector<struct half_pred_expr *> * half_pred_expressions)
+ SnapVector<struct half_pred_expr *> * half_pred_expressions)
{
void * loc = next_act->get_location();
/* Able to generate complex predicates when there are multiple predciate expressions */
void FuncNode::generate_predicates(Predicate * curr_pred, FuncInst * next_inst,
-SnapVector<struct half_pred_expr *> * half_pred_expressions)
+ SnapVector<struct half_pred_expr *> * half_pred_expressions)
{
if (half_pred_expressions->size() == 0) {
Predicate * new_pred = new Predicate(next_inst);
bool FuncNode::amend_predicate_expr(Predicate * curr_pred, FuncInst * next_inst, ModelAction * next_act)
{
ModelVector<Predicate *> * children = curr_pred->get_children();
- ASSERT(children->size() == 1);
- // there should only be only child
- Predicate * unset_pred = (*children)[0];
+ Predicate * unset_pred = NULL;
+ for (uint i = 0;i < children->size();i++) {
+ Predicate * child = (*children)[i];
+ if (child->get_func_inst() == next_inst) {
+ unset_pred = child;
+ break;
+ }
+ }
+
uint64_t read_val = next_act->get_reads_from_value();
// only generate NULLITY predicate when it is actually NULL.
template<typename _Tp>
static int partition(ModelVector<_Tp *> * arr, int low, int high)
{
- unsigned int pivot = (*arr)[high]->get_depth();
+ unsigned int pivot = (*arr)[high] -> get_depth();
int i = low - 1;
- for (int j = low; j <= high - 1; j++) {
- if ( (*arr)[j]->get_depth() < pivot ) {
- i++;
+ for (int j = low;j <= high - 1;j ++) {
+ if ( (*arr)[j] -> get_depth() < pivot ) {
+ i ++;
_Tp * tmp = (*arr)[i];
(*arr)[i] = (*arr)[j];
(*arr)[j] = tmp;
double weight_sum = 0;
bool has_unassigned_node = false;
- for (uint i = 0; i < children->size(); i++) {
+ for (uint i = 0;i < children->size();i++) {
Predicate * child = (*children)[i];
// If a child has unassigned weight
failed_predicates.reset();
quickSort(&leaves_tmp_storage, 0, leaves_tmp_storage.size() - 1);
- for (uint i = 0; i < leaves_tmp_storage.size(); i++) {
+ for (uint i = 0;i < leaves_tmp_storage.size();i++) {
Predicate * pred = leaves_tmp_storage[i];
double weight = 100.0 / sqrt(pred->get_expl_count() + pred->get_fail_count() + 1);
pred->set_weight(weight);
double weight_sum = 0;
bool has_unassigned_node = false;
- for (uint i = 0; i < children->size(); i++) {
+ for (uint i = 0;i < children->size();i++) {
Predicate * child = (*children)[i];
double weight = child->get_weight();
}
}
- for (uint i = 0; i < weight_debug_vec.size(); i++) {
+ for (uint i = 0;i < weight_debug_vec.size();i++) {
Predicate * tmp = weight_debug_vec[i];
ASSERT( tmp->get_weight() != 0 );
}