00001 // $Id: ClockService.cci 1742 2010-11-04 14:51:56Z g0dil $ 00002 // 00003 // Copyright (C) 2007 00004 // Fraunhofer (FOKUS) 00005 // Competence Center NETwork research (NET), St. Augustin, GERMANY 00006 // Stefan Bund <g0dil@berlios.de> 00007 // 00008 // This program is free software; you can redistribute it and/or modify 00009 // it under the terms of the GNU General Public License as published by 00010 // the Free Software Foundation; either version 2 of the License, or 00011 // (at your option) any later version. 00012 // 00013 // This program is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 // GNU General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU General Public License 00019 // along with this program; if not, write to the 00020 // Free Software Foundation, Inc., 00021 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00022 00026 // Custom includes 00027 #include <time.h> 00028 #include <boost/date_time/posix_time/posix_time_types.hpp> 00029 #include <senf/Utils/Exception.hh> 00030 00031 #define prefix_ inline 00032 //-///////////////////////////////////////////////////////////////////////////////////////////////// 00033 00034 //-///////////////////////////////////////////////////////////////////////////////////////////////// 00035 // senf::ClockService 00036 00037 prefix_ senf::ClockService::clock_type senf::ClockService::now() 00038 { 00039 struct timespec spec; 00040 if (clock_gettime(CLOCK_MONOTONIC, &spec) < 0) 00041 SENF_THROW_SYSTEM_EXCEPTION("clock_gettime()"); 00042 return spec.tv_sec * 1000000000LL + spec.tv_nsec; 00043 } 00044 00045 //-///////////////////////////////////////////////////////////////////////////////////////////////// 00046 // private members 00047 00048 namespace senf { namespace scheduler { ClockService::clock_type now(); } } 00049 00050 prefix_ senf::ClockService::clock_type senf::ClockService::clock_m(abstime_type time) 00051 { 00052 if (scheduler::now() - baseClock_ > 1000000000ll) 00053 restart_m(); 00054 boost::posix_time::time_duration delta (time - baseAbstime_); 00055 return baseClock_ + clock_type( delta.ticks() ) 00056 * clock_type( 1000000000UL / boost::posix_time::time_duration::ticks_per_second() ); 00057 } 00058 00059 prefix_ senf::ClockService::abstime_type senf::ClockService::abstime_m(clock_type clock) 00060 { 00061 if (clock == 0) 00062 return abstime_type(); 00063 if (scheduler::now() - baseClock_ > 1000000000ll) 00064 restart_m(); 00065 #ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG 00066 return baseAbstime_ + boost::posix_time::nanoseconds(clock-baseClock_); 00067 #else 00068 return baseAbstime_ + boost::posix_time::microseconds((clock-baseClock_+500)/1000); 00069 #endif 00070 } 00071 00072 prefix_ senf::ClockService::ClockService() 00073 { 00074 restart_m(); 00075 } 00076 00077 prefix_ void senf::ClockService::restart_m() 00078 { 00079 baseAbstime_ = boost::posix_time::microsec_clock::universal_time(); 00080 baseClock_ = now(); 00081 } 00082 00083 // public members 00084 00085 prefix_ senf::ClockService::abstime_type senf::ClockService::abstime(clock_type clock) 00086 { 00087 return instance().abstime_m(clock); 00088 } 00089 00090 prefix_ senf::ClockService::reltime_type senf::ClockService::reltime(clock_type clock) 00091 { 00092 #ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG 00093 return boost::posix_time::nanoseconds(clock); 00094 #else 00095 return boost::posix_time::microseconds((clock+500)/1000); 00096 #endif 00097 } 00098 00099 prefix_ senf::ClockService::clock_type senf::ClockService::clock(abstime_type time) 00100 { 00101 return instance().clock_m(time); 00102 } 00103 00104 prefix_ senf::ClockService::clock_type senf::ClockService::from_time_t(time_t const & time) 00105 { 00106 return clock( boost::posix_time::from_time_t(time) ); 00107 } 00108 00109 prefix_ senf::ClockService::clock_type senf::ClockService::nanoseconds(int64_type v) 00110 { 00111 return v; 00112 } 00113 00114 prefix_ senf::ClockService::clock_type senf::ClockService::microseconds(int64_type v) 00115 { 00116 return v * nanoseconds(1000); 00117 } 00118 00119 prefix_ senf::ClockService::clock_type senf::ClockService::milliseconds(int64_type v) 00120 { 00121 return v * microseconds(1000); 00122 } 00123 00124 prefix_ senf::ClockService::clock_type senf::ClockService::seconds(int64_type v) 00125 { 00126 return v * milliseconds(1000); 00127 } 00128 00129 prefix_ senf::ClockService::clock_type senf::ClockService::minutes(int64_type v) 00130 { 00131 return v * seconds(60); 00132 } 00133 00134 prefix_ senf::ClockService::clock_type senf::ClockService::hours(int64_type v) 00135 { 00136 return v * minutes(60); 00137 } 00138 00139 prefix_ senf::ClockService::clock_type senf::ClockService::days(int64_type v) 00140 { 00141 return v * hours(24); 00142 } 00143 00144 prefix_ senf::ClockService::clock_type senf::ClockService::in_nanoseconds(int64_type v) 00145 { 00146 return v; 00147 } 00148 00149 prefix_ senf::ClockService::clock_type senf::ClockService::in_microseconds(int64_type v) 00150 { 00151 return v / nanoseconds(1000); 00152 } 00153 00154 prefix_ senf::ClockService::clock_type senf::ClockService::in_milliseconds(int64_type v) 00155 { 00156 return v / microseconds(1000); 00157 } 00158 00159 prefix_ senf::ClockService::clock_type senf::ClockService::in_seconds(int64_type v) 00160 { 00161 return v / milliseconds(1000); 00162 } 00163 00164 prefix_ senf::ClockService::clock_type senf::ClockService::in_minutes(int64_type v) 00165 { 00166 return v / seconds(60); 00167 } 00168 00169 prefix_ senf::ClockService::clock_type senf::ClockService::in_hours(int64_type v) 00170 { 00171 return v / minutes(60); 00172 } 00173 00174 prefix_ senf::ClockService::clock_type senf::ClockService::in_days(int64_type v) 00175 { 00176 return v / hours(24); 00177 } 00178 00179 prefix_ senf::ClockService::clock_type senf::ClockService::from_timeval(timeval const & time) 00180 { 00181 return from_time_t(time.tv_sec) + microseconds(time.tv_usec); 00182 } 00183 00184 prefix_ void senf::ClockService::restart() 00185 { 00186 instance().restart_m(); 00187 } 00188 00189 //-///////////////////////////////////////////////////////////////////////////////////////////////// 00190 #undef prefix_ 00191 00192 00193 // Local Variables: 00194 // mode: c++ 00195 // fill-column: 100 00196 // comment-column: 40 00197 // c-file-style: "senf" 00198 // indent-tabs-mode: nil 00199 // ispell-local-dictionary: "american" 00200 // compile-command: "scons -u test" 00201 // End: