remove deprecated stuff
Change-Id: Ifc25d216bbf782416159ceb0c366a080d2c8c428
This commit is contained in:
@ -1,29 +0,0 @@
|
||||
#ifndef __FIRETIMER_AH__
|
||||
#define __FIRETIMER_AH__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// FIXME: This seems deprecated...?!
|
||||
|
||||
aspect fireTimer {
|
||||
|
||||
advice "bx_pc_system_c" : slice class {
|
||||
public:
|
||||
// TODO: Log-level?
|
||||
void fireTimer(Bit32u timerNum){
|
||||
if(timerNum <= numTimers){
|
||||
if(!timer[timerNum].active){
|
||||
std::cout << "[FAIL] WARNING: The selected timer is actually NOT active!" << std::endl;
|
||||
}
|
||||
currCountdownPeriod = Bit64u(1);
|
||||
timer[timerNum].timeToFire = Bit64u(currCountdownPeriod) + ticksTotal;
|
||||
std::cout << "[FAIL] Timer " << timerNum <<" will fire now!" << std::endl;
|
||||
}else{
|
||||
std::cout << "[FAIL] There are actually only " << numTimers <<" allocated!" << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif // __FIRETIMER_AH__
|
||||
@ -1,35 +0,0 @@
|
||||
#ifndef __JUMP_TO_PREVIOUS_CTX_AH__
|
||||
#define __JUMP_TO_PREVIOUS_CTX_AH__
|
||||
|
||||
#include "config/FailConfig.hpp"
|
||||
|
||||
// FIXME: What's the purpose of this file/code? Deprecated?
|
||||
|
||||
#if 0
|
||||
// #if defined(CONFIG_SR_RESTORE) || defined(CONFIG_SR_REBOOT)
|
||||
|
||||
#include "bochs.h"
|
||||
#include "../SALInst.hpp"
|
||||
|
||||
aspect jumpToPreviousCtx
|
||||
{
|
||||
pointcut end_reset_handler() = "void bx_gui_c::reset_handler(...)";
|
||||
//|| "int bxmain()";
|
||||
|
||||
|
||||
advice execution (end_reset_handler()) : after ()
|
||||
{
|
||||
|
||||
if (fail::restore_bochs_request || fail::reboot_bochs_request )
|
||||
{
|
||||
fail::restore_bochs_request = false;
|
||||
fail::reboot_bochs_request = false;
|
||||
fail::simulator.toPreviousCtx();
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CONFIG_SR_RESTORE || CONFIG_SR_REBOOT
|
||||
|
||||
#endif // __JUMP_TO_PREVIOUS_CTX_AH__
|
||||
@ -1,102 +0,0 @@
|
||||
#ifndef __MEM_ACCESS_BIT_FLIP_AH__
|
||||
#define __MEM_ACCESS_BIT_FLIP_AH__
|
||||
|
||||
#include "config/FailConfig.hpp"
|
||||
|
||||
#ifdef CONFIG_FI_MEM_ACCESS_BITFLIP
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
|
||||
#include "bochs.h"
|
||||
#include "../../controller/EventList.hpp"
|
||||
#include "../../controller/Event.hpp"
|
||||
|
||||
// FIXME: This is deprecated stuff. Delete this file.
|
||||
|
||||
using namespace std;
|
||||
|
||||
// FIXME this code doesn't make any sense for the read_virtual_% functions
|
||||
// (the fault would need to be injected into their *return* value)
|
||||
|
||||
aspect MemAccessBitFlip
|
||||
{
|
||||
pointcut injection_methods()
|
||||
= "% ...::bx_cpu_c::read_virtual_%(...)" || // -> access32/64.cc
|
||||
/*
|
||||
"% ...::bx_cpu_c::read_RMW_virtual_%(...)" || // -> access32.cc
|
||||
"% ...::bx_cpu_c::system_read_%(...)" || // -> access.cc
|
||||
"% ...::bx_cpu_c::v2h_read_byte(...)" || // -> access.cc
|
||||
*/
|
||||
"% ...::bx_cpu_c::write_virtual_%(...)"; // -> access32/64.cc
|
||||
/*
|
||||
"% ...::bx_cpu_c::write_RMW_virtual_%(...)" || // -> access32.cc
|
||||
"% ...::bx_cpu_c::write_new_stack_%(...)" || // -> access32/64.cc
|
||||
"% ...::bx_cpu_c::system_write_%(...)" || // -> access.cc
|
||||
"% ...::bx_cpu_c::v2h_write_byte(...)"; // -> access.cc
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// Injects a bitflip each time the guest system requests to write/read
|
||||
// data to/from RAM at the (hardcoded) addresses defined above:
|
||||
//
|
||||
// Event source: "memory write/read access"
|
||||
//
|
||||
advice execution (injection_methods()) : before ()
|
||||
{
|
||||
for(size_t i = 0; i < fi::evbuf.getEventCount(); i++) // check for active events
|
||||
{
|
||||
fi::SimpleBitFlip* pEv = dynamic_cast<fi::SimpleBitFlip*>(fi::evbuf.getEvent(i)); // FIXME: Performance verbessern
|
||||
if(pEv && *(tjp->arg<1>())/*typed!*/ == pEv->getAddress())
|
||||
{
|
||||
cout << " " << tjp->signature() << endl;
|
||||
|
||||
// Get a pointer to the data that should be written to RAM
|
||||
// *before* it is actually written:
|
||||
Bit32u* pData = (Bit32u*)(tjp->arg(JoinPoint::ARGS-1));
|
||||
|
||||
// Flip bit at position pEv->getBitPos():
|
||||
char* ptr = (char*)pData; // For simplification we're just looking at the
|
||||
// first byte of the data
|
||||
ptr[0] = (ptr[0]) ^ (pEv->getMask() << pEv->getBitPos());
|
||||
|
||||
cout << " >>> Bit flipped at index " << pEv->getBitPos()
|
||||
<< " at address 0x" << hex << (*(tjp->arg<1>())) << "!" << endl;
|
||||
fi::evbuf.fireEvent(pEv);
|
||||
// Continue... (maybe more events to process)
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
//
|
||||
// Shows the mapping of a virtual address (within eCos) to a *host* address:
|
||||
//
|
||||
if(g_fEnableInjection) // event fired?
|
||||
{
|
||||
g_fEnableInjection = false;
|
||||
const unsigned SEGMENT_SELECTOR_IDX = 2; // always the code segment (seg-base-addr should be zero)
|
||||
const bx_address logicalAddr = MEM_ADDR_TO_INJECT; // offset within the segment ("local eCos address")
|
||||
|
||||
// Get the linear address:
|
||||
Bit32u linearAddr = pThis->get_laddr32(SEGMENT_SELECTOR_IDX/ *seg* /, logicalAddr/ *offset* /);
|
||||
// Map the linear address to the physical address:
|
||||
bx_phy_address physicalAddr;
|
||||
bx_bool fValid = pThis->dbg_xlate_linear2phy(linearAddr, (bx_phy_address*)&physicalAddr);
|
||||
// Determine the *host* address of the physical address:
|
||||
Bit8u* hostAddr = BX_MEM(0)->getHostMemAddr(pThis, physicalAddr, BX_READ);
|
||||
// Now, hostAddr contains the "final" address where we are allowed to inject errors:
|
||||
*(unsigned*)hostAddr = BAD_VALUE; // inject error
|
||||
if(!fValid)
|
||||
printf("[Error]: Could not map logical address to host address.\n");
|
||||
else
|
||||
printf("[Info]: Error injected at logical addr %p (host addr %p).\n", logicalAddr, hostAddr);
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
#endif // CONFIG_FI_MEM_ACCESS_BITFLIP
|
||||
|
||||
#endif // __MEM_ACCESS_BIT_FLIP_AH__
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "DataRetrievalExperiment.hpp"
|
||||
#include "../SAL/SALInst.hpp"
|
||||
#include "../controller/Event.hpp"
|
||||
#include "ExperimentDataExample/FaultCoverageExperiment.pb.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
#define MEMTEST86_BREAKPOINT 0x4EDC
|
||||
|
||||
bool DataRetrievalExperiment::run()
|
||||
{
|
||||
cout << "[getExperimentDataExperiment] Experiment start." << endl;
|
||||
|
||||
// Breakpoint address for Memtest86:
|
||||
BPSingleEvent mainbp(MEMTEST86_BREAKPOINT);
|
||||
simulator.addEventAndWait(&mainbp);
|
||||
cout << "[getExperimentDataExperiment] Breakpoint reached." << endl;
|
||||
|
||||
FaultCoverageExperimentData* test = NULL;
|
||||
cout << "[getExperimentDataExperiment] Getting ExperimentData (FaultCoverageExperiment)..." << endl;
|
||||
test = simulator.getExperimentData<FaultCoverageExperimentData>();
|
||||
cout << "[getExperimentDataExperiment] Content of ExperimentData (FaultCoverageExperiment):" << endl;
|
||||
|
||||
if (test->has_data_name())
|
||||
cout << "Name: "<< test->data_name() << endl;
|
||||
// m_instrptr1 augeben
|
||||
cout << "m_instrptr1: " << hex << test->m_instrptr1() << endl;
|
||||
// m_instrptr2 augeben
|
||||
cout << "m_instrptr2: " << hex << test->m_instrptr2() << endl;
|
||||
|
||||
simulator.clearEvents(this);
|
||||
return true; // experiment successful
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
#ifndef __DATA_RETRIEVAL_EXPERIMENT_HPP__
|
||||
#define __DATA_RETRIEVAL_EXPERIMENT_HPP__
|
||||
|
||||
#include "../controller/ExperimentFlow.hpp"
|
||||
|
||||
class DataRetrievalExperiment : public fail::ExperimentFlow
|
||||
{
|
||||
public:
|
||||
DataRetrievalExperiment() { }
|
||||
|
||||
bool run();
|
||||
};
|
||||
|
||||
#endif // __DATA_RETRIEVAL_EXPERIMENT_HPP__
|
||||
@ -1,19 +0,0 @@
|
||||
## Setup desired protobuf descriptions HERE ##
|
||||
set(MY_PROTOS
|
||||
FaultCoverageExperiment.proto
|
||||
)
|
||||
|
||||
set(SRCS
|
||||
example.cc
|
||||
)
|
||||
|
||||
#### PROTOBUFS ####
|
||||
find_package(Protobuf REQUIRED)
|
||||
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
||||
include_directories(${CMAKE_CURRNET_BINARY_DIR})
|
||||
|
||||
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${MY_PROTOS} )
|
||||
|
||||
## Build library
|
||||
add_library(fcexperimentmessage ${PROTO_SRCS} ${SRCS} )
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
message FaultCoverageExperimentData{
|
||||
|
||||
optional string data_name = 1;
|
||||
required int64 m_InstrPtr1 = 2;
|
||||
required int64 m_InstrPtr2 = 3;
|
||||
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
cd $(dirname $0)
|
||||
g++ ../../controller/JobServer.cc ../../controller/ExperimentDataQueue.cc example.cc FaultCoverageExperiment.pb.cc -o ./ExperimentData_example -l protobuf -pthread
|
||||
@ -1,63 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include "controller/ExperimentData.hpp"
|
||||
#include "controller/ExperimentDataQueue.hpp"
|
||||
#include "jobserver/JobServer.hpp"
|
||||
#include "FaultCoverageExperiment.pb.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// FIXME: Translation missing.
|
||||
|
||||
ExperimentDataQueue exDaQu;
|
||||
ExperimentData* readFromQueue;
|
||||
|
||||
// Daten in Struktur schreiben und in Datei speichern
|
||||
ofstream fileWrite;
|
||||
fileWrite.open("test.txt");
|
||||
|
||||
FaultCoverageExperimentData faultCovExWrite;
|
||||
// Namen setzen
|
||||
faultCovExWrite.set_data_name("Testfall 42");
|
||||
// Instruktionpointer 1
|
||||
faultCovExWrite.set_m_instrptr1(0x4711);
|
||||
// Instruktionpointer 2
|
||||
faultCovExWrite.set_m_instrptr2(0x1122);
|
||||
|
||||
// In ExperimentData verpacken
|
||||
ExperimentData exDaWrite(&faultCovExWrite);
|
||||
// In Queue einbinden
|
||||
exDaQu.addData(&exDaWrite);
|
||||
// Aus Queue holen
|
||||
if (exDaQu.size() != 0)
|
||||
readFromQueue = exDaQu.getData();
|
||||
|
||||
// Serialisierung ueber Wrapper-Methode in ExperimentData
|
||||
readFromQueue->serialize(&fileWrite);
|
||||
// cout << "Ausgabe: " << out << endl;
|
||||
fileWrite.close();
|
||||
|
||||
//---------------------------------------------------------------
|
||||
|
||||
// Daten aus Datei lesen und in Struktur schreiben
|
||||
ifstream fileRead;
|
||||
fileRead.open("test.txt");
|
||||
FaultCoverageExperimentData faultCovExRead;
|
||||
ExperimentData exDaRead(&faultCovExRead);
|
||||
exDaRead.unserialize( &fileRead);
|
||||
|
||||
// Wenn Name, dann ausgeben
|
||||
if(faultCovExRead.has_data_name()){
|
||||
cout << "Name: "<< faultCovExRead.data_name() << endl;
|
||||
}
|
||||
// m_instrptr1 augeben
|
||||
cout << "m_instrptr1: " << faultCovExRead.m_instrptr1() << endl;
|
||||
// m_instrptr2 augeben
|
||||
cout << "m_instrptr2: " << faultCovExRead.m_instrptr2() << endl;
|
||||
fileRead.close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,76 +0,0 @@
|
||||
#ifndef __JUMP_AND_RUN_EXPERIMENT_HPP__
|
||||
#define __JUMP_AND_RUN_EXPERIMENT_HPP__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "../controller/ExperimentFlow.hpp"
|
||||
#include "../SAL/SALInst.hpp"
|
||||
#include "../SAL/bochs/BochsRegister.hpp"
|
||||
#include "config/FailConfig.hpp"
|
||||
|
||||
// Check if aspect dependencies are satisfied:
|
||||
#if !defined(CONFIG_EVENT_CPULOOP) || !defined(CONFIG_EVENT_JUMP)
|
||||
#error Breakpoint- and jump-events needed! Enable aspects first (see FailConfig.hpp)!
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
class JumpAndRunExperiment : public fail::ExperimentFlow {
|
||||
public:
|
||||
bool run()
|
||||
{
|
||||
/************************************
|
||||
* Description of experiment flow. *
|
||||
************************************/
|
||||
// Wait for function entry adresss:
|
||||
cout << "[JumpAndRunExperiment] Setting up experiment. Allowing to "
|
||||
<< "start now." << endl;
|
||||
BPEvent mainFuncEntry(0x3c1f);
|
||||
simulator.addEvent(&mainFuncEntry);
|
||||
if (&mainFuncEntry != simulator.waitAny()) {
|
||||
cerr << "[JumpAndRunExperiment] Now, we are completely lost! "
|
||||
<< "It's time to cry! :-(" << endl;
|
||||
simulator.clearEvents(this);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
cout << "[JumpAndRunExperiment] Entry of main function reached! "
|
||||
<< " Let's see who's jumping around here..." << endl;
|
||||
|
||||
const unsigned COUNTER = 20000;
|
||||
unsigned i = 0;
|
||||
BxFlagsReg* pFlags = dynamic_cast<BxFlagsReg*>(simulator.
|
||||
getRegisterManager().getSetOfType(RT_ST).snatch());
|
||||
assert(pFlags != NULL && "FATAL ERROR: NULL ptr not expected!");
|
||||
JumpEvent ev;
|
||||
// Catch the next "counter" jumps:
|
||||
while (++i <= COUNTER) {
|
||||
ev.setWatchInstructionPointer(ANY_INSTR);
|
||||
simulator.addEvent(&ev);
|
||||
if (simulator.waitAny() != &ev) {
|
||||
cerr << "[JumpAndRunExperiment] Damn! Something went "
|
||||
<< "terribly wrong! Who added that event?! :-(" << endl;
|
||||
simulator.clearEvents(this);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
cout << "[JumpAndRunExperiment] Jump detected. Instruction: "
|
||||
<< "0x" hex << ev.getTriggerInstructionPointer()
|
||||
<< " -- FLAGS [CF, ZF, OF, PF, SF] = ["
|
||||
<< pFlags->getCarryFlag() << ", "
|
||||
<< pFlags->getZeroFlag() << ", "
|
||||
<< pFlags->getOverflowFlag() << ", "
|
||||
<< pFlags->getParityFlag() << ", "
|
||||
<< pFlags->getSignFlag() << "]." << endl;
|
||||
}
|
||||
cout << "[JumpAndRunExperiment] " << dec << counter
|
||||
<< " jump(s) detected -- enough for today...exiting! :-)"
|
||||
<< endl;
|
||||
|
||||
simulator.clearEvents(this);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __JUMP_AND_RUN_EXPERIMENT_HPP__
|
||||
@ -1,71 +0,0 @@
|
||||
#ifndef __MEM_WRITE_EXPERIMENT_HPP__
|
||||
#define __MEM_WRITE_EXPERIMENT_HPP__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "../controller/ExperimentFlow.hpp"
|
||||
#include "../SAL/SALInst.hpp"
|
||||
#include "config/FailConfig.hpp"
|
||||
|
||||
// Check aspect dependencies:
|
||||
#if !defined(CONFIG_EVENT_CPULOOP) || !defined(CONFIG_EVENT_MEMACCESS) || !defined(CONFIG_SR_SAVE) || !defined(CONFIG_FI_MEM_ACCESS_BITFLIP)
|
||||
#error Event dependecies not satisfied! Enabled needed aspects in FailConfig.hpp!
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
class MemWriteExperiment : public fail::ExperimentFlow {
|
||||
public:
|
||||
bool run() // Example experiment (defines "what we wanna do")
|
||||
{
|
||||
/************************************
|
||||
* Description of experiment flow. *
|
||||
************************************/
|
||||
|
||||
// 1. Add some events (set up the experiment):
|
||||
cout << "[MemWriteExperiment] Setting up experiment. Allowing to"
|
||||
<< " start now." << endl;
|
||||
MemWriteEvent mem1(0x000904F0), mem2(0x02ff0916), mem3(0x0050C8E8);
|
||||
BPEvent breakpt(0x4ae6);
|
||||
simulator.addEvent(&mem1);
|
||||
simulator.addEvent(&mem2);
|
||||
simulator.addEvent(&mem3);
|
||||
simulator.addEvent(&breakpt);
|
||||
|
||||
// 2. Wait for event condition "(id1 && id2) || id3" to become true:
|
||||
cout << "[MemWriteExperiment] Waiting for condition (1) (\"(id1 &&"
|
||||
<< " id2) || id3\") to become true..." << endl;
|
||||
bool f1 = false, f2 = false, f3 = false, f4 = false;
|
||||
while (!(f1 || f2 || f3 || f4)) {
|
||||
BPEvent* pev = simulator.waitAny();
|
||||
cout << "[MemWriteExperiment] Received event id=" << id
|
||||
<< "." << endl;
|
||||
if(pev == &mem4)
|
||||
f4 = true;
|
||||
if(pev == &mem3)
|
||||
f3 = true;
|
||||
if(pev == &mem2)
|
||||
f2 = true;
|
||||
if(pev == &mem1)
|
||||
f1 = true;
|
||||
}
|
||||
cout << "[MemWriteExperiment] Condition (1) satisfied! Ready to "
|
||||
<< "add next event..." << endl;
|
||||
// 3. Add a new event now:
|
||||
cout << "[MemWriteExperiment] Adding new Event..."; cout.flush();
|
||||
simulator.clearEvents(); // remove residual events in the buffer
|
||||
// (we're just interested in the new event)
|
||||
simulator.save("./bochs_save_point");
|
||||
cout << "done!" << endl;
|
||||
|
||||
// 4. Continue simulation (waitAny) and inject bitflip:
|
||||
// ...
|
||||
|
||||
simulator.clearEvents(this);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __MEM_WRITE_EXPERIMENT_HPP__
|
||||
|
||||
@ -1,60 +0,0 @@
|
||||
#ifndef __MY_EXPERIMENT_HPP__
|
||||
#define __MY_EXPERIMENT_HPP__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "../controller/ExperimentFlow.hpp"
|
||||
#include "../SAL/SALInst.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
class MyExperiment : public fail::ExperimentFlow {
|
||||
public:
|
||||
bool run() // Example experiment (defines "what we wanna do")
|
||||
{
|
||||
/************************************
|
||||
* Description of experiment flow. *
|
||||
************************************/
|
||||
|
||||
// 1. Add some events (set up the experiment):
|
||||
cout << "[MyExperiment] Setting up experiment. Allowing to start"
|
||||
<< " now." << endl;
|
||||
BPEvent ev1(0x8048A00), ev2(0x8048F01), ev3(0x3c1f);
|
||||
simulator.addEvent(&ev1);
|
||||
simulator.addEvent(&ev2);
|
||||
simulator.addEvent(&ev3);
|
||||
|
||||
// 2. Wait for event condition "(id1 && id2) || id3" to become true:
|
||||
BPEvent* pev;
|
||||
cout << "[MyExperiment] Waiting for condition (1) (\"(id1 && id2)"
|
||||
<< " || id3\") to become true..." << endl;
|
||||
bool f1 = false, f2 = false, f3 = false;
|
||||
while (!((f1 && f2) || f3)) {
|
||||
pev = simulator.waitAny();
|
||||
cout << "[MyExperiment] Received event id=" << pev->getId()
|
||||
<< "." << endl;
|
||||
if(pev == &ev3)
|
||||
f3 = true;
|
||||
if(pev == &ev2)
|
||||
f2 = true;
|
||||
if(pev == &ev1)
|
||||
f1 = true;
|
||||
}
|
||||
cout << "[MyExperiment] Condition (1) satisfied! Ready..." << endl;
|
||||
// Remove residual (for all active experiments!)
|
||||
// events in the buffer:
|
||||
simulator.clearEvents();
|
||||
BPEvent foobar(ANY_ADDR);
|
||||
foobar.setCounter(400);
|
||||
cout << "[MyExperiment] Adding breakpoint-event, firing after the"
|
||||
<< " next 400 instructions..."; cout.flush();
|
||||
simulator.addEventAndWait(&foobar);
|
||||
cout << "cought! Exiting now." << endl;
|
||||
|
||||
simulator.clearEvents(this);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __MY_EXPERIMENT_HPP__
|
||||
@ -1,60 +0,0 @@
|
||||
#ifndef __SINGLE_STEPPING_EXPERIMENT_HPP__
|
||||
#define __SINGLE_STEPPING_EXPERIMENT_HPP__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "../controller/ExperimentFlow.hpp"
|
||||
#include "../SAL/SALInst.hpp"
|
||||
#include "config/FailConfig.hpp"
|
||||
#include "../SAL/bochs/BochsRegister.hpp"
|
||||
|
||||
// Check if aspect dependency is satisfied:
|
||||
#ifndef CONFIG_EVENT_CPULOOP
|
||||
#error Breakpoint-events needed! Enable aspect first (see FailConfig.hpp)!
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
#define FUNCTION_ENTRY_ADDRESS 0x3c1f
|
||||
|
||||
class SingleSteppingExperiment : public fail::ExperimentFlow {
|
||||
public:
|
||||
bool run()
|
||||
{
|
||||
/************************************
|
||||
* Description of experiment flow. *
|
||||
************************************/
|
||||
// Wait for function entry adresss:
|
||||
cout << "[SingleSteppingExperiment] Setting up experiment. Allowing"
|
||||
<< " to start now." << endl;
|
||||
BPEvent mainFuncEntry(FUNCTION_ENTRY_ADDRESS);
|
||||
simulator.addEvent(&mainFuncEntry);
|
||||
if (&mainFuncEntry != simulator.waitAny()) {
|
||||
cerr << "[SingleSteppingExperiment] Now, we are completely lost!"
|
||||
<< " It's time to cry! :-(" << endl;
|
||||
simulator.clearEvents(this);
|
||||
return false;
|
||||
}
|
||||
cout << "[SingleSteppingExperiment] Entry of main function reached!"
|
||||
<< " Beginning single-stepping..." << endl;
|
||||
char action;
|
||||
while (true) {
|
||||
BPEvent bp(ANY_ADDR);
|
||||
simulator.addEvent(&bp);
|
||||
simulator.waitAny();
|
||||
cout << "0x" << hex
|
||||
<< simulator.getRegisterManager().getInstructionPointer()
|
||||
<< endl;
|
||||
cout << "Continue (y/n)? ";
|
||||
cin >> action; cin.sync(); cin.clear();
|
||||
if (action != 'y')
|
||||
break;
|
||||
}
|
||||
|
||||
simulator.clearEvents(this);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __SINGLE_STEPPING_EXPERIMENT_HPP__
|
||||
@ -1,16 +0,0 @@
|
||||
#ifndef __INSTANTIATE_EXPERIMENT_AH__
|
||||
#define __INSTANTIATE_EXPERIMENT_AH__
|
||||
|
||||
// copy this file to a .ah file and instantiate the experiment(s) you need
|
||||
|
||||
#include "hscsimple.hpp"
|
||||
#include "../SAL/SALInst.hpp"
|
||||
|
||||
aspect hscsimple {
|
||||
hscsimpleExperiment experiment;
|
||||
advice execution ("void fail::SimulatorController::initExperiments()") : after () {
|
||||
fail::simulator.addFlow(&experiment);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __INSTANTIATE_EXPERIMENT_AH__
|
||||
@ -1,34 +0,0 @@
|
||||
## Setup desired protobuf descriptions HERE ##
|
||||
#set(MY_PROTOS
|
||||
# TestData.proto
|
||||
#)
|
||||
|
||||
set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
|
||||
|
||||
#find_package (LibElf REQUIRED)
|
||||
#find_package (LibDwarf REQUIRED)
|
||||
|
||||
#### PROTOBUFS ####
|
||||
#find_package(Protobuf REQUIRED)
|
||||
#include_directories(${PROTOBUF_INCLUDE_DIRS})
|
||||
include_directories(${CMAKE_BINARY_DIR})
|
||||
include_directories(${CMAKE_CURERNT_BINARY_DIR})
|
||||
|
||||
#PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${MY_PROTOS} )
|
||||
|
||||
## Build library
|
||||
#add_library(testmessages ${PROTO_SRCS})
|
||||
|
||||
## Add some tests
|
||||
#add_executable(testclient client.cc )
|
||||
#add_executable(testclient testjc.cc )
|
||||
#add_executable(testserver server.cc)
|
||||
#target_link_libraries(testclient fail ${PROTOBUF_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} anexperimentmessage protomessages)
|
||||
#target_link_libraries(testserver fail ${PROTOBUF_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} anexperimentmessage protomessages)
|
||||
|
||||
|
||||
#add_executable(dwarf dwarf.cc)
|
||||
#target_link_libraries(dwarf ${LIBDWARF_LIBRARIES} ${LIBELF_LIBRARIES} )
|
||||
#include_directories(${CMAKE_BINARY_DIR}/core/experiments/MHTestCampaign)
|
||||
#add_executable(mhcampaign mhcampaign.cc)
|
||||
#target_link_libraries(mhcampaign mhtestcampaign fail ${PROTOBUF_LIBRARY} ${Boost_THREAD_LIBRARY})
|
||||
@ -1,6 +0,0 @@
|
||||
message TestData {
|
||||
optional string foo = 1;
|
||||
optional int64 input = 2;
|
||||
|
||||
optional int64 output = 3;
|
||||
}
|
||||
@ -1,110 +0,0 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "jobserver/messagedefs/FailControlMessage.pb.h"
|
||||
#include "jobserver/SocketComm.hpp"
|
||||
|
||||
#include "experiments/AnExperiment/AnExperiment.pb.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void error(const char *s)
|
||||
{
|
||||
perror(s);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
template <typename Message>
|
||||
Message *get_job(int sockfd)
|
||||
{
|
||||
Message *msg = new Message;
|
||||
FailControlMessage ctrlmsg;
|
||||
|
||||
ctrlmsg.set_command(FailControlMessage_Command_NEED_WORK);
|
||||
ctrlmsg.set_build_id(42);
|
||||
|
||||
cout << "Sending need work msg: " << ctrlmsg.build_id() << ", Command: " << ctrlmsg.command() << endl;
|
||||
fail::SocketComm::send_msg(sockfd, ctrlmsg);
|
||||
cout << "sent ctrl message." << endl;
|
||||
fail::SocketComm::rcv_msg(sockfd, ctrlmsg);
|
||||
cout << "Received ctrl message: " << ctrlmsg.command() << endl;
|
||||
switch(ctrlmsg.command()){
|
||||
case FailControlMessage_Command_DIE: return 0;
|
||||
case FailControlMessage_Command_WORK_FOLLOWS:
|
||||
fail::SocketComm::rcv_msg(sockfd, *msg);
|
||||
return msg;
|
||||
default:
|
||||
cerr << "wtf?" << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename Message>
|
||||
void return_result(int sockfd, Message *msg)
|
||||
{
|
||||
FailControlMessage ctrlmsg;
|
||||
|
||||
ctrlmsg.set_command(FailControlMessage_Command_RESULT_FOLLOWS);
|
||||
ctrlmsg.set_build_id(42);
|
||||
cout << "Sending Result msg: " << ctrlmsg.build_id() << ", Command: " << ctrlmsg.command() << endl;
|
||||
fail::SocketComm::send_msg(sockfd, ctrlmsg);
|
||||
fail::SocketComm::send_msg(sockfd, *msg);
|
||||
delete msg;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
int portno;
|
||||
struct hostent *server;
|
||||
|
||||
cout << "JobClient" << endl;
|
||||
|
||||
if (argc < 3) {
|
||||
cerr << "usage: " << argv[0] << " hostname port" << endl;
|
||||
return 1;
|
||||
}
|
||||
portno = atoi(argv[2]);
|
||||
server = gethostbyname(argv[1]);
|
||||
if (server == NULL) {
|
||||
cerr << "cannot resolve host " << argv[1] << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int i = 1;
|
||||
while (1) {
|
||||
int sockfd;
|
||||
struct sockaddr_in serv_addr;
|
||||
cout << ">>>>>>>>>Durchgang " << i++ << endl;
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sockfd < 0) {
|
||||
error("socket()");
|
||||
}
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
|
||||
serv_addr.sin_port = htons(portno);
|
||||
|
||||
if (connect(sockfd, (sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
|
||||
error("connect()");
|
||||
}
|
||||
|
||||
MHTestData *msg = get_job<MHTestData>(sockfd);
|
||||
if(!msg){
|
||||
break;
|
||||
close(sockfd);
|
||||
}
|
||||
cout << "[Minion] received job input: " << msg->input() << endl;
|
||||
cout << "[Minion] Calculating " << msg->input() << "^2 = " << msg->input() * msg->input() << endl;
|
||||
msg->set_output(msg->input() * msg->input());
|
||||
sleep(1);
|
||||
cout << "[Minion] returning result: " << msg->output() << endl;
|
||||
|
||||
return_result<MHTestData>(sockfd, msg);
|
||||
|
||||
close(sockfd);
|
||||
}
|
||||
cout << "ByeBye" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,163 +0,0 @@
|
||||
/* Code sample: Using libdwarf for getting the address of a function
|
||||
** from DWARF in an ELF executable.
|
||||
** Not much error-handling or resource-freeing is done here...
|
||||
**
|
||||
** Eli Bendersky (http://eli.thegreenplace.net)
|
||||
** This code is in the public domain.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <dwarf.h>
|
||||
#include <libdwarf.h>
|
||||
|
||||
|
||||
void die(char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
/* List a function if it's in the given DIE.
|
||||
*/
|
||||
void list_func_in_die(Dwarf_Debug dgb, Dwarf_Die the_die)
|
||||
{
|
||||
char* die_name = 0;
|
||||
const char* tag_name = 0;
|
||||
Dwarf_Error err;
|
||||
Dwarf_Half tag;
|
||||
Dwarf_Attribute* attrs;
|
||||
Dwarf_Addr lowpc, highpc;
|
||||
Dwarf_Signed attrcount, i;
|
||||
int rc = dwarf_diename(the_die, &die_name, &err);
|
||||
|
||||
if (rc == DW_DLV_ERROR)
|
||||
die("Error in dwarf_diename\n");
|
||||
else if (rc == DW_DLV_NO_ENTRY)
|
||||
return;
|
||||
|
||||
if (dwarf_tag(the_die, &tag, &err) != DW_DLV_OK)
|
||||
die("Error in dwarf_tag\n");
|
||||
|
||||
/* Only interested in subprogram DIEs here */
|
||||
if (tag != DW_TAG_subprogram)
|
||||
return;
|
||||
|
||||
if (dwarf_get_TAG_name(tag, &tag_name) != DW_DLV_OK)
|
||||
die("Error in dwarf_get_TAG_name\n");
|
||||
|
||||
printf("DW_TAG_subprogram: '%s'\n", die_name);
|
||||
|
||||
/* Grab the DIEs attributes for display */
|
||||
if (dwarf_attrlist(the_die, &attrs, &attrcount, &err) != DW_DLV_OK)
|
||||
die("Error in dwarf_attlist\n");
|
||||
|
||||
for (i = 0; i < attrcount; ++i) {
|
||||
Dwarf_Half attrcode;
|
||||
if (dwarf_whatattr(attrs[i], &attrcode, &err) != DW_DLV_OK)
|
||||
die("Error in dwarf_whatattr\n");
|
||||
|
||||
/* We only take some of the attributes for display here.
|
||||
** More can be picked with appropriate tag constants.
|
||||
*/
|
||||
if (attrcode == DW_AT_low_pc)
|
||||
dwarf_formaddr(attrs[i], &lowpc, 0);
|
||||
else if (attrcode == DW_AT_high_pc)
|
||||
dwarf_formaddr(attrs[i], &highpc, 0);
|
||||
}
|
||||
|
||||
printf("low pc : 0x%08llx\n", lowpc);
|
||||
printf("high pc : 0x%08llx\n", highpc);
|
||||
}
|
||||
|
||||
|
||||
/* List all the functions from the file represented by the given descriptor.
|
||||
*/
|
||||
void list_funcs_in_file(Dwarf_Debug dbg)
|
||||
{
|
||||
Dwarf_Unsigned cu_header_length, abbrev_offset, next_cu_header;
|
||||
Dwarf_Half version_stamp, address_size;
|
||||
Dwarf_Error err;
|
||||
Dwarf_Die no_die = 0, cu_die, child_die;
|
||||
|
||||
/* Find compilation unit header */
|
||||
while (dwarf_next_cu_header(
|
||||
dbg,
|
||||
&cu_header_length,
|
||||
&version_stamp,
|
||||
&abbrev_offset,
|
||||
&address_size,
|
||||
&next_cu_header,
|
||||
&err) != DW_DLV_ERROR) {
|
||||
|
||||
/* Expect the CU to have a single sibling - a DIE */
|
||||
if (dwarf_siblingof(dbg, no_die, &cu_die, &err) == DW_DLV_ERROR)
|
||||
die("Error getting sibling of CU\n");
|
||||
|
||||
/* Expect the CU DIE to have children */
|
||||
if (dwarf_child(cu_die, &child_die, &err) == DW_DLV_ERROR)
|
||||
die("Error getting child of CU DIE\n");
|
||||
|
||||
/* Now go over all children DIEs */
|
||||
while (1) {
|
||||
int rc;
|
||||
list_func_in_die(dbg, child_die);
|
||||
|
||||
rc = dwarf_siblingof(dbg, child_die, &child_die, &err);
|
||||
|
||||
if (rc == DW_DLV_ERROR)
|
||||
die("Error getting sibling of DIE\n");
|
||||
else if (rc == DW_DLV_NO_ENTRY)
|
||||
break; /* done */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Dwarf_Debug dbg = 0;
|
||||
Dwarf_Error err;
|
||||
const char* progname;
|
||||
int fd = -1;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Expected a program name as argument\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
progname = argv[1];
|
||||
if ((fd = open(progname, O_RDONLY)) < 0) {
|
||||
perror("open");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (dwarf_init(fd, DW_DLC_READ, 0, 0, &dbg, &err) != DW_DLV_OK) {
|
||||
fprintf(stderr, "Failed DWARF initialization\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
list_funcs_in_file(dbg);
|
||||
|
||||
if (dwarf_finish(dbg, &err) != DW_DLV_OK) {
|
||||
fprintf(stderr, "Failed DWARF finalization\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
@ -1,62 +0,0 @@
|
||||
#include "jobserver/JobServer.hpp"
|
||||
#include <iostream>
|
||||
#include "experiments/AnExperiment.hpp"
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
|
||||
fail::JobServer js;
|
||||
using namespace std;
|
||||
|
||||
static const int nums = 30;
|
||||
|
||||
void exec_js(){
|
||||
js.waitForConnections();
|
||||
cout << "That's it.." << endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char**argv){
|
||||
|
||||
|
||||
cout << "Testing Jobserver" << endl;
|
||||
boost::thread th(exec_js);
|
||||
|
||||
AnExperimentData* datas[nums];
|
||||
|
||||
for(int i = 1; i <= nums; i++){
|
||||
datas[i] = new AnExperimentData;
|
||||
datas[i]->setInput(i);
|
||||
js.addExperiment(datas[i]);
|
||||
usleep(100 * 1000); // 100 ms
|
||||
}
|
||||
js.setNoMoreExperiments();
|
||||
|
||||
// test results.
|
||||
int f;
|
||||
int res = 0;
|
||||
int res2 = 0;
|
||||
AnExperimentData * exp;
|
||||
for(int i = 1; i <= nums; i++){
|
||||
exp = static_cast<AnExperimentData*>( js.m_doneJobs.Dequeue() );
|
||||
f = exp->getOutput();
|
||||
// cout << ">>>>>>>>>>>>>>> Output: " << i << "^2 = " << f << endl;
|
||||
res += f;
|
||||
res2 += (i*i);
|
||||
delete exp;
|
||||
}
|
||||
if (res == res2) {
|
||||
cout << "TEST SUCCESSFUL FINISHED! " << "[" << res << "==" << res2 << "]" << endl;
|
||||
}else{
|
||||
cout << "TEST FAILED!" << " [" << res << "!=" << res2 << "]" << endl;
|
||||
}
|
||||
cout << "thats all, waiting for server thread. " << endl;
|
||||
js.done();
|
||||
|
||||
th.join();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
#include <iostream>
|
||||
#include "jobserver/JobClient.hpp"
|
||||
|
||||
#include "experiments/AnExperiment.hpp"
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
int main(int argc, char** argv){
|
||||
|
||||
int portno;
|
||||
JobClient* jc;
|
||||
cout << "JobClient" << endl;
|
||||
if(argc == 1){
|
||||
jc = new JobClient();
|
||||
}else if(argc == 3){
|
||||
portno = atoi(argv[2]);
|
||||
jc = new JobClient(argv[1], portno);
|
||||
}else{
|
||||
cerr << "usage: " << argv[0] << " hostname port" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
AnExperimentData exp;
|
||||
|
||||
while(1){
|
||||
if(jc->getExperimentData(exp)){
|
||||
/// Do some work.
|
||||
cout << "Got data: " << exp.getInput() << endl;
|
||||
int result = exp.getInput() * exp.getInput();
|
||||
usleep(500 * 1000); // 500 ms
|
||||
/// Send back.
|
||||
exp.setOutput(result);
|
||||
jc->sendResult(exp);
|
||||
}else{
|
||||
cout << "No (more) data for me :(" << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete jc;
|
||||
|
||||
}
|
||||
@ -1,24 +0,0 @@
|
||||
#include "ExperimentDataQueue.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
// FIXME: This is deprecated stuff. Remove it.
|
||||
|
||||
namespace fi
|
||||
{
|
||||
|
||||
void ExperimentDataQueue::addData(ExperimentData* exp)
|
||||
{
|
||||
assert(exp != 0);
|
||||
m_queue.push_front(exp);
|
||||
}
|
||||
|
||||
ExperimentData* ExperimentDataQueue::getData()
|
||||
{
|
||||
ExperimentData* ret = m_queue.back();
|
||||
m_queue.pop_back();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
/**
|
||||
* \brief A queue for experiment data.
|
||||
*
|
||||
*
|
||||
* \author Martin Hoffmann, Richard Hellwig
|
||||
*
|
||||
*/
|
||||
|
||||
// FIXME: This is deprecated stuff. Remove it.
|
||||
|
||||
#ifndef __EXPERIMENT_DATA_QUEUE_H__
|
||||
#define __EXPERIMENT_DATA_QUEUE_H__
|
||||
|
||||
|
||||
#include <deque>
|
||||
#include "ExperimentData.hpp"
|
||||
|
||||
|
||||
namespace fi{
|
||||
|
||||
/**
|
||||
* \class ExperimentDataQueue
|
||||
* Class which manage ExperimentData in a queue.
|
||||
*/
|
||||
class ExperimentDataQueue
|
||||
{
|
||||
protected:
|
||||
std::deque<ExperimentData*> m_queue;
|
||||
|
||||
public:
|
||||
ExperimentDataQueue() {}
|
||||
~ExperimentDataQueue() {}
|
||||
|
||||
/**
|
||||
* Adds ExperimentData to the queue.
|
||||
* @param exp ExperimentData that is to be added to the queue.
|
||||
*/
|
||||
void addData(ExperimentData* exp);
|
||||
/**
|
||||
* Returns an item from the queue
|
||||
* @return the next element of the queue
|
||||
*/
|
||||
ExperimentData* getData();
|
||||
/**
|
||||
* Returns the number of elements in the queue
|
||||
* @return the size of teh queue
|
||||
*/
|
||||
size_t size() const { return m_queue.size(); };
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif //__EXPERIMENT_DATA_QUEUE_H__
|
||||
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
|
||||
// Author: Adrian Böckenkamp
|
||||
// Date: 15.06.2011
|
||||
|
||||
// FIXME: This is deprecated stuff. Delete it.
|
||||
|
||||
#include "Signal.hpp"
|
||||
|
||||
namespace fi
|
||||
{
|
||||
|
||||
std::auto_ptr<Signal> Signal::m_This;
|
||||
Mutex Signal::m_InstanceMutex;
|
||||
|
||||
|
||||
} // end-of-namespace: fi
|
||||
@ -1,135 +0,0 @@
|
||||
#ifndef __SIGNAL_HPP__
|
||||
#define __SIGNAL_HPP__
|
||||
|
||||
// FIXME: This is deprecated stuff. Delete it.
|
||||
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#ifndef __puma
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/interprocess/sync/named_semaphore.hpp>
|
||||
|
||||
#include <boost/thread/condition.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#endif
|
||||
|
||||
namespace fi
|
||||
{
|
||||
|
||||
#ifndef __puma
|
||||
typedef boost::mutex Mutex; // lock/unlock
|
||||
typedef boost::mutex::scoped_lock ScopeLock; // use RAII with lock/unlock mechanism
|
||||
typedef boost::condition_variable ConditionVariable; // wait/notify_one
|
||||
#else
|
||||
typedef int Mutex;
|
||||
typedef int ScopeLock;
|
||||
typedef int ConditionVariable;
|
||||
#endif
|
||||
|
||||
// Simulate a "private" semaphore using boost-mechanisms:
|
||||
class Semaphore
|
||||
{
|
||||
private:
|
||||
Mutex m_Mutex;
|
||||
ConditionVariable m_CondVar;
|
||||
unsigned long m_Value;
|
||||
public:
|
||||
// Create a semaphore object based on a mutex and a condition variable
|
||||
// and initialize it to value "init".
|
||||
Semaphore(unsigned long init = 0) : m_Value(init) { }
|
||||
|
||||
void post()
|
||||
{
|
||||
ScopeLock lock(m_Mutex);
|
||||
++m_Value; // increase semaphore value:
|
||||
#ifndef __puma
|
||||
m_CondVar.notify_one(); // wake up other thread, currently waiting on condition var.
|
||||
#endif
|
||||
}
|
||||
|
||||
void wait()
|
||||
{
|
||||
ScopeLock lock(m_Mutex);
|
||||
#ifndef __puma
|
||||
while(!m_Value) // "wait-if-zero"
|
||||
m_CondVar.wait(lock);
|
||||
#endif
|
||||
--m_Value; // decrease semaphore value
|
||||
}
|
||||
};
|
||||
|
||||
class Signal
|
||||
{
|
||||
private:
|
||||
static Mutex m_InstanceMutex; // used to sync calls to getInst()
|
||||
static std::auto_ptr<Signal> m_This; // the one and only instance
|
||||
|
||||
Semaphore m_semBochs;
|
||||
Semaphore m_semContr;
|
||||
Semaphore m_semSimCtrl;
|
||||
bool m_Locked; // prevent misuse of thread-sync
|
||||
|
||||
// Singleton class (forbid creation, copying and assignment):
|
||||
Signal()
|
||||
: m_semBochs(0), m_semContr(0),
|
||||
m_semSimCtrl(0), m_Locked(false) { }
|
||||
Signal(Signal const& s)
|
||||
: m_semBochs(), m_semContr(),
|
||||
m_semSimCtrl(), m_Locked(false) { } // never called.
|
||||
Signal& operator=(Signal const&) { return *this; } // dito.
|
||||
~Signal() { }
|
||||
friend class std::auto_ptr<Signal>;
|
||||
public:
|
||||
static Signal& getInst()
|
||||
{
|
||||
ScopeLock lock(m_InstanceMutex); // lock/unlock handled by RAII principle
|
||||
if(!m_This.get())
|
||||
m_This.reset(new Signal());
|
||||
return (*m_This);
|
||||
}
|
||||
|
||||
// Called from Experiment-Controller class ("beyond Bochs"):
|
||||
void lockExperiment()
|
||||
{
|
||||
assert(!m_Locked &&
|
||||
"[Signal::lockExperiment]: lockExperiment called twice without calling unlockExperiment() in between.");
|
||||
m_Locked = true;
|
||||
m_semContr.wait(); // suspend experiment process
|
||||
}
|
||||
|
||||
// Called from Experiment-Controller class ("beyond Bochs"):
|
||||
void unlockExperiment()
|
||||
{
|
||||
assert(m_Locked &&
|
||||
"[Signal::unlockExperiment]: unlockExperiment called twice without calling lockExperiment() in between.");
|
||||
m_Locked = false;
|
||||
m_semBochs.post(); // resume experiment (continue bochs simulation)
|
||||
}
|
||||
|
||||
// Called from Advice-Code ("within Bochs") to trigger event occurrence:
|
||||
void signalEvent()
|
||||
{
|
||||
m_semContr.post(); // Signal event (to Experiment-Controller)
|
||||
m_semBochs.wait(); // Wait upon handling to finish
|
||||
}
|
||||
|
||||
// Called from Experiment-Controller to allow simulation start:
|
||||
void startSimulation()
|
||||
{
|
||||
m_semSimCtrl.post();
|
||||
}
|
||||
|
||||
// Called from Bochs, directly after thread creation for Experiment-Controller:
|
||||
// (This ensures that Bochs waits until the experiment has been set up in the
|
||||
// Experiment-Controller.)
|
||||
void waitForStartup()
|
||||
{
|
||||
m_semSimCtrl.wait();
|
||||
}
|
||||
};
|
||||
|
||||
} // end-of-namespace: fi
|
||||
|
||||
#endif /* __SIGNAL_HPP__ */
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
#include "SynchronizedExperimentDataQueue.hpp"
|
||||
|
||||
// FIXME: This file is not used. Delete it either.
|
||||
|
||||
namespace fi {
|
||||
|
||||
void SynchronizedExperimentDataQueue::addData(ExperimentData* exp){
|
||||
//
|
||||
m_sema_full.wait();
|
||||
ExperimentDataQueue::addData(exp);
|
||||
m_sema_empty.post();
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
ExperimentData* SynchronizedExperimentDataQueue::getData(){
|
||||
//
|
||||
m_sema_empty.wait();
|
||||
return ExperimentDataQueue::getData();
|
||||
m_sema_full.post();
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
@ -1,57 +0,0 @@
|
||||
/**
|
||||
* \brief A queue for experiment data.
|
||||
*
|
||||
*
|
||||
* \author Martin Hoffmann, Richard Hellwig
|
||||
*
|
||||
*/
|
||||
|
||||
// FIXME: This file is not used. Delete it.
|
||||
|
||||
#ifndef __SYNC_EXPERIMENT_DATA_QUEUE_H__
|
||||
#define __SYNC_EXPERIMENT_DATA_QUEUE_H__
|
||||
|
||||
#include "ExperimentDataQueue.hpp"
|
||||
#include "Signal.hpp"
|
||||
|
||||
namespace fi{
|
||||
|
||||
/**
|
||||
* \class SynchronizedExperimentDataQueue
|
||||
* Class which manage ExperimentData in a queue.
|
||||
* Thread safe using semphores.
|
||||
*/
|
||||
class SynchronizedExperimentDataQueue : public ExperimentDataQueue
|
||||
{
|
||||
private:
|
||||
/// There are maxSize elements in at a time
|
||||
/// Or do we allow a really possibly huge queue?
|
||||
Semaphore m_sema_full;
|
||||
Semaphore m_sema_empty;
|
||||
|
||||
public:
|
||||
SynchronizedExperimentDataQueue(int maxSize = 1024) : m_sema_full(maxSize), m_sema_empty(0) {}
|
||||
~SynchronizedExperimentDataQueue() {}
|
||||
|
||||
/**
|
||||
* Adds ExperimentData to the queue.
|
||||
* @param exp ExperimentData that is to be added to the queue.
|
||||
*/
|
||||
void addData(ExperimentData* exp);
|
||||
/**
|
||||
* Returns an item from the queue
|
||||
* @return the next element of the queue
|
||||
*/
|
||||
ExperimentData* getData();
|
||||
/**
|
||||
* Returns the number of elements in the queue
|
||||
* @return the size of the queue
|
||||
*/
|
||||
size_t size() const { return m_queue.size(); };
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif //__EXPERIMENT_DATA_QUEUE_H__
|
||||
|
||||
|
||||
Reference in New Issue
Block a user