diff --git a/src/core/cpn/DatabaseCampaign.cc b/src/core/cpn/DatabaseCampaign.cc index 120283ed..82e0f741 100644 --- a/src/core/cpn/DatabaseCampaign.cc +++ b/src/core/cpn/DatabaseCampaign.cc @@ -112,16 +112,17 @@ void DatabaseCampaign::collect_result_thread() { bool DatabaseCampaign::run_variant(Database::Variant variant) { /* Gather all unfinished jobs */ int experiment_count; - std::string sql_select = "SELECT pilot_id, g.fspmethod_id, g.variant_id, p.injection_instr, p.injection_instr_absolute, g.data_address, p.data_width "; + std::string sql_select = "SELECT p.id, p.fspmethod_id, p.variant_id, p.injection_instr, p.injection_instr_absolute, p.data_address, p.data_width, t.instr1, t.instr2 "; std::stringstream ss; - ss << " FROM fspgroup g" - << " INNER JOIN fsppilot p ON p.id = g.pilot_id " - << " WHERE p.known_outcome = 0 " - << " AND g.fspmethod_id = " << fspmethod_id - << " AND g.variant_id = " << variant.id - << " AND (SELECT COUNT(*) FROM " + db_connect.result_table() + " as r WHERE r.pilot_id = g.pilot_id)" + ss << " FROM trace t, fsppilot p" + << " WHERE p.fspmethod_id = " << fspmethod_id + << " AND p.variant_id = " << variant.id + << " AND (SELECT COUNT(*) FROM " + db_connect.result_table() + " as r WHERE r.pilot_id = p.id)" << " < " << expected_number_of_results(variant.variant, variant.benchmark) - << " ORDER BY p.injection_instr"; + << " AND p.variant_id = t.variant_id" + << " AND p.instr2 = t.instr2" + << " AND p.data_address = t.data_address" + << " ORDER BY t.instr1"; std::string sql_body = ss.str(); /* Get the number of unfinished experiments */ @@ -146,6 +147,8 @@ bool DatabaseCampaign::run_variant(Database::Variant variant) { unsigned injection_instr = atoi(row[3]); unsigned data_address = strtoul(row[5], NULL, 10); unsigned data_width = atoi(row[6]); + unsigned instr1 = strtoul(row[7], NULL, 10); + unsigned instr2 = strtoul(row[8], NULL, 10); DatabaseCampaignMessage pilot; @@ -157,7 +160,7 @@ bool DatabaseCampaign::run_variant(Database::Variant variant) { pilot.set_variant(variant.variant); pilot.set_benchmark(variant.benchmark); - ip.parseFromInjectionInstr(injection_instr); + ip.parseFromInjectionInstr(instr1, instr2); ip.addToCampaignMessage(pilot); if (row[4]) { diff --git a/src/core/cpn/InjectionPoint.hpp b/src/core/cpn/InjectionPoint.hpp index baf17610..7cd6544c 100644 --- a/src/core/cpn/InjectionPoint.hpp +++ b/src/core/cpn/InjectionPoint.hpp @@ -5,6 +5,8 @@ #include "util/Logger.hpp" #include "config/FailConfig.hpp" +#include + namespace fail { /** @@ -26,7 +28,7 @@ public: * Used by server. * @param inj_instr trace instruction offset to be parsed */ - virtual void parseFromInjectionInstr(unsigned inj_instr) = 0; + virtual void parseFromInjectionInstr(unsigned instr1, unsigned instr2) = 0; /** * Parses (extracts) generic representation from a DatabaseCampaignMessage. @@ -62,19 +64,28 @@ class SmartHops; class InjectionPointHops : public InjectionPointBase { private: SmartHops *m_sa; // !< Hop calculator which generates the hop chain - uint32_t m_curr_inst; // !< Instruction for which currently a hop chain is available + + // Boundaries must be signed to ensure, they can be initialized as outside of beginning + // of the trace (instr is -1). + long m_curr_instr1; // !< Lower end of instructions for which currently a hop chain is available + long m_curr_instr2; // !< Upper end of instructions for which currently a hop chain is available + bool m_initialized; + std::vector m_results; void init(); public: - InjectionPointHops(); + InjectionPointHops() : InjectionPointBase(), m_sa(NULL), m_curr_instr1(-1), + m_curr_instr2(-1), m_initialized(false) {} + virtual ~InjectionPointHops(); /** * Parses a hop chain from a injection instruction (trace offset). - * @param inj_instr trace instruction offset to be parsed + * @param instr1 trace instruction offset of beginning of equivalence class + * @param instr2 trace instruction offset of ending of equivalence class */ - virtual void parseFromInjectionInstr(unsigned inj_instr); + virtual void parseFromInjectionInstr(unsigned instr1, unsigned instr2); }; typedef InjectionPointHops ConcreteInjectionPoint; @@ -94,9 +105,10 @@ public: /** * Parses a trace offset from a injection instruction (trace offset), * so it effectively just stores the value in the protobuf message. - * @param inj_instr trace instruction offset to be parsed + * @param instr1 trace instruction offset of beginning of equivalence class + * @param instr2 trace instruction offset of ending of equivalence class */ - virtual void parseFromInjectionInstr(unsigned inj_instr); + virtual void parseFromInjectionInstr(unsigned instr1, unsigned instr2); }; typedef InjectionPointSteps ConcreteInjectionPoint; diff --git a/src/core/cpn/InjectionPointHops.cc b/src/core/cpn/InjectionPointHops.cc index fc1f1f6b..a1cf957c 100644 --- a/src/core/cpn/InjectionPointHops.cc +++ b/src/core/cpn/InjectionPointHops.cc @@ -1,10 +1,10 @@ #include "InjectionPoint.hpp" #include "util/smarthops/SmartHops.hpp" -namespace fail { +#include +#include -InjectionPointHops::InjectionPointHops() : InjectionPointBase(), m_sa(NULL), m_curr_inst(0), m_initialized(false) { -} +namespace fail { InjectionPointHops::~InjectionPointHops() { @@ -15,7 +15,7 @@ InjectionPointHops::~InjectionPointHops() { void InjectionPointHops::init() { m_sa = new SmartHops(); - m_curr_inst = 0; + char * elfpath = getenv("FAIL_TRACE_PATH"); if(elfpath == NULL){ m_log << "FAIL_TRACE_PATH not set :(" << std::endl; @@ -27,27 +27,73 @@ void InjectionPointHops::init() m_initialized = true; } -void InjectionPointHops::parseFromInjectionInstr(unsigned inj_instr) { +/* + * if (!it->has_costs()) { + m_log << "FATAL ERROR: Costs must be delivered in order to calculate minimum costs" << endl; + } + */ + +void InjectionPointHops::parseFromInjectionInstr(unsigned instr1, unsigned instr2) { if (!m_initialized) { init(); } - // Already calculated result needed? - if (m_curr_inst == inj_instr) { - return; - } - - // Non monotonic ascending injection instruction given? - if (m_curr_inst > inj_instr) { - m_log << "FATAL ERROR: Got not monotonic ascending values of injection instruction" << std::endl; - exit(-1); + // clear results older than instr1, as the input needs to be sorted by instr1, these + // results won't be needed anymore + std::vector::iterator it = m_results.begin(), delete_iterator = m_results.end(); + for (; it != m_results.end(); it++) { + if (!it->has_target_trace_position()) { + m_log << "FATAL ERROR: Target trace offset must be delivered in order to calculate minimum costs" << std::endl; + } + if (it->target_trace_position() < instr1) { + delete_iterator = it; + } } - if (!m_sa->calculateFollowingHop(m_ip, inj_instr)) { - m_log << "FATAL ERROR: Trace does not contain enough instructions (" << inj_instr << ")" << std::endl; - exit(-1); + // Delete as chunk + if (delete_iterator != m_results.end()) { + m_results.erase(m_results.begin(), delete_iterator); + m_curr_instr1 = instr1; } - m_curr_inst = inj_instr; + + // Calculate next needed results + while (instr2 > m_curr_instr2) { + // if instr1 is bigger than nex instr2, we can skip instructions + // And current instr1 will be newly defined + unsigned new_curr_instr2; + if (instr1 > m_curr_instr2) { + m_curr_instr1 = instr1; + new_curr_instr2 = instr1; + } else { + new_curr_instr2 = m_curr_instr2 + 1; + } + + InjectionPointMessage m; + if (!m_sa->calculateFollowingHop(m, new_curr_instr2)) { + m_log << "FATAL ERROR: Trace does not contain enough instructions (no instruction with offset " + << new_curr_instr2 << ")" << std::endl; + exit(-1); + } + + m_results.push_back(m); + m_curr_instr2 = new_curr_instr2; + } + + // Choose minimum + InjectionPointMessage *min_cost_msg; + uint32_t min_costs = std::numeric_limits::max(); + + std::vector::iterator search, search_end; + search = m_results.begin() + (instr1 - m_curr_instr1); + search_end = m_results.begin() + (instr2 - m_curr_instr1); + + for(;search != search_end; search++) { + if (search->costs() < min_costs) { + min_cost_msg = &(*search); + min_costs = search->costs(); + } + } + m_ip = *min_cost_msg; } } /* namespace fail */ diff --git a/src/core/cpn/InjectionPointSteps.cc b/src/core/cpn/InjectionPointSteps.cc index ab07688a..962d66b7 100644 --- a/src/core/cpn/InjectionPointSteps.cc +++ b/src/core/cpn/InjectionPointSteps.cc @@ -2,9 +2,9 @@ namespace fail { -void InjectionPointSteps::parseFromInjectionInstr(unsigned inj_instr) { +void InjectionPointSteps::parseFromInjectionInstr(unsigned instr1, unsigned instr2) { // compute hops - m_ip.set_injection_instr(inj_instr); + m_ip.set_injection_instr(instr2); } } /* namespace fail */