cpn: Generic wrapper for injection point

As for the pandaboard to navigate fast to the injection
instruction we need to deliver a hop chain to the fail-client,
this commit adds a generic wrapper for a injection point.
For now we have only the two options hop chain and instruction
offset, so it is activated via a cmake ON/OFF switch.

Change-Id: Ic01a07a30ac386d4316e6d6d271baf1549db966a
This commit is contained in:
Lars Rademacher
2013-11-14 23:58:02 +01:00
parent 227f0fd7b4
commit c142818325
18 changed files with 747 additions and 4 deletions

View File

@ -4,6 +4,19 @@ set(SRCS
DatabaseCampaign.cc
)
# only compile concrete implementation of InjectionPoint
if(CONFIG_INJECTIONPOINT_HOPS)
set (SRCS ${SRCS} InjectionPointHops.cc)
else(CONFIG_INJECTIONPOINT_HOPS)
set (SRCS ${SRCS} InjectionPointSteps.cc)
endif(CONFIG_INJECTIONPOINT_HOPS)
add_library(fail-cpn ${SRCS})
# if hop-chains need to be calculated by the server, we
# the smarthopping module
if(CONFIG_INJECTIONPOINT_HOPS)
add_dependencies(fail-cpn fail-smarthopping)
endif(CONFIG_INJECTIONPOINT_HOPS)
add_dependencies(fail-cpn fail-comm)

View File

@ -4,7 +4,7 @@
#include "util/Logger.hpp"
#include "util/Database.hpp"
#include "comm/ExperimentData.hpp"
#include "InjectionPoint.hpp"
#ifndef __puma
#include <boost/thread.hpp>
@ -135,6 +135,11 @@ bool DatabaseCampaign::run_variant(Database::Variant variant) {
log_send << "Found " << experiment_count << " unfinished experiments in database. ("
<< variant.variant << "/" << variant.benchmark << ")" << std::endl;
// abstraction of injection point
// must not be initialized in loop, because hop chain calculator would loose state after loop pass
// and so for every hop chain it would have to begin calculating at trace instruction zero
ConcreteInjectionPoint ip;
sent_pilots = 0;
while ((row = mysql_fetch_row(pilots)) != 0) {
unsigned pilot_id = atoi(row[0]);
@ -147,10 +152,14 @@ bool DatabaseCampaign::run_variant(Database::Variant variant) {
pilot.set_pilot_id(pilot_id);
pilot.set_fspmethod_id(fspmethod_id);
pilot.set_variant_id(variant.id);
// ToDo: Remove this, if all experiments work with abstract API (InjectionPoint)
pilot.set_injection_instr(injection_instr);
pilot.set_variant(variant.variant);
pilot.set_benchmark(variant.benchmark);
ip.parseFromInjectionInstr(injection_instr);
ip.addToCampaignMessage(pilot);
if (row[4]) {
unsigned injection_instr_absolute = atoi(row[4]);
pilot.set_injection_instr_absolute(injection_instr_absolute);

View File

@ -0,0 +1,104 @@
#ifndef INJECTIONPOINT_HPP_
#define INJECTIONPOINT_HPP_
#include "comm/DatabaseCampaignMessage.pb.h"
#include "util/Logger.hpp"
#include "config/FailConfig.hpp"
namespace fail {
/**
* \class InjectionPointBase
*
* Interface for a generic InjectionPoint (e.g. trace instruction offset or
* hop chain) for use in the generic DatabaseCampaign. Every
* DataBaseCampaignMessage contains a concrete InjectionPoint.
*/
class InjectionPointBase {
protected:
InjectionPointMessage m_ip; // !< Protobuf message of concrete injection point, this class wraps
Logger m_log;
public:
InjectionPointBase() : m_log("InjectionPoint") {}
/**
* Parses generic representation from a injection instruction (trace offset).
* Used by server.
* @param inj_instr trace instruction offset to be parsed
*/
virtual void parseFromInjectionInstr(unsigned inj_instr) = 0;
/**
* Parses (extracts) generic representation from a DatabaseCampaignMessage.
* Used by client.
* @param pilot DatabaseCampaignMessage which contains a InjectionPoint
*/
void parseFromCampaignMessage(const DatabaseCampaignMessage &pilot) {m_ip.CopyFrom(pilot.injection_point());}
/**
* Adds generic representation to a DatabaseCampaignMessage
* @param pilot DatabaseCampaignMessage to which the generic protobuf representation will be added
*/
void addToCampaignMessage(DatabaseCampaignMessage &pilot) {pilot.mutable_injection_point()->CopyFrom(m_ip);}
/**
* Get a copy of the contained InjectionPointMessage
* @param ipm Generic InjectionPointMessage to which the content will be copied
*/
void copyInjectionPointMessage(InjectionPointMessage &ipm) {ipm.CopyFrom(m_ip);}
};
#ifdef CONFIG_INJECTIONPOINT_HOPS
#include "comm/InjectionPointHopsMessage.pb.h"
class SmartHops;
/**
* \class InjectionPointHops
*
* Concrete injection point which contains a hop chain to the target
* trace instruction.
*/
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
public:
InjectionPointHops();
virtual ~InjectionPointHops();
/**
* Parses a hop chain from a injection instruction (trace offset).
* @param inj_instr trace instruction offset to be parsed
*/
virtual void parseFromInjectionInstr(unsigned inj_instr);
};
typedef InjectionPointHops ConcreteInjectionPoint;
#else
#include "comm/InjectionPointStepsMessage.pb.h"
/**
* \class InjectionPointSteps
*
* Concrete injection point which contains a trace instruction offset.
*/
class InjectionPointSteps : public InjectionPointBase {
public:
virtual ~InjectionPointSteps() {}
/**
* 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
*/
virtual void parseFromInjectionInstr(unsigned inj_instr);
};
typedef InjectionPointSteps ConcreteInjectionPoint;
#endif
} /* namespace fail */
#endif /* INJECTIONPOINT_HPP_ */

View File

@ -0,0 +1,40 @@
#include "InjectionPoint.hpp"
#include "util/smarthops/SmartHops.hpp"
namespace fail {
InjectionPointHops::InjectionPointHops() : InjectionPointBase(), 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;
exit(-1);
}else{
m_sa->init((const char*)elfpath);
}
}
InjectionPointHops::~InjectionPointHops() {
delete m_sa;
}
void InjectionPointHops::parseFromInjectionInstr(unsigned inj_instr) {
// 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);
}
if (!m_sa->calculateFollowingHop(m_ip, inj_instr)) {
m_log << "FATAL ERROR: Trace does not contain enough instructions (" << inj_instr << ")" << std::endl;
exit(-1);
}
m_curr_inst = inj_instr;
}
} /* namespace fail */

View File

@ -0,0 +1,10 @@
#include "InjectionPoint.hpp"
namespace fail {
void InjectionPointSteps::parseFromInjectionInstr(unsigned inj_instr) {
// compute hops
m_ip.set_injection_instr(inj_instr);
}
} /* namespace fail */