void setTraceRef(sllnode<ModelAction *> *ref) { trace_ref = ref; }
void setThrdMapRef(sllnode<ModelAction *> *ref) { thrdmap_ref = ref; }
void setActionRef(sllnode<ModelAction *> *ref) { action_ref = ref; }
- void setFuncActRef(void *ref) { func_act_ref = ref; }
sllnode<ModelAction *> * getTraceRef() { return trace_ref; }
sllnode<ModelAction *> * getThrdMapRef() { return thrdmap_ref; }
sllnode<ModelAction *> * getActionRef() { return action_ref; }
- void * getFuncActRef() { return func_act_ref; }
+
+ void incr_func_ref_count() { func_ref_count++; }
+ void decr_func_ref_count() { if (func_ref_count > 0) func_ref_count--; }
+ uint32_t get_func_ref_count() { return func_ref_count; }
SNAPSHOTALLOC
private:
sllnode<ModelAction *> * trace_ref;
sllnode<ModelAction *> * thrdmap_ref;
sllnode<ModelAction *> * action_ref;
- void * func_act_ref;
+
+ /** @brief Number of read actions that are reading from this store */
+ uint32_t func_ref_count;
/** @brief The value written (for write or RMW; undefined for read) */
uint64_t value;
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();
- // Remove func_act_ref so that actions can be deleted by Execution::collectActions
+ 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
if (rf->get_original_type() != ATOMIC_NOP && rf->get_swap_flag() == false)
rf->use_original_type();
- rf->setFuncActRef(NULL);
+ rf->decr_read_ref_count();
}
- act->setFuncActRef(NULL);
FuncInst * func_inst = get_inst(act);
void * loc = act->get_location();
// 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 act
+ // Do iteration early in case we delete read actions
it = it->getNext();
- // Revert back action types for actions whose types have been changed.
+ // 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)
if (act->get_swap_flag() == true)
act->use_original_type();
- if (act->is_free()) {
- // TODO
- } else if (act->is_read()) {
+ // Free read actions
+ if (act->is_read()) {
if (act->is_rmw()) {
- // reads_from can not be READY_FREE
+ // Do nothing. Its reads_from can not be READY_FREE
} else {
ModelAction *rf = act->get_reads_from();
if (rf->is_free()) {
}
}
+ // 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;
/* Add to curr_inst_list */
- act->setFuncActRef(curr_act_list->add_back(act));
+ curr_act_list->push_back(act);
+
+ // Increment ref count for every action and reads_froms
+ act->incr_read_ref_count();
if (act->is_read()) {
ModelAction * rf = act->get_reads_from();
- void * func_act_ref = rf->getFuncActRef();
- if (func_act_ref == WRITE_REFERENCED) {
- // do nothing
- } else if (func_act_ref == NULL) {
- rf->setFuncActRef(WRITE_REFERENCED);
- }
+ rf->incr_read_ref_count();
}
FuncNode * func_node = func_nodes[func_id];