[Avida-SVN] r3581 - in development/source: actions cpu main
beckma24 at myxo.css.msu.edu
beckma24 at myxo.css.msu.edu
Mon Dec 28 12:25:54 PST 2009
Author: beckma24
Date: 2009-12-28 15:25:53 -0500 (Mon, 28 Dec 2009)
New Revision: 3581
Modified:
development/source/actions/PrintActions.cc
development/source/cpu/cHardwareBase.h
development/source/cpu/cHardwareCPU.cc
development/source/cpu/cHardwareCPU.h
development/source/cpu/cHardwareExperimental.h
development/source/cpu/cHardwareGX.h
development/source/cpu/cHardwareSMT.h
development/source/cpu/cHardwareTransSMT.h
development/source/main/cDeme.cc
development/source/main/cDeme.h
development/source/main/cOrganism.cc
development/source/main/cStats.cc
development/source/main/cStats.h
Log:
Active messages can now trigger thread-based interrupts. Interrupts caused by movement have not been tested, but the code is there. Minor perfromace hit because of addition of conditional on line 795 of cHardwareCPU::SingleProcess. I'm open to suggestions on alternative code for scheduling interrupt threads. Thread preemption config option is not currently implemented.
Modified: development/source/actions/PrintActions.cc
===================================================================
--- development/source/actions/PrintActions.cc 2009-12-28 17:13:01 UTC (rev 3580)
+++ development/source/actions/PrintActions.cc 2009-12-28 20:25:53 UTC (rev 3581)
@@ -77,6 +77,7 @@
STATS_OUT_FILE(PrintStatsData, stats.dat );
STATS_OUT_FILE(PrintCountData, count.dat );
STATS_OUT_FILE(PrintMessageData, message.dat );
+STATS_OUT_FILE(PrintInterruptData, interrupt.dat );
STATS_OUT_FILE(PrintTotalsData, totals.dat );
STATS_OUT_FILE(PrintTasksData, tasks.dat );
STATS_OUT_FILE(PrintTasksExeData, tasks_exe.dat );
@@ -3153,6 +3154,7 @@
action_lib->Register<cActionPrintStatsData>("PrintStatsData");
action_lib->Register<cActionPrintCountData>("PrintCountData");
action_lib->Register<cActionPrintMessageData>("PrintMessageData");
+ action_lib->Register<cActionPrintInterruptData>("PrintInterruptData");
action_lib->Register<cActionPrintTotalsData>("PrintTotalsData");
action_lib->Register<cActionPrintTasksData>("PrintTasksData");
action_lib->Register<cActionPrintTasksExeData>("PrintTasksExeData");
Modified: development/source/cpu/cHardwareBase.h
===================================================================
--- development/source/cpu/cHardwareBase.h 2009-12-28 17:13:01 UTC (rev 3580)
+++ development/source/cpu/cHardwareBase.h 2009-12-28 20:25:53 UTC (rev 3581)
@@ -88,9 +88,6 @@
static const unsigned int MASKOFF_LOWEST12 = 0xFFFFF000;
static const unsigned int MASKOFF_LOWEST8 = 0xFFFFFF00;
static const unsigned int MASKOFF_LOWEST4 = 0xFFFFFFF0;
-
- // interrupt types
- enum interruptTypes {MSG_INTERRUPT = 0, MOVE_INTERRUPT};
cHardwareBase(); // @not_implemented
cHardwareBase(const cHardwareBase&); // @not_implemented
@@ -100,14 +97,16 @@
cHardwareBase(cWorld* world, cOrganism* in_organism, cInstSet* inst_set, int inst_set_id);
virtual ~cHardwareBase() { ; }
- int GetInstSetID() const { return m_inst_set_id; }
+ // interrupt types
+ enum interruptTypes {MSG_INTERRUPT = 0, MOVE_INTERRUPT};
+ int GetInstSetID() const { return m_inst_set_id; }
// -------- Organism ---------
cOrganism* GetOrganism() { return m_organism; }
const cInstSet& GetInstSet() { return *m_inst_set; }
-
+
// -------- Core Functionality --------
void Reset(cAvidaContext& ctx);
virtual bool SingleProcess(cAvidaContext& ctx, bool speculative = false) = 0;
@@ -174,6 +173,9 @@
virtual int GetCurThread() const = 0;
virtual int GetCurThreadID() const = 0;
+ // interrupt current thread
+ virtual bool InterruptThread(int interruptType) = 0; // only implemented in cHardwareCPU
+
// -------- Parasite Stuff --------
virtual bool InjectHost(const cCodeLabel& in_label, const cGenome& injection) = 0;
@@ -257,9 +259,6 @@
int TriggerMutations_ScopeGlobal(cAvidaContext& ctx, const cMutation* cur_mut,
cGenome& target_memory, cHeadCPU& cur_head, const double rate);
- // interrupt current thread
- void InterruptThread(int interruptType) {;}
-
private:
void checkImplicitRepro(cAvidaContext& ctx, bool exec_last_inst = false);
};
Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc 2009-12-28 17:13:01 UTC (rev 3580)
+++ development/source/cpu/cHardwareCPU.cc 2009-12-28 20:25:53 UTC (rev 3581)
@@ -538,15 +538,15 @@
tInstLibEntry<tMethod>("alarm-label-low", &cHardwareCPU::Inst_Alarm_Label),
// Interrupt
+ tInstLibEntry<tMethod>("send-msg-interrupt-type0", &cHardwareCPU::Inst_SendMessageInterruptType0, nInstFlag::STALL),
tInstLibEntry<tMethod>("send-msg-interrupt-type1", &cHardwareCPU::Inst_SendMessageInterruptType1, nInstFlag::STALL),
tInstLibEntry<tMethod>("send-msg-interrupt-type2", &cHardwareCPU::Inst_SendMessageInterruptType1, nInstFlag::STALL),
- tInstLibEntry<tMethod>("msg-handler", &cHardwareCPU::Inst_MSG_Handler),
- tInstLibEntry<tMethod>("msg-handler-type1", &cHardwareCPU::Inst_MSG_Handler),
- tInstLibEntry<tMethod>("msg-handler-type2", &cHardwareCPU::Inst_MSG_Handler),
-// tInstLibEntry<tMethod>("moved-handler", &cHardwareCPU::Inst_Moved_Handler),
- tInstLibEntry<tMethod>("end-handler", &cHardwareCPU::Inst_End_Handler),
+ tInstLibEntry<tMethod>("msg-handler-type0", &cHardwareCPU::Inst_START_Handler),
+ tInstLibEntry<tMethod>("msg-handler-type1", &cHardwareCPU::Inst_START_Handler),
+ tInstLibEntry<tMethod>("msg-handler-type2", &cHardwareCPU::Inst_START_Handler),
+ tInstLibEntry<tMethod>("moved-handler", &cHardwareCPU::Inst_START_Handler),
+ tInstLibEntry<tMethod>("end-handler", &cHardwareCPU::Inst_End_Handler),
-
// Placebo instructions
tInstLibEntry<tMethod>("skip", &cHardwareCPU::Inst_Skip),
@@ -786,9 +786,16 @@
// timestep, adjust the number of instructions executed accordingly.
const int num_inst_exec = m_thread_slicing_parallel ? num_threads : 1;
+ const bool isInterruptEnabled = m_world->GetConfig().INTERRUPT_ENABLED.Get();
+
for (int i = 0; i < num_inst_exec; i++) {
// Setup the hardware for the next instruction to be executed.
- int last_thread = m_cur_thread++;
+ int last_thread = m_cur_thread;
+
+ if (!isInterruptEnabled) {
+ m_cur_thread++;
+ } // else INTERRUPT_ENABLED is true and only current thread is processed.
+
if (m_cur_thread >= num_threads) m_cur_thread = 0;
m_advance_ip = true;
@@ -1363,25 +1370,11 @@
cString handlerHeadInstructionString;
switch (interruptType) {
- case MSG_INTERRUPT: {
- int messageType = GetOrganism()->PeekAtNextMessageType();
- if(messageType == 0) {
- handlerHeadInstructionString.Set("msg-handler");
- } else {
- handlerHeadInstructionString.Set("msg-handler-type%d", messageType);
- }
-
- // if(initializeInterruptState(msgHandlerString)) {
- // IP().Retreat();
- // Inst_RetrieveMessage(m_world->GetDefaultContext());
- // IP().Advance();
- // }
+ case MSG_INTERRUPT:
+ handlerHeadInstructionString.Set("msg-handler-type%d", GetOrganism()->PeekAtNextMessageType());
break;
- }
case MOVE_INTERRUPT:
- // if(initializeInterruptState("moved-handler")) {
- // ; // perform movement interrupt initialization here
- // }
+ handlerHeadInstructionString.Set("moved-handler");
break;
default:
cerr << "Unknown intrerrupt type " << interruptType << " Exitting.\n\n";
@@ -1398,7 +1391,9 @@
while (start_pos != search_head.GetPosition()) {
if (search_head.GetInst() == label_inst) { // found handlerHeadInstructionString
search_head++; // one instruction past instruction
+ break;
}
+ search_head++;
}
if(start_pos == search_head.GetPosition()) {
@@ -1428,6 +1423,20 @@
for(int i = 0; i < NUM_HEADS; i++) {
GetHead(i,new_id).Set(search_head.GetPosition());
}
+
+ switch (interruptType) {
+ case MSG_INTERRUPT:
+ IP().Retreat();
+ Inst_RetrieveMessage(m_world->GetDefaultContext());
+ IP().Advance();
+ break;
+ case MOVE_INTERRUPT:
+ // do nothing extra
+ break;
+ }
+
+ m_organism->GetOrgInterface().GetDeme()->IncOrgInterruptedCount();
+
return true;
}
@@ -7291,6 +7300,12 @@
return SendMessage(ctx);
}
+// Same as cHardwareCPU::Inst_SendMessage. Added for clearity
+bool cHardwareCPU::Inst_SendMessageInterruptType0(cAvidaContext& ctx)
+{
+ return SendMessage(ctx, 0);
+}
+
bool cHardwareCPU::Inst_SendMessageInterruptType1(cAvidaContext& ctx)
{
return SendMessage(ctx, 1);
@@ -7302,7 +7317,7 @@
}
// jumps one instruction passed end-handler
-bool cHardwareCPU::Inst_MSG_Handler(cAvidaContext& ctx) {
+bool cHardwareCPU::Inst_START_Handler(cAvidaContext& ctx) {
m_advance_ip = false;
//Jump 1 instruction passed msg-handler
cInstruction label_inst = GetInstSet().GetInst("end-handler");
@@ -7324,8 +7339,9 @@
}
bool cHardwareCPU::Inst_End_Handler(cAvidaContext& ctx) {
- KillThread(); // return false if one thread exists or max threads has been reached... this is OK.
- // previous thread is now restored
+ if(KillThread()) { // return false if one thread exists or max threads has been reached... this is OK.
+ m_organism->GetOrgInterface().GetDeme()->DecOrgInterruptedCount();
+ } // previous thread is now restored
// if interrupt enabled and more messages to process then reinterrupt
if (m_organism->GetReceivedMessages().size() > 0) {
Modified: development/source/cpu/cHardwareCPU.h
===================================================================
--- development/source/cpu/cHardwareCPU.h 2009-12-28 17:13:01 UTC (rev 3580)
+++ development/source/cpu/cHardwareCPU.h 2009-12-28 20:25:53 UTC (rev 3581)
@@ -763,11 +763,10 @@
bool Inst_Broadcast8(cAvidaContext& ctx);
// Active messaging //
+ bool Inst_SendMessageInterruptType0(cAvidaContext& ctx);
bool Inst_SendMessageInterruptType1(cAvidaContext& ctx);
bool Inst_SendMessageInterruptType2(cAvidaContext& ctx);
- bool Inst_MSG_Handler(cAvidaContext& ctx);
- bool Inst_MSG_Handler_Type1(cAvidaContext& ctx);
- bool Inst_MSG_Handler_Type2(cAvidaContext& ctx);
+ bool Inst_START_Handler(cAvidaContext& ctx);
bool Inst_End_Handler(cAvidaContext& ctx);
//// Alarm ////
Modified: development/source/cpu/cHardwareExperimental.h
===================================================================
--- development/source/cpu/cHardwareExperimental.h 2009-12-28 17:13:01 UTC (rev 3580)
+++ development/source/cpu/cHardwareExperimental.h 2009-12-28 20:25:53 UTC (rev 3581)
@@ -295,7 +295,9 @@
int GetCurThread() const { return m_cur_thread; }
int GetCurThreadID() const { return m_threads[m_cur_thread].GetID(); }
-
+ // interrupt current thread
+ bool InterruptThread(int interruptType) { return false; }
+
// -------- Parasite Stuff --------
bool InjectHost(const cCodeLabel& in_label, const cGenome& injection);
Modified: development/source/cpu/cHardwareGX.h
===================================================================
--- development/source/cpu/cHardwareGX.h 2009-12-28 17:13:01 UTC (rev 3580)
+++ development/source/cpu/cHardwareGX.h 2009-12-28 20:25:53 UTC (rev 3581)
@@ -371,6 +371,9 @@
virtual int GetCurThread() const { return -1; }
virtual int GetCurThreadID() const { return -1; }
+ // interrupt current thread
+ bool InterruptThread(int interruptType) { return false; }
+
// -------- Parasite Stuff --------
bool InjectHost(const cCodeLabel& in_label, const cGenome& injection);
Modified: development/source/cpu/cHardwareSMT.h
===================================================================
--- development/source/cpu/cHardwareSMT.h 2009-12-28 17:13:01 UTC (rev 3580)
+++ development/source/cpu/cHardwareSMT.h 2009-12-28 20:25:53 UTC (rev 3581)
@@ -262,7 +262,9 @@
int GetCurThread() const { return m_cur_thread; }
int GetCurThreadID() const { return m_cur_thread; }
-
+ // interrupt current thread
+ bool InterruptThread(int interruptType) { return false; }
+
// -------- Parasite Stuff --------
bool InjectHost(const cCodeLabel& in_label, const cGenome& inject_code);
Modified: development/source/cpu/cHardwareTransSMT.h
===================================================================
--- development/source/cpu/cHardwareTransSMT.h 2009-12-28 17:13:01 UTC (rev 3580)
+++ development/source/cpu/cHardwareTransSMT.h 2009-12-28 20:25:53 UTC (rev 3581)
@@ -260,7 +260,9 @@
int GetCurThread() const { return m_cur_thread; }
int GetCurThreadID() const { return m_cur_thread; }
-
+ // interrupt current thread
+ bool InterruptThread(int interruptType) { return false; }
+
// -------- Parasite Stuff --------
bool InjectHost(const cCodeLabel& in_label, const cGenome& inject_code);
Modified: development/source/main/cDeme.cc
===================================================================
--- development/source/main/cDeme.cc 2009-12-28 17:13:01 UTC (rev 3580)
+++ development/source/main/cDeme.cc 2009-12-28 20:25:53 UTC (rev 3581)
@@ -42,7 +42,7 @@
cDeme::cDeme() : _id(0), width(0), replicateDeme(false), treatable(false), cur_birth_count(0), last_birth_count(0), cur_org_count(0), last_org_count(0), injected_count(0), birth_count_perslot(0),
_age(0), generation(0), total_org_energy(0.0),
time_used(0), gestation_time(0), cur_normalized_time_used(0.0), last_normalized_time_used(0.0),
-MSG_sendFailed(0), MSG_dropped(0), MSG_SuccessfullySent(0), MSG_sent(0), energyInjectedIntoOrganisms(0.0), energyRemainingInDemeAtReplication(0.0), total_energy_testament(0.0),
+MSG_sendFailed(0), MSG_dropped(0), MSG_SuccessfullySent(0), MSG_sent(0), numOrgsInterruted(0), energyInjectedIntoOrganisms(0.0), energyRemainingInDemeAtReplication(0.0), total_energy_testament(0.0),
eventsTotal(0), eventsKilled(0), eventsKilledThisSlot(0), eventKillAttempts(0), eventKillAttemptsThisSlot(0),
consecutiveSuccessfulEventPeriods(0), sleeping_count(0),
avg_founder_generation(0.0), generations_per_lifetime(0.0),
@@ -314,7 +314,9 @@
MSG_dropped = 0;
MSG_SuccessfullySent = 0;
MSG_sent = 0;
-
+
+ numOrgsInterruted = 0;
+
consecutiveSuccessfulEventPeriods = 0;
replicateDeme = false;
Modified: development/source/main/cDeme.h
===================================================================
--- development/source/main/cDeme.h 2009-12-28 17:13:01 UTC (rev 3580)
+++ development/source/main/cDeme.h 2009-12-28 20:25:53 UTC (rev 3581)
@@ -81,6 +81,7 @@
unsigned int MSG_dropped;
unsigned int MSG_SuccessfullySent;
unsigned int MSG_sent;
+ unsigned int numOrgsInterruted;
double energyInjectedIntoOrganisms; //! total amount of energy injected into seed organisms
double energyRemainingInDemeAtReplication; //! total amount of energy remaining in deme when deme was last replicated.
double total_energy_testament; //! total amount of energy from suicide organisms for offspring deme
@@ -345,6 +346,11 @@
unsigned int GetMessageDropped() { return MSG_dropped; }
unsigned int GetMessageSendFailed() { return MSG_sendFailed; }
+ // --- Organism Interrupted Stats --- //
+ void IncOrgInterruptedCount() { ++numOrgsInterruted; }
+ void DecOrgInterruptedCount() { --numOrgsInterruted; }
+ int GetOrgInterruptedCount() { return numOrgsInterruted; }
+
// --- Pheromones --- //
void AddPheromone(int absolute_cell_id, double value);
Modified: development/source/main/cOrganism.cc
===================================================================
--- development/source/main/cOrganism.cc 2009-12-28 17:13:01 UTC (rev 3580)
+++ development/source/main/cOrganism.cc 2009-12-28 20:25:53 UTC (rev 3581)
@@ -26,6 +26,7 @@
#include "cOrganism.h"
#include "cAvidaContext.h"
+#include "cHeadCPU.h"
#include "nHardware.h"
#include "cEnvironment.h"
#include "functions.h"
@@ -895,22 +896,16 @@
msg.SetReceiver(this);
m_msg->received.push_back(msg);
-
- //TODO: perform context switch
- // need config option for depth of saved context stack
-
- // if(INTERRUPT_ENABLED) {
+
+ if (m_world->GetConfig().INTERRUPT_ENABLED.Get()) {
// if preempt running interrupt thread and #thread < max_threads
+// if (m_world->GetConfig().INTERRUPT_PREEMPTION_ENABLED.Get() && m_world->GetConfig().MAX_CPU_THREADS.Get() >= m_hardware->GetNumThreads()) {
// then create new thread and load its registers
-
- // hardware->IP().Retreat();
- // hardware->Inst_RetrieveMessage(m_world->GetDefaultContext());
- // hardware->IP().Advance();
-
- // else // cannot preempt
+ m_hardware->InterruptThread(cHardwareBase::MSG_INTERRUPT);
+// }
+ // else cannot preempt!
// do nothing since message is already buffered. It will get processed later.
-
-
+ }
}
@@ -938,6 +933,16 @@
{
assert(m_interface);
DoOutput(ctx);
+
+ if (m_world->GetConfig().INTERRUPT_ENABLED.Get()) {
+ // if preempt running interrupt thread and #thread < max_threads
+ if (m_world->GetConfig().INTERRUPT_PREEMPTION_ENABLED.Get() && m_world->GetConfig().MAX_CPU_THREADS.Get() >= m_hardware->GetNumThreads()) {
+ // then create new thread and load its registers
+ m_hardware->InterruptThread(cHardwareBase::MOVE_INTERRUPT);
+ }
+ // else cannot preempt!
+ // do nothing since message is already buffered. It will get processed later.
+ }
} //End cOrganism::Move()
bool cOrganism::BcastAlarmMSG(cAvidaContext& ctx, int jump_label, int bcast_range) {
Modified: development/source/main/cStats.cc
===================================================================
--- development/source/main/cStats.cc 2009-12-28 17:13:01 UTC (rev 3580)
+++ development/source/main/cStats.cc 2009-12-28 20:25:53 UTC (rev 3581)
@@ -867,7 +867,7 @@
void cStats::PrintMessageData(const cString& filename) {
cDataFile& df = m_world->GetDataFile(filename);
- df.WriteComment( "Number of organsism to organisms messages\n" );
+ df.WriteComment( "Number of organism to organism messages\n" );
df.Write( GetUpdate(), "update" );
@@ -886,7 +886,7 @@
totalMessagesFailed += pop.GetDeme(i).GetMessageSendFailed();
}
- df.Write(totalMessagesSent, "Totlal messages sent");
+ df.Write(totalMessagesSent, "Total messages sent");
df.Write(totalMessagesSuccessfullySent, "Sent successfully");
df.Write(totalMessagesDropped, "Dropped");
df.Write(totalMessagesFailed, "Failed");
@@ -894,6 +894,27 @@
df.Endl();
}
+void cStats::PrintInterruptData(const cString& filename) {
+ cDataFile& df = m_world->GetDataFile(filename);
+
+ df.WriteComment( "Total number of organisms interrupted\n" );
+
+ df.Write( GetUpdate(), "update" );
+
+ cPopulation& pop = m_world->GetPopulation();
+ int numDemes = pop.GetNumDemes();
+
+ unsigned int totalOrgsInterrupted(0);
+
+ for( int i=0; i < numDemes; i++ ){
+ totalOrgsInterrupted += pop.GetDeme(i).GetOrgInterruptedCount();
+ }
+
+ df.Write(totalOrgsInterrupted, "Total organisms interrupted");
+
+ df.Endl();
+}
+
void cStats::PrintTotalsData(const cString& filename)
{
cDataFile& df = m_world->GetDataFile(filename);
Modified: development/source/main/cStats.h
===================================================================
--- development/source/main/cStats.h 2009-12-28 17:13:01 UTC (rev 3580)
+++ development/source/main/cStats.h 2009-12-28 20:25:53 UTC (rev 3581)
@@ -778,6 +778,7 @@
void PrintStatsData(const cString& filename);
void PrintCountData(const cString& filename);
void PrintMessageData(const cString& filename);
+ void PrintInterruptData(const cString& filename);
void PrintTotalsData(const cString& filename);
void PrintTasksData(const cString& filename);
void PrintTasksExeData(const cString& filename);
More information about the Avida-cvs
mailing list