00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef _VPR_SIM_CONTROLLER_H_
00043 #define _VPR_SIM_CONTROLLER_H_
00044
00045 #include <vpr/vprConfig.h>
00046
00047 #include <queue>
00048 #include <utility>
00049 #include <map>
00050 #include <vpr/vprTypes.h>
00051 #include <vpr/Sync/Mutex.h>
00052 #include <vpr/Sync/Guard.h>
00053 #include <vpr/Thread/Thread.h>
00054 #include <vpr/Thread/TSObjectProxy.h>
00055
00056 #include <vpr/md/SIM/Clock.h>
00057 #include <vpr/md/SIM/SocketManager.h>
00058 #include <vpr/md/SIM/Network/NetworkGraph.h>
00059
00060
00061 namespace vpr
00062 {
00063
00064 class Interval;
00065
00066 namespace sim
00067 {
00068
00077 class VPR_CLASS_API Controller
00078 {
00079 public:
00089 Controller();
00090
00097 ~Controller()
00098 {
00099 ;
00100 }
00101
00107 static void setInstance (Controller* c)
00108 {
00109 mInstance->setObject(c);
00110 }
00111
00118 static Controller* instance()
00119 {
00120
00121
00122
00123
00124
00125 static vpr::Mutex singleton_lock;
00126
00127 if ( mInstance->getObject() == NULL )
00128 {
00129 vpr::Guard<vpr::Mutex> guard(singleton_lock);
00130
00131 if ( mPrimordialInstance == NULL )
00132 {
00133 mPrimordialInstance = new Controller;
00134 }
00135
00136 if ( mInstance->getObject() == NULL )
00137 {
00138 mInstance->setObject(mPrimordialInstance);
00139 }
00140
00141 vprASSERT(mInstance->getObject() != NULL && "No instance defined");
00142 }
00143
00144 return mInstance->getObject();
00145 }
00146
00147 vpr::ReturnStatus constructNetwork(const std::string& graph_file);
00148
00149 void destroyNetworkGraph()
00150 {
00151 mGraph.clear();
00152 }
00153
00161 bool isRunning()
00162 {
00163 vprASSERT(false && "Not supported right now. If you want it, then implement it.");
00164
00165 return false;
00166 }
00167
00172 void setSimulationPauseTime(const vpr::Uint32 sleep_time)
00173 {
00174 mSleepTime = sleep_time;
00175 }
00176
00181 void addMessageEvent(const vpr::Interval& event_time,
00182 const NetworkGraph::net_edge_t edge,
00183 const NetworkLine::LineDirection dir);
00184
00185 void addConnectionEvent(const vpr::Interval& event_time,
00186 vpr::SocketImplSIM* acceptor_sock);
00187
00188 void addConnectionCompletionEvent(const vpr::Interval& event_time,
00189 vpr::SocketImplSIM* connector_sock);
00190
00191 void addLocalhostDeliveryEvent(const vpr::Interval& event_time,
00192 vpr::SocketImplSIM* connector_sock);
00193
00198 void flushPath(const vpr::SocketImplSIM* sock,
00199 vpr::sim::NetworkGraph::VertexListPtr path);
00200
00207 void processNextEvent(vpr::SocketImplSIM** recvSocket = NULL);
00208
00217 void processEvents(const vpr::Interval& time_step);
00218
00222 vpr::Uint32 getNumPendingEvents()
00223 {
00224 return mEvents.size();
00225 }
00226
00227 const vpr::sim::Clock& getClock() const
00228 {
00229 return mClock;
00230 }
00231
00232 vpr::sim::SocketManager& getSocketManager()
00233 {
00234 return mSocketManager;
00235 }
00236
00237 vpr::sim::NetworkGraph& getNetworkGraph()
00238 {
00239 return mGraph;
00240 }
00241
00242 private:
00243 void moveMessage(vpr::sim::MessagePtr, const vpr::Interval& cur_time,
00244 vpr::SocketImplSIM** recvSocket);
00245
00246 class ControllerTS
00247 {
00248 public:
00249 ControllerTS() : mObj(NULL)
00250 {
00251 ;
00252 }
00253
00254 Controller* getObject() const
00255 {
00256 return mObj;
00257 }
00258
00259 void setObject(Controller* c)
00260 {
00261 mObj = c;
00262 }
00263
00264 private:
00265 Controller* mObj;
00266 };
00267
00268 static Controller* mPrimordialInstance;
00269 static vpr::TSObjectProxy<ControllerTS> mInstance;
00270
00271 protected:
00272
00273
00274
00275
00276 Controller(const Controller& o) {;}
00277 void operator=(const Controller& o) {;}
00278
00279 vpr::sim::Clock mClock;
00280 vpr::sim::SocketManager mSocketManager;
00281 vpr::sim::NetworkGraph mGraph;
00283 struct EventData
00284 {
00285 enum EventType
00286 {
00287 MESSAGE,
00288 CONNECTION_INIT,
00289 CONNECTION_COMPLETE,
00290 LOCALHOST_DELIVERY
00291 };
00292
00293 EventData(const NetworkGraph::net_edge_t _edge,
00294 const NetworkLine::LineDirection _dir)
00295 : type(MESSAGE), edge(_edge), direction(_dir)
00296 {
00297 ;
00298 }
00299
00300 EventData(vpr::SocketImplSIM* sock, const EventType _type)
00301 : type(_type), socket(sock)
00302 {
00303 ;
00304 }
00305
00306 bool operator==(const EventData& obj) const
00307 {
00308 bool status = false;
00309
00310 if ( type == obj.type )
00311 {
00312
00313
00314
00315 status = (type == MESSAGE) ? (edge == obj.edge && direction == obj.direction)
00316 : (socket == obj.socket);
00317 }
00318
00319 return status;
00320 }
00321
00322 EventType type;
00323 NetworkGraph::net_edge_t edge;
00324 NetworkLine::LineDirection direction;
00325 vpr::SocketImplSIM* socket;
00326 };
00327
00328
00329
00330 typedef std::multimap<vpr::Interval, EventData> event_map_t;
00331 event_map_t mEvents;
00332
00333 vpr::Uint32 mSleepTime;
00334 };
00335
00336 }
00337
00338 }
00339
00340
00341 #endif