00001 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 00002 /* 00003 * Copyright (c) 2005,2006 INRIA 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation; 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 * 00018 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> 00019 */ 00020 00021 #include "simulator.h" 00022 #include "default-simulator-impl.h" 00023 #include "scheduler.h" 00024 #include "event-impl.h" 00025 00026 #include "ns3/ptr.h" 00027 #include "ns3/pointer.h" 00028 #include "ns3/assert.h" 00029 #include "ns3/log.h" 00030 00031 #include <math.h> 00032 00033 NS_LOG_COMPONENT_DEFINE ("DefaultSimulatorImpl"); 00034 00035 namespace ns3 { 00036 00037 NS_OBJECT_ENSURE_REGISTERED (DefaultSimulatorImpl); 00038 00039 TypeId 00040 DefaultSimulatorImpl::GetTypeId (void) 00041 { 00042 static TypeId tid = TypeId ("ns3::DefaultSimulatorImpl") 00043 .SetParent<Object> () 00044 .AddConstructor<DefaultSimulatorImpl> () 00045 ; 00046 return tid; 00047 } 00048 00049 DefaultSimulatorImpl::DefaultSimulatorImpl () 00050 { 00051 m_stop = false; 00052 // uids are allocated from 4. 00053 // uid 0 is "invalid" events 00054 // uid 1 is "now" events 00055 // uid 2 is "destroy" events 00056 m_uid = 4; 00057 // before ::Run is entered, the m_currentUid will be zero 00058 m_currentUid = 0; 00059 m_currentTs = 0; 00060 m_unscheduledEvents = 0; 00061 } 00062 00063 DefaultSimulatorImpl::~DefaultSimulatorImpl () 00064 { 00065 while (!m_events->IsEmpty ()) 00066 { 00067 Scheduler::Event next = m_events->RemoveNext (); 00068 next.impl->Unref (); 00069 } 00070 m_events = 0; 00071 } 00072 00073 void 00074 DefaultSimulatorImpl::Destroy () 00075 { 00076 while (!m_destroyEvents.empty ()) 00077 { 00078 Ptr<EventImpl> ev = m_destroyEvents.front ().PeekEventImpl (); 00079 m_destroyEvents.pop_front (); 00080 NS_LOG_LOGIC ("handle destroy " << ev); 00081 if (!ev->IsCancelled ()) 00082 { 00083 ev->Invoke (); 00084 } 00085 } 00086 } 00087 00088 void 00089 DefaultSimulatorImpl::SetScheduler (Ptr<Scheduler> scheduler) 00090 { 00091 if (m_events != 0) 00092 { 00093 while (!m_events->IsEmpty ()) 00094 { 00095 Scheduler::Event next = m_events->RemoveNext (); 00096 scheduler->Insert (next); 00097 } 00098 } 00099 m_events = scheduler; 00100 } 00101 00102 Ptr<Scheduler> 00103 DefaultSimulatorImpl::GetScheduler (void) const 00104 { 00105 return m_events; 00106 } 00107 00108 00109 void 00110 DefaultSimulatorImpl::ProcessOneEvent (void) 00111 { 00112 Scheduler::Event next = m_events->RemoveNext (); 00113 00114 NS_ASSERT (next.key.m_ts >= m_currentTs); 00115 --m_unscheduledEvents; 00116 00117 NS_LOG_LOGIC ("handle " << next.key.m_ts); 00118 m_currentTs = next.key.m_ts; 00119 m_currentUid = next.key.m_uid; 00120 next.impl->Invoke (); 00121 next.impl->Unref (); 00122 } 00123 00124 bool 00125 DefaultSimulatorImpl::IsFinished (void) const 00126 { 00127 return m_events->IsEmpty (); 00128 } 00129 00130 uint64_t 00131 DefaultSimulatorImpl::NextTs (void) const 00132 { 00133 NS_ASSERT (!m_events->IsEmpty ()); 00134 Scheduler::Event ev = m_events->PeekNext (); 00135 return ev.key.m_ts; 00136 } 00137 00138 Time 00139 DefaultSimulatorImpl::Next (void) const 00140 { 00141 return TimeStep (NextTs ()); 00142 } 00143 00144 void 00145 DefaultSimulatorImpl::Run (void) 00146 { 00147 m_stop = false; 00148 while (!m_events->IsEmpty () && !m_stop) 00149 { 00150 ProcessOneEvent (); 00151 } 00152 00153 // If the simulator stopped naturally by lack of events, make a 00154 // consistency test to check that we didn't lose any events along the way. 00155 NS_ASSERT(!m_events->IsEmpty () || m_unscheduledEvents == 0); 00156 } 00157 00158 void 00159 DefaultSimulatorImpl::RunOneEvent (void) 00160 { 00161 ProcessOneEvent (); 00162 } 00163 00164 void 00165 DefaultSimulatorImpl::Stop (void) 00166 { 00167 m_stop = true; 00168 } 00169 00170 00171 // 00172 // Schedule an event for a _relative_ time in the future. 00173 // 00174 EventId 00175 DefaultSimulatorImpl::Schedule (Time const &time, EventImpl *event) 00176 { 00177 Time tAbsolute = time + Now(); 00178 00179 NS_ASSERT (tAbsolute.IsPositive ()); 00180 NS_ASSERT (tAbsolute >= TimeStep (m_currentTs)); 00181 Scheduler::Event ev; 00182 ev.impl = event; 00183 ev.key.m_ts = (uint64_t) tAbsolute.GetTimeStep (); 00184 ev.key.m_uid = m_uid; 00185 m_uid++; 00186 ++m_unscheduledEvents; 00187 m_events->Insert (ev); 00188 return EventId (event, ev.key.m_ts, ev.key.m_uid); 00189 } 00190 00191 EventId 00192 DefaultSimulatorImpl::ScheduleNow (EventImpl *event) 00193 { 00194 Scheduler::Event ev; 00195 ev.impl = event; 00196 ev.key.m_ts = m_currentTs; 00197 ev.key.m_uid = m_uid; 00198 m_uid++; 00199 ++m_unscheduledEvents; 00200 m_events->Insert (ev); 00201 return EventId (event, ev.key.m_ts, ev.key.m_uid); 00202 } 00203 00204 EventId 00205 DefaultSimulatorImpl::ScheduleDestroy (EventImpl *event) 00206 { 00207 EventId id (Ptr<EventImpl> (event, false), m_currentTs, 2); 00208 m_destroyEvents.push_back (id); 00209 m_uid++; 00210 return id; 00211 } 00212 00213 Time 00214 DefaultSimulatorImpl::Now (void) const 00215 { 00216 return TimeStep (m_currentTs); 00217 } 00218 00219 Time 00220 DefaultSimulatorImpl::GetDelayLeft (const EventId &id) const 00221 { 00222 if (IsExpired (id)) 00223 { 00224 return TimeStep (0); 00225 } 00226 else 00227 { 00228 return TimeStep (id.GetTs () - m_currentTs); 00229 } 00230 } 00231 00232 void 00233 DefaultSimulatorImpl::Remove (const EventId &id) 00234 { 00235 if (id.GetUid () == 2) 00236 { 00237 // destroy events. 00238 for (DestroyEvents::iterator i = m_destroyEvents.begin (); i != m_destroyEvents.end (); i++) 00239 { 00240 if (*i == id) 00241 { 00242 m_destroyEvents.erase (i); 00243 break; 00244 } 00245 } 00246 return; 00247 } 00248 if (IsExpired (id)) 00249 { 00250 return; 00251 } 00252 Scheduler::Event event; 00253 event.impl = id.PeekEventImpl (); 00254 event.key.m_ts = id.GetTs (); 00255 event.key.m_uid = id.GetUid (); 00256 m_events->Remove (event); 00257 event.impl->Cancel (); 00258 // whenever we remove an event from the event list, we have to unref it. 00259 event.impl->Unref (); 00260 00261 --m_unscheduledEvents; 00262 } 00263 00264 void 00265 DefaultSimulatorImpl::Cancel (const EventId &id) 00266 { 00267 if (!IsExpired (id)) 00268 { 00269 id.PeekEventImpl ()->Cancel (); 00270 } 00271 } 00272 00273 bool 00274 DefaultSimulatorImpl::IsExpired (const EventId &ev) const 00275 { 00276 if (ev.GetUid () == 2) 00277 { 00278 // destroy events. 00279 for (DestroyEvents::const_iterator i = m_destroyEvents.begin (); i != m_destroyEvents.end (); i++) 00280 { 00281 if (*i == ev) 00282 { 00283 return false; 00284 } 00285 } 00286 return true; 00287 } 00288 if (ev.PeekEventImpl () == 0 || 00289 ev.GetTs () < m_currentTs || 00290 (ev.GetTs () == m_currentTs && 00291 ev.GetUid () <= m_currentUid) || 00292 ev.PeekEventImpl ()->IsCancelled ()) 00293 { 00294 return true; 00295 } 00296 else 00297 { 00298 return false; 00299 } 00300 } 00301 00302 Time 00303 DefaultSimulatorImpl::GetMaximumSimulationTime (void) const 00304 { 00305 // XXX: I am fairly certain other compilers use other non-standard 00306 // post-fixes to indicate 64 bit constants. 00307 return TimeStep (0x7fffffffffffffffLL); 00308 } 00309 00310 } // namespace ns3 00311 00312