src/core/model/wall-clock-synchronizer.cc
changeset 11131 6a448ac28669
parent 10968 2d29fee2b7b8
child 11246 9a95c9e7c9b4
equal deleted inserted replaced
11130:3f9a0f5f0be6 11131:6a448ac28669
    14  * You should have received a copy of the GNU General Public License
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program; if not, write to the Free Software
    15  * along with this program; if not, write to the Free Software
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    17  */
    17  */
    18 
    18 
    19 #include <ctime> // for clock_getres
    19 
    20 #include <sys/time.h>
    20 #include <ctime>       // clock_t
       
    21 #include <sys/time.h>  // gettimeofday
       
    22                        // clock_getres: glibc < 2.17, link with librt
    21 
    23 
    22 #include "log.h"
    24 #include "log.h"
    23 #include "system-condition.h"
    25 #include "system-condition.h"
    24 
    26 
    25 #include "wall-clock-synchronizer.h"
    27 #include "wall-clock-synchronizer.h"
    26 
    28 
       
    29 /**
       
    30  * \file
       
    31  * \ingroup realtime
       
    32  * ns3::WallClockSynchronizer implementation.
       
    33  */
       
    34 
    27 namespace ns3 {
    35 namespace ns3 {
    28 
    36 
    29 NS_LOG_COMPONENT_DEFINE ("WallClockSynchronizer");
    37 NS_LOG_COMPONENT_DEFINE ("WallClockSynchronizer");
       
    38 
       
    39 NS_OBJECT_ENSURE_REGISTERED (WallClockSynchronizer);
       
    40 
       
    41 TypeId 
       
    42 WallClockSynchronizer::GetTypeId (void)
       
    43 {
       
    44   static TypeId tid = TypeId ("ns3::WallClockSynchronizer")
       
    45     .SetParent<Synchronizer> ()
       
    46   ;
       
    47   return tid;
       
    48 }
    30 
    49 
    31 WallClockSynchronizer::WallClockSynchronizer ()
    50 WallClockSynchronizer::WallClockSynchronizer ()
    32 {
    51 {
    33   NS_LOG_FUNCTION (this);
    52   NS_LOG_FUNCTION (this);
    34 //
    53 //
   293 
   312 
   294 bool
   313 bool
   295 WallClockSynchronizer::SpinWait (uint64_t ns)
   314 WallClockSynchronizer::SpinWait (uint64_t ns)
   296 {
   315 {
   297   NS_LOG_FUNCTION (this << ns);
   316   NS_LOG_FUNCTION (this << ns);
   298 //
       
   299 // Do a busy-wait until the normalized realtime equals the value passed in
       
   300 // or the condition variable becomes true.  The condition becomes true if
       
   301 // an outside entity (a network device receives a packet, sets the condition
       
   302 // and signals the scheduler it needs to re-evaluate).
       
   303 // 
       
   304 // We just sit here and spin, wasting CPU cycles until we get to the right
   317 // We just sit here and spin, wasting CPU cycles until we get to the right
   305 // time or are told to leave.
   318 // time or are told to leave.
   306 //
       
   307   for (;;) 
   319   for (;;) 
   308     {
   320     {
   309       if (GetNormalizedRealtime () >= ns)
   321       if (GetNormalizedRealtime () >= ns)
   310         {
   322         {
   311           return true;
   323           return true;
   321 
   333 
   322 bool
   334 bool
   323 WallClockSynchronizer::SleepWait (uint64_t ns)
   335 WallClockSynchronizer::SleepWait (uint64_t ns)
   324 {
   336 {
   325   NS_LOG_FUNCTION (this << ns);
   337   NS_LOG_FUNCTION (this << ns);
   326 //
       
   327 // Put our process to sleep for some number of nanoseconds.  Typically this
       
   328 // will be some time equal to an integral number of jiffies.  We will usually
       
   329 // follow a call to SleepWait with a call to SpinWait to get the kind of
       
   330 // accuracy we want.
       
   331 //
       
   332 // We have to have some mechanism to wake up this sleep in case an external
       
   333 // event happens that causes a schedule event in the simulator.  This newly
       
   334 // scheduled event might be before the time we are waiting until, so we have
       
   335 // to break out of both the SleepWait and the following SpinWait to go back
       
   336 // and reschedule/resynchronize taking the new event into account.  The 
       
   337 // SystemCondition we have saved in m_condition takes care of this for us.
       
   338 //
       
   339 // This call will return if the timeout expires OR if the condition is 
       
   340 // set true by a call to WallClockSynchronizer::SetCondition (true) followed
       
   341 // by a call to WallClockSynchronizer::Signal().  In either case, we are done
       
   342 // waiting.  If the timeout happened, we TimedWait returns true; if a Signal
       
   343 // happened, false.
       
   344 //
       
   345   return m_condition.TimedWait (ns);
   338   return m_condition.TimedWait (ns);
   346 }
   339 }
   347 
   340 
   348 uint64_t
   341 uint64_t
   349 WallClockSynchronizer::DriftCorrect (uint64_t nsNow, uint64_t nsDelay)
   342 WallClockSynchronizer::DriftCorrect (uint64_t nsNow, uint64_t nsDelay)