User Manual, Developers Guide and API Documentation

RealTime.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2007
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 16, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <WNS/events/scheduler/RealTime.hpp>
00029 #include <sys/time.h>
00030 
00031 using namespace wns::events::scheduler;
00032 
00033 STATIC_FACTORY_REGISTER(
00034     RealTime,
00035     Interface,
00036     "wns.events.scheduler.RealTime");
00037 
00038 RealTime::RealTime() :
00039     Map(),
00040     timeOfSchedulerStart_(),
00041     inSync_(true)
00042 {
00043 }
00044 
00045 RealTime::~RealTime()
00046 {
00047 }
00048 
00049 void
00050 RealTime::onNewSimTime(const wns::simulator::Time& nextTime)
00051 {
00052     timeval currentTime;
00053 
00054     double d_delay = nextTime;
00055     d_delay += RealTime::timevalToDouble(&timeOfSchedulerStart_);
00056 
00057     gettimeofday(&currentTime, NULL);
00058     d_delay -= RealTime::timevalToDouble(&currentTime);
00059 
00060 
00061     // wait
00062     if (d_delay > 0)
00063     {
00064         // we are in sync again!
00065         if (!inSync_)
00066         {
00067             std::cout << "RealTime scheduler is in sync again.\n";
00068             inSync_ = true;
00069         }
00070 
00071         // compute from double to timeval (needed for select statement)
00072         timespec delay;
00073         delay.tv_sec = static_cast<time_t>(d_delay);
00074         delay.tv_nsec = static_cast<long>((d_delay-delay.tv_sec)*1E9);
00075 
00076         // this causes the scheduler to wait
00077         /* from "man nanosleep"
00078 
00079         The current implementation of nanosleep() is
00080         based on the normal kernel timer mechanism,
00081         which has a resolution of 1/HZ s (see time(7)).
00082         Therefore, nanosleep() pauses always for at
00083         least the specified time, however it can take up
00084         to 10 ms longer than specified until the process
00085         becomes runnable again. For the same reason, the
00086         value returned in case of a delivered signal in
00087         *rem is usually rounded to the next larger
00088         multiple of 1/HZ s.
00089         */
00090         nanosleep(&delay, NULL);
00091     }
00092     // lagging
00093     else
00094     {
00095         // if lagging more than 10 ms show a warning
00096         if(d_delay < -0.010 && inSync_)
00097         {
00098             std::cout << "Warning: RealTime scheduler lagging more than 10 ms.\n";
00099             inSync_ = false;
00100         }
00101     }
00102 }
00103 
00104 void
00105 RealTime::doReset()
00106 {
00107     inSync_ = true;
00108     Map::doReset();
00109 }
00110 
00111 void
00112 RealTime::doStart()
00113 {
00114     gettimeofday(&timeOfSchedulerStart_, NULL);
00115     Map::doStart();
00116 }
00117 
00118 
00119 double
00120 RealTime::timevalToDouble(const timeval* t)
00121 {
00122     return static_cast<double>(t->tv_sec) + static_cast<double>(t->tv_usec)/1E6;
00123 }

Generated on Fri May 25 03:31:38 2012 for openWNS by  doxygen 1.5.5