[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