From ad558abeb6209353947f05a5fc5e38305e3f7145 Mon Sep 17 00:00:00 2001 From: Michael Lenz Date: Wed, 10 Feb 2016 12:12:24 +0100 Subject: [PATCH] DatabaseCampaign/-Experiment: add burst faults This change introduces the ability to inject burst faults to the DatabaseCampaign/-Experiment and thus to all derived campaigns/experiments. Change-Id: I491d021ed3953562bd7c908e9de50d448bc8ef33 --- .../comm/DatabaseCampaignMessage.proto.in | 7 ++++-- src/core/cpn/DatabaseCampaign.cc | 14 ++++++++++- src/core/cpn/DatabaseCampaign.hpp | 6 ++++- src/core/efw/DatabaseExperiment.cc | 25 ++++++++++++++++--- src/core/efw/DatabaseExperiment.hpp | 1 + 5 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/core/comm/DatabaseCampaignMessage.proto.in b/src/core/comm/DatabaseCampaignMessage.proto.in index 9e4c4dbc..3389b223 100644 --- a/src/core/comm/DatabaseCampaignMessage.proto.in +++ b/src/core/comm/DatabaseCampaignMessage.proto.in @@ -19,9 +19,12 @@ message DatabaseCampaignMessage { required string benchmark = 9 [(sql_ignore) = true]; required InjectionPointMessage injection_point = 10 [(sql_ignore) = true]; + + required bool inject_bursts = 11 [default = false]; } message DatabaseExperimentMessage { - required uint32 bitoffset = 1 [(sql_primary_key) = true]; - required uint32 original_value = 2; + required uint32 bitoffset = 1 [(sql_primary_key) = true]; + required uint32 original_value = 2; + required uint32 injection_width = 3; } diff --git a/src/core/cpn/DatabaseCampaign.cc b/src/core/cpn/DatabaseCampaign.cc index 1d445df1..c093e70d 100644 --- a/src/core/cpn/DatabaseCampaign.cc +++ b/src/core/cpn/DatabaseCampaign.cc @@ -46,6 +46,10 @@ bool DatabaseCampaign::run() { cmd.addOption("p", "prune-method", Arg::Required, "-p/--prune-method \tWhich import method(s) to use (default: \"%\"; use % and _ as wildcard characters)"); + CommandLine::option_handle BURST = + cmd.addOption("","inject-bursts", Arg::None, + "--inject-bursts \tinject burst faults (default: single bitflips)"); + if (!cmd.parse()) { log_send << "Error parsing arguments." << std::endl; exit(-1); @@ -91,6 +95,14 @@ bool DatabaseCampaign::run() { benchmarks.push_back("%"); } + if (cmd[BURST]) { + m_inject_bursts = true; + log_send << "fault model: burst" << std::endl; + } else { + m_inject_bursts = false; + log_send << "fault model: single-bit flip" << std::endl; + } + if (cmd[PRUNER]) { m_fspmethod = std::string(cmd[PRUNER].first()->arg); } else { @@ -225,7 +237,7 @@ bool DatabaseCampaign::run_variant(Database::Variant variant) { } pilot.set_data_address(data_address); pilot.set_data_width(data_width); - + pilot.set_inject_bursts(m_inject_bursts); this->cb_send_pilot(pilot); diff --git a/src/core/cpn/DatabaseCampaign.hpp b/src/core/cpn/DatabaseCampaign.hpp index 97bafc30..6546d722 100644 --- a/src/core/cpn/DatabaseCampaign.hpp +++ b/src/core/cpn/DatabaseCampaign.hpp @@ -39,6 +39,8 @@ class DatabaseCampaign : public Campaign { id_map completed_pilots; // !< map: Pilot IDs -> result count #endif + bool m_inject_bursts; // !< inject burst faults? + public: DatabaseCampaign() {}; @@ -61,7 +63,9 @@ public: * there are less result rows, the pilot will be again sent to the clients * @return \c exptected number of results */ - virtual int expected_number_of_results(std::string variant, std::string benchmark) { return 8;} + virtual int expected_number_of_results(std::string variant, std::string benchmark) { + return (m_inject_bursts ? 1 : 8); + } /** * Callback function that can be used to add command line options diff --git a/src/core/efw/DatabaseExperiment.cc b/src/core/efw/DatabaseExperiment.cc index 7cc67d30..7a2bf6d4 100644 --- a/src/core/efw/DatabaseExperiment.cc +++ b/src/core/efw/DatabaseExperiment.cc @@ -27,6 +27,18 @@ DatabaseExperiment::~DatabaseExperiment() { delete this->m_jc; } +unsigned DatabaseExperiment::injectBurst(address_t data_address) { + unsigned value, burst_value; + value = m_mm.getByte(data_address); + burst_value = value ^ 0xff; + m_mm.setByte(data_address, burst_value); + + m_log << "INJECTED BURST at: 0x" << hex<< setw(2) << setfill('0') << data_address + << " value: 0x" << setw(2) << setfill('0') << value << " -> 0x" + << setw(2) << setfill('0') << burst_value << endl; + return value; +} + unsigned DatabaseExperiment::injectBitFlip(address_t data_address, unsigned bitpos){ unsigned int value, injectedval; @@ -92,8 +104,9 @@ bool DatabaseExperiment::run() unsigned injection_instr = fsppilot->injection_instr(); address_t data_address = fsppilot->data_address(); unsigned width = fsppilot->data_width(); + unsigned injection_width = fsppilot->inject_bursts() ? 8 : 1; - for (unsigned bit_offset = 0; bit_offset < width * 8; ++bit_offset) { + for (unsigned bit_offset = 0; bit_offset < width * 8; bit_offset += injection_width) { // 8 results in one job Message *outer_result = cb_new_result(param); m_current_result = outer_result; @@ -157,8 +170,14 @@ bool DatabaseExperiment::run() simulator.clearListeners(); - /// INJECT BITFLIP: - result->set_original_value(injectBitFlip(data_address, bit_offset)); + if (fsppilot->inject_bursts()) { + /// INJECT BURST: + result->set_original_value(injectBurst((data_address+bit_offset/8))); + } else { + /// INJECT BITFLIP: + result->set_original_value(injectBitFlip(data_address, bit_offset)); + } + result->set_injection_width(injection_width); if (!this->cb_before_resume()) { continue; // Continue to next experiment diff --git a/src/core/efw/DatabaseExperiment.hpp b/src/core/efw/DatabaseExperiment.hpp index f60ddf9a..71fae098 100644 --- a/src/core/efw/DatabaseExperiment.hpp +++ b/src/core/efw/DatabaseExperiment.hpp @@ -15,6 +15,7 @@ class DatabaseExperiment : public fail::ExperimentFlow { fail::JobClient *m_jc; unsigned injectBitFlip(fail::address_t data_address, unsigned bitpos); + unsigned injectBurst(fail::address_t data_address); /** The current experiment data as returned by the job client. This