• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

sst/elements/genericProc/FE/thread.h

00001 // Copyright 2010 Sandia Corporation. Under the terms
00002 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
00003 // Government retains certain rights in this software.
00004 // 
00005 // Copyright (c) 2005-2010, Sandia Corporation
00006 // All rights reserved.
00007 // Copyright (c) 2003-2005, University of Notre Dame
00008 // All rights reserved.
00009 // 
00010 // This file is part of the SST software package. For license
00011 // information, see the LICENSE file in the top level directory of the
00012 // distribution.
00013 
00014 
00015 #ifndef THREAD_H
00016 #define THREAD_H
00017 
00018 #include "instruction.h"
00019 #include "fe_memory.h"
00020 
00021 #include <vector>
00022 using namespace std;
00023 
00024 #include <string>
00025 using std::string;
00026 
00027 //#include "sst/boost.h"
00028 #include "sst/core/component.h"
00029 
00030 // forward declare function from ppcMachine.h so that we don't ahve to
00031 // drag all that code into here.
00032 void md_init_decoder(void);
00033 
00034 class processor;
00035 class thread;
00036 
00037 class threadSource {
00038   friend class boost::serialization::access;
00039   template<class Archive>
00040   void save(Archive & ar, const unsigned int version) const
00041   {
00042     ar & BOOST_SERIALIZATION_NVP(firstThreads);
00043     ar & BOOST_SERIALIZATION_NVP(proc);    
00044   }
00045   template<class Archive>
00046   void load(Archive & ar, const unsigned int version)
00047   {
00048     ar & BOOST_SERIALIZATION_NVP(firstThreads);
00049     ar & BOOST_SERIALIZATION_NVP(proc);    
00050     md_init_decoder();
00051   }
00052   BOOST_SERIALIZATION_SPLIT_MEMBER()
00053 
00054   vector<thread*> firstThreads;
00055   processor *proc;
00056 public:
00057   void init(processor *, SST::Component::Params_t& paramsC);
00058   thread* getFirstThread(unsigned int);
00059   void deleteThread(thread *t);
00060 };
00061 
00062 //: Front End Thread
00063 //
00064 // Representation of a thread.
00065 //
00066 // Threads are factories for instructions which are consumed by
00067 // processors.
00068 //
00069 // For backends which which to model out-of-order execution or branch
00070 // prediction, things are a bit more complex. The back end it required
00071 // to track the program counter. Instead of simply asking for the next
00072 // instruction, the backend must provide a program counter. The
00073 // backEnd is responsible for detecting when a misprediction has
00074 // occured. If it wishes to model speculative execution, it must
00075 // inform the thread that it is beginning speculation and when it is
00076 // ending speculative execution.
00077 //
00078 // This allows the thread to do something similar to
00079 // simpleScalar. When speculative execution begins, a copy of the
00080 // threads state is made which is used during the speculative
00081 // execution. When speculation ends, the thread can simply discard the
00082 // speculative state.
00083 //
00084 //!SEC:Framework
00085 class thread {  
00086   string Cfgstr;
00087   friend class boost::serialization::access;
00088   template<class Archive> 
00089   void serialize(Archive & ar, const unsigned int version )
00090   {
00091     ar & BOOST_SERIALIZATION_NVP(callStack);
00092     ar & BOOST_SERIALIZATION_NVP(stackStack);
00093     ar & BOOST_SERIALIZATION_NVP(targetStack);
00094     ar & BOOST_SERIALIZATION_NVP(mem_accs);
00095     ar & BOOST_SERIALIZATION_NVP(_isDead);
00096     ar & BOOST_SERIALIZATION_NVP(eviction);
00097     ar & BOOST_SERIALIZATION_NVP(migration);    
00098   }
00099  protected:  
00100   vector<simAddress> callStack;
00101   vector<simAddress> stackStack;
00102   vector<simAddress> targetStack;
00103   //: Is this thread active?
00104   //
00105   // A thread may be 'dead' but has not been collected yet. 
00106   bool _isDead;
00107 
00108   simAddress stack_top, stack_base;
00109   unsigned int call_count, max_call_stk;
00110   unsigned int mem_accs[MemTypes];
00111 
00112   bool eviction, migration;
00113 
00114  public:
00115 
00116   void setEvict(bool tf) {eviction = tf;}
00117   bool canEvict() {return eviction;}
00118   void setMigrate(bool tf) {migration = tf;}
00119   bool canMigrate() {return migration;}
00120 
00121  thread() : stack_base(0), eviction(true), migration(true) {
00122     for (int i = 0; i < MemTypes; i++)
00123       mem_accs[i] = 0;
00124   }
00125 
00126   void recordMemStat();
00127 
00128   void freeStack();
00129 #if 0
00130   void setStackLimits (simAddress max, simAddress min);
00131   int checkAccess (simAddress sa);
00132   virtual void printCallStack();
00133   virtual simAddress popFromCallStack();
00134   virtual void pushToCallStack(simAddress lr, simAddress sp, simAddress target);
00135 #endif
00136 
00137   virtual ~thread() {;}
00138   //: Accessor for 'death' status of thread
00139   bool isDead() {return _isDead;};
00140   //: Returns the next instruction in the stream
00141   //
00142   // This function may return a NULL if the thread cannot produce
00143   // another instruction. For example, it may not support more than
00144   // one outstanding instruction, or it may not be able to speculate
00145   // beyond a branch.
00146   virtual instruction* getNextInstruction()=0;
00147   //: Cancel execution of an instruction
00148   //
00149   // If an instruction which may have been fetch()ed and issue()ed
00150   // needs to be cancled, squash() allows this. The thread should
00151   // rollback any state changes caused by this instruction. An
00152   // instruction which has been commit()ed cannot be squash()ed.
00153   virtual bool squash(instruction *)=0; 
00154   //: Finish an instruction
00155   //
00156   // After an instruction has been commit()ed, it should be retire()ed
00157   // so the thread can know it has been completed and is no longer
00158   // outstanding.
00159   // 
00160   // This may fail if the thread detects and error. ex: an instruction
00161   // which was not issued from the thread was retired.
00162   virtual bool retire(instruction *)=0; 
00163   //: Acquaint a thread with a new processor
00164   //
00165   // Upon arriving (or being created) at a processor, assimilate() is
00166   // called to allows the thread to perform whatever book keeping or
00167   // resource managemnt it requires. For example, allocating a frame
00168   // and copying in data.
00169   virtual void assimilate(processor *)=0;
00170   //: Prepare a thread to be migrated
00171   //
00172   // Tells a thread to prepare for migration. This may include
00173   // deallocating frames, copying data, etc...
00174   virtual void packageToSend(processor *)=0;  
00175   //: Get InitalPC
00176   //
00177   // Get the address of the instruction where execution should start
00178   // (or resetart, after a thread migration say)
00179   virtual simAddress getStartPC()=0;
00180   //: Check PC validity
00181   //
00182   // See if a given address contains a valid instruction. Useful for
00183   // checking after branch prediction.
00184   virtual bool isPCValid(const simAddress)=0;
00185   //: Get instruction at given address
00186   //
00187   // Request an instruction at the given address from the thread. This
00188   // is required by back ends which may predict branches.
00189   virtual instruction* getNextInstruction(const simAddress)=0;
00190   //: Squash speculative state
00191   //
00192   // A processor may begin speculating down a 'wrong' path. After it
00193   // wishes to stop this speculation, it calls squashSpec() to dump
00194   // any changes to state that the "wrong" path may have performed.
00195   virtual void squashSpec()=0;
00196   //: Prepare speculative state
00197   //
00198   // A processor may begin speculating down a 'wrong' path. When it
00199   // begins to do so (say, after a branch mispredict) it calls
00200   // prepareSpec() so the thread can initialize a special speculative
00201   // state area which will be dumped eventually.
00202   virtual void prepareSpec()=0;
00203   //: Get process ID
00204   virtual simPID pid() const =0;
00205   //: Set process ID
00206   virtual void changePid(const simPID) =0;
00207   //: return instruction size in bytes
00208   // Required for some branch predictors.
00209   virtual int getInstructionSize()=0;
00210 
00211   //: Return Stack location
00212   //
00213   // Optional for threads to implement. Default returns 0.
00214   virtual simRegister getStack() const {return 0;}
00215 
00216   //: Returns if a given address is constant
00217   //
00218   // If a given region of memory is determined to be constant (i.e.
00219   // cstring sections).
00220   virtual bool isConstSection(const simAddress, const simPID) const {return 0;}
00221 
00222   //: squash an instruction but keep it around.
00223   //
00224   // This performs the actions of a squash, but does not yet reclaim
00225   // the instruction data structure. This allows an instruction which
00226   // we know will be squashed to be removed from any internal thread
00227   // structures, but still keep the instruction data structure active
00228   // and valid (i.e. it is not recycled).
00229   virtual bool condemn(instruction *)=0;
00230 };
00231 
00232 #endif 

Generated on Fri Oct 22 2010 11:02:22 for SST by  doxygen 1.7.1