00001 #ifndef MULTITHREADSIMENGINE_H_
00002 #define MULTITHREADSIMENGINE_H_
00003
00004 #include "ThreadPool.h"
00005 #include "SimObject.h"
00006 #include "MultiThreadSpikeScheduler.h"
00007 #include "SingleThreadSimEngine.h"
00008 #include "MultiThreadAnalogMsgDispatcher.h"
00009
00010 #include <boost/thread/barrier.hpp>
00011
00013 class SimEngineAdvanceJob : public ThreadPoolJob
00014 {
00015 public :
00016
00018
00023 SimEngineAdvanceJob(SingleThreadSimEngine *eng, int numSteps);
00024
00025
00027 void setNumSteps(int nSteps);
00028
00030 virtual void start();
00031
00032
00033 protected :
00034 SingleThreadSimEngine *engine;
00035 int nSteps;
00036 };
00037
00038 class SimEngineResetJob : public ThreadPoolJob
00039 {
00040 public:
00042
00045 SimEngineResetJob(SingleThreadSimEngine *eng);
00046
00048 virtual void start();
00049
00050 protected :
00051 SingleThreadSimEngine *eng;
00052 };
00053
00054 class SimEngineInitializeJob : public ThreadPoolJob
00055 {
00056 public:
00058
00061 SimEngineInitializeJob(SingleThreadSimEngine *eng);
00062
00064 virtual void start();
00065
00066 protected :
00067 SingleThreadSimEngine *eng;
00068 };
00069
00070
00071 class CycleAdvanceJob : public ThreadPoolJob
00072 {
00073 public:
00074 CycleAdvanceJob(vector<AnalogDelayObject *> *analogDelayObjects)
00075 : analog_delay_objects(analogDelayObjects) {};
00076
00077
00078
00080
00085 virtual void start();
00086
00087 protected:
00088 vector<AnalogDelayObject *> *analog_delay_objects;
00089 };
00090
00091 class SimNetwork;
00092
00094
00103 class MultiThreadSimEngine : public SimEngine
00104 {
00105
00106 public:
00107
00109
00118 MultiThreadSimEngine(int ID,
00119 int numThreads,
00120 ThreadPool &thrPool,
00121 SpikeScheduler &scheduler,
00122 AnalogMessageDispatcherVector &analogMsgDispatchers,
00123 SimNetwork &net);
00124
00125
00126
00127 virtual ~MultiThreadSimEngine();
00128
00130 virtual void advance(int nSteps = 1);
00131
00133 virtual void reset();
00134
00136 virtual void initialize();
00137
00139 virtual void addObject( SimObjectFactory const& objFactory, SimObject::ID &id )
00140 {
00141 engines[id.eng]->addObject( objFactory, id );
00142 };
00143
00144 void addForAdvanceCycle( AnalogDelayObject *o, SimObject::ID &id)
00145 {
00146 o->setAddedForAdvanceCycle();
00147 analogDelayObjects[id.eng].push_back(o);
00148 }
00149
00150 virtual void mount( const SimObjectFactory &objFactory, const SimObject::ID &mountpoint, SimObject::ID &gid );
00151 virtual void insert( const SimObjectFactory &objFactory, const SimObject::ID &mountpoint, SimObject::ID &gid );
00152
00154 virtual SimObject *getObject(const SimObject::ID & id)
00155 {
00156 return engines[id.eng]->getObject(id);
00157 };
00158
00160 SimObjectPool* getPool(engineid_t e)
00161 {
00162 return engines[e]->getPool();
00163 }
00164
00165 void advanceSeveralStepsWithinACycle(int steps);
00166
00167 void finalizeCycle();
00168
00169 void advanceOneFullCycle();
00170
00171 SingleThreadSimEngine & getSTEngine(engineid_t eng);
00172
00173 virtual void seed( vector<uint32> const& noiseSeed );
00174 virtual void seed( uint32 noiseSeed );
00175
00176 virtual void noiseRandEngineOutput( vector<uint32> & r );
00177
00178 protected:
00179
00180 inline void two_way_link( const SimObject::ID &id1, const SimObject::ID &id2 );
00181 inline void one_way_link( const SimObject::ID &id1, const SimObject::ID &id2 );
00182
00184 int _numThreads;
00185
00187 ThreadPool &thr_pool;
00188
00190 vector<SimEngineAdvanceJob> advance_jobs;
00191
00193 vector<SimEngineResetJob> reset_jobs;
00194
00195 vector<SimEngineInitializeJob> initialize_jobs;
00196
00198 vector<SingleThreadSimEngine*> engines;
00199
00200 boost::barrier *thr_barrier;
00201
00202 vector< vector<AnalogDelayObject *> > analogDelayObjects;
00203
00204 vector< CycleAdvanceJob > mtCycleAdvanceJobs;
00205
00206 int currentStepWithinCycle;
00207
00208 } ;
00209
00210 #endif