X-Git-Url: http://plrg.eecs.uci.edu/git/?p=c11tester.git;a=blobdiff_plain;f=waitobj.cc;h=dc422be7804e0a245130b1ff0b3a93c511931e75;hp=42870b5c7d1cb65edee8924fd2967a4bfd2db298;hb=25d73096cfc14c655f94b01bb235cc5efd1d5696;hpb=6d6466bb4b471d3ff1062bb574b1f50dad0f31c9 diff --git a/waitobj.cc b/waitobj.cc index 42870b5c..dc422be7 100644 --- a/waitobj.cc +++ b/waitobj.cc @@ -2,20 +2,23 @@ #include "threads-model.h" #include "funcnode.h" +#define COUNTER_THRESHOLD 1000 + WaitObj::WaitObj(thread_id_t tid) : tid(tid), waiting_for(32), waited_by(32), thrd_dist_maps(), - thrd_target_nodes() + thrd_target_nodes(), + thrd_action_counters() {} WaitObj::~WaitObj() { - for (uint i = 0; i < thrd_dist_maps.size(); i++) + for (uint i = 0;i < thrd_dist_maps.size();i++) delete thrd_dist_maps[i]; - for (uint i = 0; i < thrd_target_nodes.size(); i++) + for (uint i = 0;i < thrd_target_nodes.size();i++) delete thrd_target_nodes[i]; } @@ -43,7 +46,7 @@ void WaitObj::add_waited_by(thread_id_t other) * @return true if "other" is removed from waiting_for set * false if only a target node of "other" is removed */ -bool WaitObj::remove_waiting_for(thread_id_t other, FuncNode * node) +bool WaitObj::remove_waiting_for_node(thread_id_t other, FuncNode * node) { dist_map_t * dist_map = getDistMap(other); dist_map->remove(node); @@ -53,13 +56,32 @@ bool WaitObj::remove_waiting_for(thread_id_t other, FuncNode * node) /* The thread has no nodes to reach */ if (target_nodes->isEmpty()) { + int index = id_to_int(other); + thrd_action_counters[index] = 0; waiting_for.remove(other); + return true; } return false; } +/* Stop waiting for the thread */ +void WaitObj::remove_waiting_for(thread_id_t other) +{ + waiting_for.remove(other); + + // TODO: clear dist_map or not? + /* dist_map_t * dist_map = getDistMap(other); + dist_map->reset(); */ + + node_set_t * target_nodes = getTargetNodes(other); + target_nodes->reset(); + + int index = id_to_int(other); + thrd_action_counters[index] = 0; +} + void WaitObj::remove_waited_by(thread_id_t other) { waited_by.remove(other); @@ -68,7 +90,11 @@ void WaitObj::remove_waited_by(thread_id_t other) int WaitObj::lookup_dist(thread_id_t tid, FuncNode * target) { dist_map_t * map = getDistMap(tid); - if (map->contains(target)) + node_set_t * node_set = getTargetNodes(tid); + + /* thrd_dist_maps is not reset when clear_waiting_for is called, + * so node_set should be checked */ + if (node_set->contains(target) && map->contains(target)) return map->get(target); return -1; @@ -81,7 +107,7 @@ dist_map_t * WaitObj::getDistMap(thread_id_t tid) if (old_size <= thread_id) { thrd_dist_maps.resize(thread_id + 1); - for (int i = old_size; i < thread_id + 1; i++) { + for (int i = old_size;i < thread_id + 1;i++) { thrd_dist_maps[i] = new dist_map_t(16); } } @@ -96,7 +122,7 @@ node_set_t * WaitObj::getTargetNodes(thread_id_t tid) if (old_size <= thread_id) { thrd_target_nodes.resize(thread_id + 1); - for (int i = old_size; i < thread_id + 1; i++) { + for (int i = old_size;i < thread_id + 1;i++) { thrd_target_nodes[i] = new node_set_t(16); } } @@ -104,17 +130,46 @@ node_set_t * WaitObj::getTargetNodes(thread_id_t tid) return thrd_target_nodes[thread_id]; } +/** + * Increment action counter for thread tid + * @return true if the counter for tid expires + */ +bool WaitObj::incr_counter(thread_id_t tid) +{ + int thread_id = id_to_int(tid); + + /* thrd_action_counters.resize does not work here */ + while (thrd_action_counters.size() <= (uint) thread_id) { + thrd_action_counters.push_back(0); + } + + thrd_action_counters[thread_id]++; + if (thrd_action_counters[thread_id] > COUNTER_THRESHOLD) { + thrd_action_counters[thread_id] = 0; + return true; + } + + return false; +} + void WaitObj::clear_waiting_for() { thrd_id_set_iter * iter = waiting_for.iterator(); while (iter->hasNext()) { thread_id_t tid = iter->next(); int index = id_to_int(tid); - thrd_target_nodes[index]->reset(); + thrd_action_counters[index] = 0; + /* thrd_dist_maps are not reset because distances - * will be overwritten when node targets are added */ + * will be overwritten when node targets are added + * thrd_dist_maps[index]->reset(); */ + + node_set_t * target_nodes = getTargetNodes(tid); + target_nodes->reset(); } + delete iter; + waiting_for.reset(); /* waited_by relation should be kept */ } @@ -132,11 +187,12 @@ void WaitObj::print_waiting_for(bool verbose) model_print("%d ", waiting_for_id); } model_print("\n"); + delete it; if (verbose) { /* Print out the distances from each thread to target nodes */ model_print("\t"); - for (uint i = 0; i < thrd_target_nodes.size(); i++) { + for (uint i = 0;i < thrd_target_nodes.size();i++) { dist_map_t * dist_map = getDistMap(i); node_set_t * node_set = getTargetNodes(i); node_set_iter * node_iter = node_set->iterator(); @@ -144,13 +200,15 @@ void WaitObj::print_waiting_for(bool verbose) if (!node_set->isEmpty()) { model_print("[thread %d](", int_to_id(i)); - while (node_iter->hasNext()){ + while (node_iter->hasNext()) { FuncNode * node = node_iter->next(); int dist = dist_map->get(node); model_print("node %d: %d, ", node->get_func_id(), dist); } model_print(") "); } + + delete node_iter; } model_print("\n"); } @@ -170,4 +228,5 @@ void WaitObj::print_waited_by() } model_print("\n"); + delete it; }