* @return false: other is already in predecessors
* true : other is added to precedessors
*/
-bool FuncInst::add_pred(FuncInst * other) {
+bool FuncInst::add_pred(FuncInst * other)
+{
func_inst_list_mt::iterator it;
for (it = predecessors.begin(); it != predecessors.end(); it++) {
FuncInst * inst = *it;
return true;
}
-bool FuncInst::add_succ(FuncInst * other) {
+bool FuncInst::add_succ(FuncInst * other)
+{
func_inst_list_mt::iterator it;
for (it = successors.begin(); it != successors.end(); it++) {
FuncInst * inst = *it;
return true;
}
-FuncInst * FuncInst::search_in_collision(ModelAction *act) {
+FuncInst * FuncInst::search_in_collision(ModelAction *act)
+{
action_type type = act->get_type();
func_inst_list_mt::iterator it;
}
return NULL;
}
+
+bool FuncInst::is_read() const
+{
+ return type == ATOMIC_READ || type == ATOMIC_RMWR || type == ATOMIC_RMWRCAS;
+}
func_inst_list_mt * get_preds() { return &predecessors; }
func_inst_list_mt * get_succs() { return &successors; }
+ bool is_read() const;
+
MEMALLOC
private:
//ModelAction * const action;
#include "funcnode.h"
FuncNode::FuncNode() :
- func_insts(),
+ func_inst_map(),
inst_list(),
entry_insts()
{}
+/* Check whether FuncInst with the same type, position, and location
+ * as act has been added to func_inst_map or not. If so, return it;
+ * if not, add it and return it.
+ *
+ * @return FuncInst with the same type, position, and location as act */
FuncInst * FuncNode::get_or_add_action(ModelAction *act)
{
ASSERT(act);
-
const char * position = act->get_position();
/* Actions THREAD_CREATE, THREAD_START, THREAD_YIELD, THREAD_JOIN,
if (position == NULL)
return NULL;
- if ( func_insts.contains(position) ) {
- FuncInst * inst = func_insts.get(position);
+ if ( func_inst_map.contains(position) ) {
+ FuncInst * inst = func_inst_map.get(position);
if (inst->get_type() != act->get_type() ) {
// model_print("action with a different type occurs at line number %s\n", position);
func_inst = new FuncInst(act, this);
inst->get_collisions()->push_back(func_inst);
inst_list.push_back(func_inst); // delete?
- // model_print("collision added\n");
-
+ if (func_inst->is_read())
+ group_reads_by_loc(func_inst);
+
return func_inst;
}
}
FuncInst * func_inst = new FuncInst(act, this);
- func_insts.put(position, func_inst);
-
+ func_inst_map.put(position, func_inst);
inst_list.push_back(func_inst);
+
+ if (func_inst->is_read())
+ group_reads_by_loc(func_inst);
+
return func_inst;
}
entry_insts.push_back(inst);
}
+
+/* group atomic read actions by memory location */
+void FuncNode::group_reads_by_loc(FuncInst * inst)
+{
+ ASSERT(inst);
+ if ( !inst->is_read() )
+ return;
+
+ void * location = inst->get_location();
+
+ func_inst_list_mt * reads;
+ if ( !reads_by_loc.contains(location) ) {
+ reads = new func_inst_list_mt();
+ reads->push_back(inst);
+ reads_by_loc.put(location, reads);
+ return;
+ }
+
+ reads = reads_by_loc.get(location);
+ func_inst_list_mt::iterator it;
+ for (it = reads->begin(); it != reads->end(); it++) {
+ if (inst == *it)
+ return;
+ }
+
+ reads->push_back(inst);
+}
FuncInst * get_or_add_action(ModelAction *act);
- HashTable<const char *, FuncInst *, uintptr_t, 4, model_malloc, model_calloc, model_free> * getFuncInsts() { return &func_insts; }
+ HashTable<const char *, FuncInst *, uintptr_t, 4, model_malloc, model_calloc, model_free> * getFuncInstMap() { return &func_inst_map; }
func_inst_list_mt * get_inst_list() { return &inst_list; }
func_inst_list_mt * get_entry_insts() { return &entry_insts; }
void add_entry_inst(FuncInst * inst);
+ void group_reads_by_loc(FuncInst * inst);
+
MEMALLOC
private:
uint32_t func_id;
* To do: cds_atomic_compare_exchange contains three atomic operations
* that are feeded with the same source line number by llvm pass
*/
- HashTable<const char *, FuncInst *, uintptr_t, 4, model_malloc, model_calloc, model_free> func_insts;
+ HashTable<const char *, FuncInst *, uintptr_t, 4, model_malloc, model_calloc, model_free> func_inst_map;
- /* list of all atomic instructions in this function */
+ /* list of all atomic actions in this function */
func_inst_list_mt inst_list;
- /* possible entry atomic instructions in this function */
+ /* possible entry atomic actions in this function */
func_inst_list_mt entry_insts;
+
+ /* group atomic read actions by memory location */
+ HashTable<void *, func_inst_list_mt *, uintptr_t, 4, model_malloc, model_calloc, model_free> reads_by_loc;
};