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

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