#include <vpr/md/SIM/Controller.h>
Collaboration diagram for vpr::sim::Controller:

Public Member Functions | |
| Controller () | |
| Initializes the socket simulation. | |
| ~Controller () | |
| Resets the Sim Socket Manager's clock to 0. | |
| vpr::ReturnStatus | constructNetwork (const std::string &graph_file) |
| void | destroyNetworkGraph () |
| bool | isRunning () |
| Queries the running state of this socket simulation. | |
| void | setSimulationPauseTime (const vpr::Uint32 sleep_time) |
| Sets the amount of time (in microseconds) to sleep after processing a single event. | |
| void | addMessageEvent (const vpr::Interval &event_time, const NetworkGraph::net_edge_t edge, const NetworkLine::LineDirection dir) |
| Adds an event scheduled to occur at the given time to the queue of upcoming events. | |
| void | addConnectionEvent (const vpr::Interval &event_time, vpr::SocketImplSIM *acceptor_sock) |
| void | addConnectionCompletionEvent (const vpr::Interval &event_time, vpr::SocketImplSIM *connector_sock) |
| void | addLocalhostDeliveryEvent (const vpr::Interval &event_time, vpr::SocketImplSIM *connector_sock) |
| void | flushPath (const vpr::SocketImplSIM *sock, vpr::sim::NetworkGraph::VertexListPtr path) |
| Flushes all messages (and associated events) on the given path destined for the given socket. | |
| void | processNextEvent (vpr::SocketImplSIM **recvSocket=NULL) |
| Processes the next event in the event queue no matter how far into the (simulated) future it occurs. | |
| void | processEvents (const vpr::Interval &time_step) |
| Limits the time frame for the occurrence of the next events to the given time step. | |
| vpr::Uint32 | getNumPendingEvents () |
| Return the number of events pending in the system. | |
| const vpr::sim::Clock & | getClock () const |
| vpr::sim::SocketManager & | getSocketManager () |
| vpr::sim::NetworkGraph & | getNetworkGraph () |
Static Public Member Functions | |
| static void | setInstance (Controller *c) |
| Set the instance to be returned in this thread to the given object pointer. | |
| static Controller * | instance () |
| Returns an instance of this thread-specific singleton class. | |
Protected Types | |
| typedef std::multimap< vpr::Interval, EventData > | event_map_t |
Protected Member Functions | |
| Controller (const Controller &o) | |
| void | operator= (const Controller &o) |
Protected Attributes | |
| vpr::sim::Clock | mClock |
| The global clock that we are using. | |
| vpr::sim::SocketManager | mSocketManager |
| The socket manager that we are using. | |
| vpr::sim::NetworkGraph | mGraph |
| The network graph used for the simulation. | |
| event_map_t | mEvents |
| vpr::Uint32 | mSleepTime |
Classes | |
| class | ControllerTS |
| struct | EventData |
This is used to step through a simulation being controlled by the Sim Socket Manager. This class is a thread-specific singleton so that each running thread can have its own unique instance. It can also be used as a traditional global singleton. To use it as a thread-specific singleton, call setInstance() as the first step of a newly spawned thread. This is crucial to its functionality.
Definition at line 78 of file Controller.h.
typedef std::multimap<vpr::Interval, EventData> vpr::sim::Controller::event_map_t [protected] |
Definition at line 331 of file Controller.h.
| vpr::sim::Controller::Controller | ( | ) |
Initializes the socket simulation.
This should only be called when a thread-specific instance is needed. Otherwise, use the static instance() method to get a thread-specific or global instance depending on what is available.
Definition at line 69 of file Controller.cpp.
00070 : mSleepTime(0) 00071 { 00072 /* Do nothing. */ ; 00073 }
| vpr::sim::Controller::~Controller | ( | ) | [inline] |
Resets the Sim Socket Manager's clock to 0.
Definition at line 98 of file Controller.h.
| vpr::sim::Controller::Controller | ( | const Controller & | o | ) | [inline, protected] |
| static void vpr::sim::Controller::setInstance | ( | Controller * | c | ) | [inline, static] |
Set the instance to be returned in this thread to the given object pointer.
This should be done as the first step by all threads wishing to have a thread-specific instance of this singleton class.
Definition at line 108 of file Controller.h.
| static Controller* vpr::sim::Controller::instance | ( | ) | [inline, static] |
Returns an instance of this thread-specific singleton class.
If a thread-specific instance was set by the currently active thread using setInstance(), that instance is returned. If no instance is associated with the current thread, the primordial (global) instance is returned.
Definition at line 119 of file Controller.h.
References vprASSERT.
Referenced by vpr::SocketStreamImplSIM::accept(), vpr::sim::SocketManager::assignToNode(), vpr::SocketImplSIM::bind(), vpr::SocketImplSIM::close(), vpr::sim::SocketManager::connect(), vpr::SocketImplSIM::connect(), vpr::sim::SocketManager::ensureNetworkNodeIsRegistered(), vpr::sim::SocketManager::findRoute(), vpr::SocketStreamImplSIM::listen(), vpr::sim::SocketManager::sendMessage(), vpr::sim::SocketManager::sendMessageTo(), vpr::SocketDatagramImplSIM::sendto(), and vpr::SocketImplSIM::write_i().
00120 { 00121 // WARNING! race condition possibility, creation of static vars 00122 // are not thread safe. This is only an issue when creating 00123 // your first thread, since it uses a singleton thread manager, 00124 // the two threads might both try to call instance at the same time 00125 // which then the creation of the following mutex would not be certain. 00126 static vpr::Mutex singleton_lock; 00127 00128 if ( mInstance->getObject() == NULL ) 00129 { 00130 vpr::Guard<vpr::Mutex> guard(singleton_lock); 00131 00132 if ( mPrimordialInstance == NULL ) 00133 { 00134 mPrimordialInstance = new Controller; 00135 } 00136 00137 if ( mInstance->getObject() == NULL ) 00138 { 00139 mInstance->setObject(mPrimordialInstance); 00140 } 00141 00142 vprASSERT(mInstance->getObject() != NULL && "No instance defined"); 00143 } 00144 00145 return mInstance->getObject(); 00146 }
| vpr::ReturnStatus vpr::sim::Controller::constructNetwork | ( | const std::string & | graph_file | ) |
Definition at line 75 of file Controller.cpp.
References vpr::sim::NetworkGraph::clear(), vpr::sim::NetworkGraph::construct(), vpr::sim::NetworkGraph::isValid(), mGraph, mSocketManager, vpr::sim::SocketManager::setActive(), and vpr::ReturnStatus::success().
00076 { 00077 vpr::ReturnStatus status; 00078 00079 if ( mGraph.isValid() ) 00080 { 00081 mGraph.clear(); 00082 } 00083 00084 status = mGraph.construct(graph_file); 00085 00086 if ( status.success() ) 00087 { 00088 mSocketManager.setActive(); 00089 } 00090 00091 return status; 00092 }
| void vpr::sim::Controller::destroyNetworkGraph | ( | ) | [inline] |
| bool vpr::sim::Controller::isRunning | ( | ) | [inline] |
Queries the running state of this socket simulation.
The simulation is considered running if it has been started and if the Sim Socket Manager still has active sockets registered.
Definition at line 162 of file Controller.h.
References vprASSERT.
00163 { 00164 vprASSERT(false && "Not supported right now. If you want it, then implement it."); 00165 //return mGraph.isValid() && mSocketManager.hasActiveSockets(); 00166 return false; 00167 }
| void vpr::sim::Controller::setSimulationPauseTime | ( | const vpr::Uint32 | sleep_time | ) | [inline] |
Sets the amount of time (in microseconds) to sleep after processing a single event.
Definition at line 173 of file Controller.h.
00174 { 00175 mSleepTime = sleep_time; 00176 }
| void vpr::sim::Controller::addMessageEvent | ( | const vpr::Interval & | event_time, | |
| const NetworkGraph::net_edge_t | edge, | |||
| const NetworkLine::LineDirection | dir | |||
| ) |
Adds an event scheduled to occur at the given time to the queue of upcoming events.
Definition at line 94 of file Controller.cpp.
References vpr::Interval::getBaseVal(), mEvents, vprDBG_HVERB_LVL, vprDBG_SIM(), vprDEBUG, and vprDEBUG_FLUSH.
Referenced by vpr::sim::SocketManager::sendMessage().
00097 { 00098 vprDEBUG(vprDBG_SIM, vprDBG_HVERB_LVL) 00099 << "Controller::addMessageEvent(): Adding message event scheduled for time " 00100 << event_time.getBaseVal() << " on edge " << edge << "\n" 00101 << vprDEBUG_FLUSH; 00102 mEvents.insert(std::pair<vpr::Interval, EventData>(event_time, EventData(edge, dir))); 00103 }
| void vpr::sim::Controller::addConnectionEvent | ( | const vpr::Interval & | event_time, | |
| vpr::SocketImplSIM * | acceptor_sock | |||
| ) |
Definition at line 105 of file Controller.cpp.
References vpr::sim::Controller::EventData::CONNECTION_INIT, vpr::Interval::getBaseVal(), mEvents, vprDBG_HVERB_LVL, vprDBG_SIM(), vprDEBUG, and vprDEBUG_FLUSH.
00107 { 00108 vprDEBUG(vprDBG_SIM, vprDBG_HVERB_LVL) 00109 << "Controller::addConnectionEvent(): Adding connection request event scheduled for time " 00110 << event_time.getBaseVal() << "\n" << vprDEBUG_FLUSH; 00111 mEvents.insert(std::pair<vpr::Interval, EventData>(event_time, EventData(acceptor_sock, EventData::CONNECTION_INIT))); 00112 }
| void vpr::sim::Controller::addConnectionCompletionEvent | ( | const vpr::Interval & | event_time, | |
| vpr::SocketImplSIM * | connector_sock | |||
| ) |
Definition at line 114 of file Controller.cpp.
References vpr::sim::Controller::EventData::CONNECTION_COMPLETE, vpr::Interval::getBaseVal(), mEvents, vprDBG_HVERB_LVL, vprDBG_SIM(), vprDEBUG, and vprDEBUG_FLUSH.
Referenced by vpr::SocketStreamImplSIM::accept().
00116 { 00117 vprDEBUG(vprDBG_SIM, vprDBG_HVERB_LVL) 00118 << "Controller::addConnectionCompletionEvent(): Adding connection " 00119 << "completion event scheduled for time " << event_time.getBaseVal() 00120 << "\n" << vprDEBUG_FLUSH; 00121 mEvents.insert(std::pair<vpr::Interval, EventData>(event_time, EventData(connector_sock, EventData::CONNECTION_COMPLETE))); 00122 }
| void vpr::sim::Controller::addLocalhostDeliveryEvent | ( | const vpr::Interval & | event_time, | |
| vpr::SocketImplSIM * | connector_sock | |||
| ) |
Definition at line 124 of file Controller.cpp.
References vpr::Interval::getBaseVal(), vpr::sim::Controller::EventData::LOCALHOST_DELIVERY, mEvents, vprDBG_HVERB_LVL, vprDBG_SIM(), vprDEBUG, and vprDEBUG_FLUSH.
Referenced by vpr::sim::SocketManager::sendMessage().
00126 { 00127 vprDEBUG(vprDBG_SIM, vprDBG_HVERB_LVL) 00128 << "Controller::addConnectionCompletionEvent(): Adding localhost " 00129 << "delivery event scheduled for time " << event_time.getBaseVal() 00130 << "\n" << vprDEBUG_FLUSH; 00131 mEvents.insert(std::pair<vpr::Interval, EventData>(event_time, EventData(connector_sock, EventData::LOCALHOST_DELIVERY))); 00132 }
| void vpr::sim::Controller::flushPath | ( | const vpr::SocketImplSIM * | sock, | |
| vpr::sim::NetworkGraph::VertexListPtr | path | |||
| ) |
Flushes all messages (and associated events) on the given path destined for the given socket.
Definition at line 134 of file Controller.cpp.
References vpr::sim::NetworkLine::FORWARD, vpr::sim::NetworkGraph::getEdge(), vpr::sim::NetworkGraph::getLineProperty(), vpr::sim::NetworkGraph::isSource(), mEvents, mGraph, vpr::sim::NetworkLine::removeActiveMessages(), vpr::sim::NetworkLine::REVERSE, vprDBG_SIM(), vprDBG_STATE_LVL, vprDBG_VERB_LVL, vprDEBUG, and vprDEBUG_FLUSH.
00136 { 00137 vpr::DebugOutputGuard dbg_output(vprDBG_SIM, vprDBG_STATE_LVL, 00138 std::string("Controller::flushPath()\n"), 00139 std::string("End of Controller::flushPath()\n")); 00140 00141 vpr::sim::NetworkGraph::VertexList::iterator source, dest; 00142 vpr::sim::NetworkGraph::net_edge_t current_line; 00143 bool got_next_line; 00144 00145 source = dest = path->begin(); 00146 ++dest; 00147 00148 for ( ; dest != path->end(); ++dest ) 00149 { 00150 boost::tie(current_line, got_next_line) = mGraph.getEdge(*source, *dest); 00151 00152 if ( got_next_line ) 00153 { 00154 vprDEBUG(vprDBG_SIM, vprDBG_STATE_LVL) 00155 << "Controller::flushPath(): Working on line " << current_line 00156 << std::endl << vprDEBUG_FLUSH; 00157 00158 vpr::sim::NetworkLine& line_prop = mGraph.getLineProperty(current_line); 00159 vpr::sim::NetworkLine::LineDirection dir; 00160 std::vector<vpr::Interval> event_times; 00161 00162 dir = mGraph.isSource(*source, current_line) ? NetworkLine::FORWARD 00163 : NetworkLine::REVERSE; 00164 00165 vprDEBUG(vprDBG_SIM, vprDBG_VERB_LVL) 00166 << "Controller::flushPath(): Removing active messages on line " 00167 << current_line << " in the " 00168 << ((dir == NetworkLine::FORWARD) ? "forward" : "reverse") 00169 << " queue\n" << vprDEBUG_FLUSH; 00170 00171 line_prop.removeActiveMessages(sock, event_times, dir); 00172 00173 // If the event_times vector has elements in it, these specify the 00174 // times at which flushed messages were scheduled to arrive. We must 00175 // remove these events from the mEvents container. 00176 if ( ! event_times.empty() ) 00177 { 00178 EventData test_event(current_line, dir); // Message event 00179 event_map_t::iterator event_iter, end_iter; 00180 00181 // For each of the scheduled event times, look up all the events 00182 // in the event container with that time and find the one that 00183 // matches the message flushed from the line above. 00184 for ( std::vector<vpr::Interval>::iterator i = event_times.begin(); 00185 i != event_times.end(); 00186 ++i ) 00187 { 00188 vprDEBUG(vprDBG_SIM, vprDBG_STATE_LVL) 00189 << "Controller::flushPath(): Looking for events scheduled to occur at " 00190 << (*i).getBaseVal() << std::endl << vprDEBUG_FLUSH; 00191 00192 boost::tie(event_iter, end_iter) = mEvents.equal_range(*i); 00193 00194 // XXX: I'm not sure if std::remove_if() can be used here 00195 // because mEvents is currently an associative container. 00196 for ( ; event_iter != end_iter; ++event_iter ) 00197 { 00198 if ( test_event == (*event_iter).second ) 00199 { 00200 vprDEBUG(vprDBG_SIM, vprDBG_VERB_LVL) 00201 << "Controller::flushPath(): Removing event\n" 00202 << vprDEBUG_FLUSH; 00203 mEvents.erase(event_iter); 00204 } 00205 } 00206 } 00207 } 00208 } 00209 00210 // Finally, move the source to point to the current destination. The 00211 // destination will be incremented as part of the for loop's 00212 // iteration. 00213 source = dest; 00214 } 00215 }
| void vpr::sim::Controller::processNextEvent | ( | vpr::SocketImplSIM ** | recvSocket = NULL |
) |
Processes the next event in the event queue no matter how far into the (simulated) future it occurs.
If there is an event in the queue, it will be processed by this method.
| recvSocket | The socket that recv'ed the event (NULL if none) |
Definition at line 217 of file Controller.cpp.
References vpr::sim::Controller::EventData::CONNECTION_COMPLETE, vpr::sim::Controller::EventData::CONNECTION_INIT, vpr::sim::NetworkLine::FORWARD, vpr::sim::NetworkLine::getArrivedMessage(), vpr::Interval::getBaseVal(), vpr::sim::Clock::getCurrentTime(), vpr::sim::NetworkGraph::getLineProperty(), vpr::sim::NetworkLine::getNetworkAddressString(), mClock, vpr::sim::Controller::EventData::MESSAGE, mEvents, mGraph, mSleepTime, vpr::sim::Clock::setCurrentTime(), vpr::ReturnStatus::success(), vpr::SystemPosix::usleep(), vprASSERT, vprDBG_HVERB_LVL, vprDBG_SIM(), vprDBG_STATE_LVL, vprDBG_VERB_LVL, vprDEBUG, and vprDEBUG_FLUSH.
Referenced by processEvents().
00218 { 00219 vpr::DebugOutputGuard dbg_output(vprDBG_SIM, vprDBG_STATE_LVL, 00220 std::string("Controller::processNextEvent()\n"), 00221 std::string("End of Controller::processNextEvent()\n")); 00222 00223 if ( recvSocket != NULL ) 00224 { 00225 (*recvSocket) = NULL; 00226 } 00227 00228 event_map_t::iterator cur_event = mEvents.begin(); 00229 00230 if ( cur_event != mEvents.end() ) 00231 { 00232 vpr::Interval event_time = (*cur_event).first; 00233 00234 vprDEBUG(vprDBG_SIM, vprDBG_VERB_LVL) 00235 << "Controller::processNextEvent() [time = " 00236 << mClock.getCurrentTime().getBaseVal() 00237 << "]: Processing event scheduled to occur at time " 00238 << event_time.getBaseVal() << " (moving clock forward)\n" 00239 << vprDEBUG_FLUSH; 00240 00241 mClock.setCurrentTime(event_time); 00242 00243 if ( (*cur_event).second.type == EventData::MESSAGE ) 00244 { 00245 NetworkGraph::net_edge_t event_edge = (*cur_event).second.edge; 00246 NetworkLine::LineDirection dir = (*cur_event).second.direction; 00247 vpr::sim::NetworkLine& line = mGraph.getLineProperty(event_edge); 00248 vpr::sim::MessagePtr msg; 00249 vpr::ReturnStatus status; 00250 00251 // ------------------------------------------------------------------- 00252 // Process event in the line's transmission queue. 00253 // ------------------------------------------------------------------- 00254 00255 status = line.getArrivedMessage(event_time, msg, dir); 00256 vprASSERT(status.success() && "No arrived message at this time"); 00257 00258 vprDEBUG(vprDBG_SIM, vprDBG_HVERB_LVL) 00259 << "Controller::processNextEvent(): Event is the arrival of a message for " 00260 << msg->getDestinationSocket()->getLocalAddr() << " on " 00261 << ((dir == vpr::sim::NetworkLine::FORWARD) ? "forward" : "reverse") 00262 << " queue of line " << line.getNetworkAddressString() << "\n" 00263 << vprDEBUG_FLUSH; 00264 00265 moveMessage(msg, event_time, recvSocket); 00266 } 00267 else if ( (*cur_event).second.type == EventData::CONNECTION_COMPLETE ) 00268 { 00269 vprDEBUG(vprDBG_SIM, vprDBG_HVERB_LVL) 00270 << "Controller::processNextEvent(): Event is a connection completion for " 00271 << (*cur_event).second.socket->getLocalAddr() << "\n" 00272 << vprDEBUG_FLUSH; 00273 00274 if ( recvSocket != NULL ) 00275 { 00276 *recvSocket = (*cur_event).second.socket; 00277 } 00278 } 00279 else if ( (*cur_event).second.type == EventData::CONNECTION_INIT ) 00280 { 00281 vprDEBUG(vprDBG_SIM, vprDBG_HVERB_LVL) 00282 << "Controller::processNextEvent(): Event is a connection request to " 00283 << (*cur_event).second.socket->getLocalAddr() << "\n" 00284 << vprDEBUG_FLUSH; 00285 00286 if ( recvSocket != NULL ) 00287 { 00288 *recvSocket = (*cur_event).second.socket; 00289 } 00290 } 00291 else 00292 { 00293 vprDEBUG(vprDBG_SIM, vprDBG_HVERB_LVL) 00294 << "Controller::processNextEvent(): Event is a localhost message delivery to " 00295 << (*cur_event).second.socket->getLocalAddr() << "\n" 00296 << vprDEBUG_FLUSH; 00297 00298 if ( recvSocket != NULL ) 00299 { 00300 *recvSocket = (*cur_event).second.socket; 00301 } 00302 } 00303 00304 mEvents.erase(cur_event); 00305 00306 if ( mSleepTime != 0 ) 00307 { 00308 vpr::System::usleep(mSleepTime); 00309 } 00310 } 00311 }
| void vpr::sim::Controller::processEvents | ( | const vpr::Interval & | time_step | ) |
Limits the time frame for the occurrence of the next events to the given time step.
There may not be an event in the queue that occurs between the current time and the time step, and in that case, no event will be processed.
| time_step | The maximum time step allowed for the simulation. |
Definition at line 313 of file Controller.cpp.
References vpr::Interval::getBaseVal(), vpr::sim::Clock::getCurrentTime(), mClock, mEvents, processNextEvent(), vpr::sim::Clock::setCurrentTime(), vprDBG_SIM(), vprDBG_STATE_LVL, vprDBG_VERB_LVL, vprDEBUG, and vprDEBUG_FLUSH.
00314 { 00315 vpr::DebugOutputGuard dbg_output(vprDBG_SIM, vprDBG_STATE_LVL, 00316 std::string("Controller::processEvents()\n"), 00317 std::string("End of Controller::processEvents()\n")); 00318 00319 vpr::SocketImplSIM* recv_sock; 00320 vpr::Interval event_time = mClock.getCurrentTime() + time_step; 00321 event_map_t::iterator next_event; 00322 00323 vprDEBUG(vprDBG_SIM, vprDBG_VERB_LVL) 00324 << "Controller::processEvents [time = " 00325 << mClock.getCurrentTime().getBaseVal() << "]: Moving clock ahead " 00326 << time_step.getBaseVal() << " units to be " << event_time.getBaseVal() 00327 << std::endl << vprDEBUG_FLUSH; 00328 00329 mClock.setCurrentTime(event_time); 00330 00331 // The current time based on the time step is the same as or greater than 00332 // the time of the next event in the queue. That means that that event is 00333 // eligible for processing. 00334 while ( (next_event = mEvents.begin()) != mEvents.end() && 00335 (*next_event).first <= event_time ) 00336 { 00337 processNextEvent(&recv_sock); 00338 } 00339 }
| vpr::Uint32 vpr::sim::Controller::getNumPendingEvents | ( | ) | [inline] |
Return the number of events pending in the system.
Definition at line 223 of file Controller.h.
00224 { 00225 return mEvents.size(); 00226 }
| const vpr::sim::Clock& vpr::sim::Controller::getClock | ( | ) | const [inline] |
Definition at line 228 of file Controller.h.
Referenced by vpr::SocketStreamImplSIM::accept(), and vpr::sim::SocketManager::sendMessage().
00229 { 00230 return mClock; 00231 }
| vpr::sim::SocketManager& vpr::sim::Controller::getSocketManager | ( | ) | [inline] |
Definition at line 233 of file Controller.h.
Referenced by vpr::SocketStreamImplSIM::accept().
00234 { 00235 return mSocketManager; 00236 }
| vpr::sim::NetworkGraph& vpr::sim::Controller::getNetworkGraph | ( | ) | [inline] |
Definition at line 238 of file Controller.h.
Referenced by vpr::sim::SocketManager::assignToNode(), vpr::sim::SocketManager::connect(), vpr::sim::SocketManager::ensureNetworkNodeIsRegistered(), vpr::sim::SocketManager::findRoute(), vpr::sim::SocketManager::sendMessage(), and vpr::sim::SocketManager::sendMessageTo().
00239 { 00240 return mGraph; 00241 }
| void vpr::sim::Controller::operator= | ( | const Controller & | o | ) | [inline, protected] |
vpr::sim::Clock vpr::sim::Controller::mClock [protected] |
The global clock that we are using.
Definition at line 280 of file Controller.h.
Referenced by processEvents(), and processNextEvent().
The socket manager that we are using.
Definition at line 281 of file Controller.h.
Referenced by constructNetwork().
vpr::sim::NetworkGraph vpr::sim::Controller::mGraph [protected] |
The network graph used for the simulation.
Definition at line 282 of file Controller.h.
Referenced by constructNetwork(), flushPath(), and processNextEvent().
event_map_t vpr::sim::Controller::mEvents [protected] |
Definition at line 332 of file Controller.h.
Referenced by addConnectionCompletionEvent(), addConnectionEvent(), addLocalhostDeliveryEvent(), addMessageEvent(), flushPath(), processEvents(), and processNextEvent().
vpr::Uint32 vpr::sim::Controller::mSleepTime [protected] |
1.5.1