From b139c7105342f3288ffdb69163222950497dd1ed Mon Sep 17 00:00:00 2001 From: chb Date: Tue, 14 Aug 2012 09:32:07 +0000 Subject: [PATCH] ecos_kernel_test: experiment calculates timeout in STEP 2 git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1492 8c4709b5-6ec9-48aa-a5cd-a96041d1645a --- src/experiments/ecos_kernel_test/campaign.cc | 15 +++--- src/experiments/ecos_kernel_test/campaign.hpp | 4 +- .../ecos_kernel_test/experiment.cc | 51 ++++++++++++++----- 3 files changed, 48 insertions(+), 22 deletions(-) diff --git a/src/experiments/ecos_kernel_test/campaign.cc b/src/experiments/ecos_kernel_test/campaign.cc index ff327875..4a9240b2 100644 --- a/src/experiments/ecos_kernel_test/campaign.cc +++ b/src/experiments/ecos_kernel_test/campaign.cc @@ -46,19 +46,19 @@ bool EcosKernelTestCampaign::readMemoryMap(fail::MemoryMap &mm, char const * con return (count > 0); } -bool EcosKernelTestCampaign::writeTraceInfo(unsigned instr_counter, unsigned lowest_addr, unsigned highest_addr) { +bool EcosKernelTestCampaign::writeTraceInfo(unsigned instr_counter, unsigned timeout, unsigned lowest_addr, unsigned highest_addr) { ofstream ti(traceinfo_name, ios::out | ios::app); if (!ti.is_open()) { cout << "failed to open " << traceinfo_name << endl; return false; } - ti << instr_counter << endl << lowest_addr << endl << highest_addr << endl; + ti << instr_counter << endl << timeout << endl << lowest_addr << endl << highest_addr << endl; ti.flush(); ti.close(); return true; } -bool EcosKernelTestCampaign::readTraceInfo(unsigned &instr_counter, unsigned &lowest_addr, unsigned &highest_addr) { +bool EcosKernelTestCampaign::readTraceInfo(unsigned &instr_counter, unsigned &timeout, unsigned &lowest_addr, unsigned &highest_addr) { ifstream file(traceinfo_name); if (!file.is_open()) { cout << "failed to open " << traceinfo_name << endl; @@ -75,9 +75,12 @@ bool EcosKernelTestCampaign::readTraceInfo(unsigned &instr_counter, unsigned &lo ss >> instr_counter; break; case 1: - ss >> lowest_addr; + ss >> timeout; break; case 2: + ss >> lowest_addr; + break; + case 3: ss >> highest_addr; break; } @@ -123,8 +126,8 @@ bool EcosKernelTestCampaign::run() ProtoIStream ps(&tracef); // read trace info - unsigned instr_counter, lowest_addr, highest_addr; - EcosKernelTestCampaign::readTraceInfo(instr_counter, lowest_addr, highest_addr); + unsigned instr_counter, estimated_timeout, lowest_addr, highest_addr; + EcosKernelTestCampaign::readTraceInfo(instr_counter, estimated_timeout, lowest_addr, highest_addr); // a map of addresses of ECC protected objects MemoryMap mm; diff --git a/src/experiments/ecos_kernel_test/campaign.hpp b/src/experiments/ecos_kernel_test/campaign.hpp index 4af2abe2..8797088b 100644 --- a/src/experiments/ecos_kernel_test/campaign.hpp +++ b/src/experiments/ecos_kernel_test/campaign.hpp @@ -15,7 +15,7 @@ class EcosKernelTestCampaign : public fail::Campaign { public: virtual bool run(); static bool readMemoryMap(fail::MemoryMap &mm, char const * const filename); - static bool writeTraceInfo(unsigned instr_counter, unsigned lowest_addr, unsigned highest_addr); - static bool readTraceInfo(unsigned &instr_counter, unsigned &lowest_addr, unsigned &highest_addr); + static bool writeTraceInfo(unsigned instr_counter, unsigned timeout, unsigned lowest_addr, unsigned highest_addr); + static bool readTraceInfo(unsigned &instr_counter, unsigned &timeout, unsigned &lowest_addr, unsigned &highest_addr); }; diff --git a/src/experiments/ecos_kernel_test/experiment.cc b/src/experiments/ecos_kernel_test/experiment.cc index 7b790152..7f9228f4 100644 --- a/src/experiments/ecos_kernel_test/experiment.cc +++ b/src/experiments/ecos_kernel_test/experiment.cc @@ -98,6 +98,7 @@ bool EcosKernelTestExperiment::retrieveGuestAddresses() { } assert(number_of_guest_events > 0); //log << "Breakpoint at 'ECOS_FUNC_FINISH' reached: created memory map (" << number_of_guest_events << " entries)" << endl; + //TODO: check if ECOS_FUNC_FINISH was reached!!! log << "Record timeout reached: created memory map (" << number_of_guest_events << " entries)" << endl; delete str; @@ -177,6 +178,14 @@ bool EcosKernelTestExperiment::performTrace() { simulator.addListener(&ev_count); unsigned instr_counter = 0; + // on the way, count elapsed time + TimerListener time_step(10000); //TODO: granularity? + //elapsed_time.setCounter(0xFFFFFFFFU); // not working for TimerListener + simulator.addListener(&time_step); + unsigned elapsed_time = 1; // always run 1 step + // just increase elapsed_time counter by 1, which serves as time for ECC recovery algorithm + ++elapsed_time; // (this is a rough guess ... TODO) + // on the way, record lowest and highest memory address accessed MemAccessListener ev_mem(ANY_ADDR, MemAccessEvent::MEM_READWRITE); simulator.addListener(&ev_mem); @@ -187,9 +196,19 @@ bool EcosKernelTestExperiment::performTrace() { BaseListener* ev = simulator.resume(); while(ev != &bp) { if(ev == &ev_count) { - ++instr_counter; + if(instr_counter++ == 0xFFFFFFFFU) { + log << "ERROR: instr_counter overflowed" << endl; + return false; + } simulator.addListener(&ev_count); } + else if(ev == &time_step) { + if(elapsed_time++ == 0xFFFFFFFFU) { + log << "ERROR: elapsed_time overflowed" << endl; + return false; + } + simulator.addListener(&time_step); + } else if(ev == &ev_mem) { unsigned trigger_addr = ev_mem.getTriggerAddress(); if( (lowest_addr == 0) && (highest_addr == 0) ) { @@ -206,11 +225,19 @@ bool EcosKernelTestExperiment::performTrace() { ev = simulator.resume(); } + unsigned long long estimated_timeout_overflow_check = ((unsigned long long)elapsed_time) * time_step.getTimeout(); + if(estimated_timeout_overflow_check > 0xFFFFFFFFU) { + log << "Timeout estimation overflowed" << endl; + return false; + } + unsigned estimated_timeout = (unsigned)estimated_timeout_overflow_check; + log << dec << "tracing finished after " << instr_counter << " instructions" << endl; log << hex << "all memory accesses within [ 0x" << lowest_addr << " , 0x" << highest_addr << " ]" << endl; + log << dec << "elapsed time: " << estimated_timeout << " [TimerListener units]" << endl; // save these values for experiment STEP 3 - EcosKernelTestCampaign::writeTraceInfo(instr_counter, lowest_addr, highest_addr); + EcosKernelTestCampaign::writeTraceInfo(instr_counter, estimated_timeout, lowest_addr, highest_addr); simulator.removeFlow(&tp); @@ -233,8 +260,8 @@ bool EcosKernelTestExperiment::faultInjection() { log << "STEP 3: The actual experiment." << endl; // read trace info - unsigned instr_counter, lowest_addr, highest_addr; - EcosKernelTestCampaign::readTraceInfo(instr_counter, lowest_addr, highest_addr); + unsigned instr_counter, estimated_timeout, lowest_addr, highest_addr; + EcosKernelTestCampaign::readTraceInfo(instr_counter, estimated_timeout, lowest_addr, highest_addr); BPSingleListener bp; @@ -359,18 +386,14 @@ bool EcosKernelTestExperiment::faultInjection() { simulator.addListener(&ev_mem_high); // timeout (e.g., stuck in a HLT instruction) - // 10000us = 500000 instructions - TimerListener ev_timeout(500000); + TimerListener ev_timeout(estimated_timeout); simulator.addListener(&ev_timeout); - //TODO: if ev_timeout would depend on instr_counter, ev_end would not be needed! - // --> (instr_counter + ECOS_RECOVERYINSTR) * factor? // remaining instructions until "normal" ending // number of instructions that are executed additionally for error corrections - enum { ECOS_RECOVERYINSTR = 0x2000 }; // (this is a rough guess ... TODO) - BPSingleListener ev_end(ANY_ADDR); - ev_end.setCounter(instr_counter + ECOS_RECOVERYINSTR - instr_offset); - simulator.addListener(&ev_end); + //BPSingleListener ev_end(ANY_ADDR); + //ev_end.setCounter(instr_counter - instr_offset + ECOS_RECOVERYINSTR); + //simulator.addListener(&ev_end); // eCos' test output function, which will show if the test PASSed or FAILed BPSingleListener func_test_output(ECOS_FUNC_TEST_OUTPUT); @@ -429,7 +452,7 @@ bool EcosKernelTestExperiment::faultInjection() { result->set_error_corrected(error_corrected); // record ecos_test_result - if (ecos_test_passed && !ecos_test_failed) { + if ( (ecos_test_passed == true) && (ecos_test_failed == false) ) { result->set_ecos_test_result(result->PASS); } else { result->set_ecos_test_result(result->FAIL); @@ -439,7 +462,7 @@ bool EcosKernelTestExperiment::faultInjection() { // do we reach finish? log << "experiment finished ordinarily" << endl; result->set_resulttype(result->FINISHED); - } else if (ev == &ev_timeout || ev == &ev_end) { + } else if (ev == &ev_timeout /*|| ev == &ev_end*/) { log << "Result TIMEOUT" << endl; result->set_resulttype(result->TIMEOUT); } else if (ev == &ev_below_text || ev == &ev_beyond_text) {