![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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(¤tTime, NULL); 00058 d_delay -= RealTime::timevalToDouble(¤tTime); 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 }
1.5.5