Savarese Software Research Corporation
TimeValue.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2006-2008 Savarese Software Research Corporation
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.savarese.com/software/ApacheLicense-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00022 #ifndef __SSRC_WISP_UTILITY_TIME_VALUE_H
00023 #define __SSRC_WISP_UTILITY_TIME_VALUE_H
00024 
00025 #include <ssrc/wisp-packages.h>
00026 
00027 #include <cstdint>
00028 #include <stdexcept>
00029 #include <ctime>
00030 #include <time.h>
00031 
00032 #if defined(WISP_HAVE_MACH_CLOCK_H)
00033 #include <mach/mach_host.h>
00034 #include <mach/clock.h>
00035 #endif
00036 
00037 #include <boost/integer_traits.hpp>
00038 
00039 __BEGIN_NS_SSRC_WISP_UTILITY
00040 
00041 #define __WISP_BILLION 1000000000
00042 
00043 class TimeValue {
00044   timespec _time;
00045 
00046 
00047 #ifdef WISP_HAVE_CLOCK_GETTIME
00048   static int gettime(::clockid_t clk_id, timespec *tp) {
00049     return ::clock_gettime(clk_id, tp);
00050   }
00051 #elif defined(WISP_HAVE_CLOCK_GET_TIME)
00052   static int gettime(::clock_id_t clk_id, timespec *tp) {
00053     ::clock_serv_t clock_serv;
00054     ::mach_timespec_t mtp;
00055     int result = -1;
00056 
00057     if((::host_get_clock_service(mach_host_self(), clk_id, &clock_serv) ==
00058         KERN_SUCCESS))
00059     {
00060       if(::clock_get_time(clock_serv, &mtp) == KERN_SUCCESS) {
00061         tp->tv_sec  = mtp.tv_sec;
00062         tp->tv_nsec = mtp.tv_nsec;
00063         result = 0;
00064       }
00065     }
00066     return result;
00067   }
00068 #else
00069 # error "System does not implement POSIX clock_gettime or MACH clock_get_time."
00070 #endif
00071 
00072 public:
00073   typedef std::int64_t ms_type;
00074   typedef time_t sec_type;
00075   typedef long nsec_type;
00076   typedef boost::integer_traits<sec_type> sec_type_traits;
00077 
00078   static sec_type now_seconds() {
00079     return std::time(0);
00080   }
00081 
00082   static TimeValue time() {
00083     return TimeValue().now();
00084   }
00085 
00086   TimeValue() {
00087     _time.tv_sec = _time.tv_nsec = 0;
00088   }
00089 
00090   TimeValue(const sec_type seconds,
00091             const nsec_type nanoseconds)
00092     SSRC_DECL_THROW(std::invalid_argument)
00093   {
00094     if(seconds < 0 || nanoseconds < 0)
00095       throw std::invalid_argument("negative time");
00096 
00097     if(nanoseconds >= __WISP_BILLION) {
00098       _time.tv_sec = seconds + nanoseconds / __WISP_BILLION;
00099       _time.tv_nsec = nanoseconds %  __WISP_BILLION;
00100     } else {
00101       _time.tv_sec  = seconds;
00102       _time.tv_nsec = nanoseconds;
00103     }
00104   }
00105 
00106   explicit TimeValue(const ms_type millisec) {
00107     _time.tv_sec = millisec / 1000;
00108     _time.tv_nsec = (millisec % 1000) * 1000000;
00109   }
00110 
00111   TimeValue & now() {
00112 #ifdef WISP_HAVE_CLOCK_GETTIME
00113     gettime(CLOCK_REALTIME, &_time);
00114 #elif defined(WISP_HAVE_CLOCK_GET_TIME)
00115     gettime(CALENDAR_CLOCK, &_time);
00116 #endif
00117     return *this;
00118   }
00119 
00120   TimeValue & now_mono() {
00121 #ifdef WISP_HAVE_CLOCK_GETTIME
00122     gettime(CLOCK_MONOTONIC, &_time);
00123 #elif defined(WISP_HAVE_CLOCK_GET_TIME)
00124     gettime(SYSTEM_CLOCK, &_time);
00125 #endif
00126     return *this;
00127   }
00128 
00129   ms_type to_milliseconds() const {
00130     return (static_cast<ms_type>(_time.tv_sec)*1000 + 
00131             (_time.tv_nsec + 999999)/1000000);
00132   }
00133 
00134   sec_type seconds() const throw () {
00135     return _time.tv_sec;
00136   }
00137 
00138   nsec_type nanoseconds() const throw () {
00139     return _time.tv_nsec;
00140   }
00141 
00142   TimeValue & operator+=(const TimeValue & t2) {
00143     _time.tv_sec+=t2._time.tv_sec;
00144     _time.tv_nsec+=t2._time.tv_nsec;
00145 
00146     if(_time.tv_nsec >= __WISP_BILLION) {
00147       ++_time.tv_sec;
00148       _time.tv_nsec-=__WISP_BILLION;
00149     }
00150 
00151     return *this;
00152   }
00153 
00154   TimeValue & operator-=(const TimeValue & t2) {
00155     _time.tv_sec-=t2._time.tv_sec;
00156     _time.tv_nsec-=t2._time.tv_nsec;
00157 
00158     if(_time.tv_nsec < 0) {
00159       --_time.tv_sec;
00160       _time.tv_nsec+=__WISP_BILLION;
00161     }
00162 
00163     return *this;
00164   }
00165 
00166   friend bool operator==(const TimeValue & t1, const TimeValue & t2) {
00167     return (t1._time.tv_sec == t2._time.tv_sec &&
00168             t1._time.tv_nsec == t2._time.tv_nsec);
00169   }
00170 
00171   friend bool operator<(const TimeValue & t1, const TimeValue & t2) {
00172     return (t1._time.tv_sec < t2._time.tv_sec ||
00173             (t1._time.tv_sec == t2._time.tv_sec &&
00174              t1._time.tv_nsec < t2._time.tv_nsec));
00175   }
00176 
00177   template<class Archive>
00178   void serialize(Archive & ar, const unsigned int) {
00179     ar & _time.tv_sec & _time.tv_nsec;
00180   }
00181 };
00182 
00183 inline TimeValue operator-(const TimeValue & t1, const TimeValue & t2) {
00184   TimeValue result(t1);
00185   return (result-=t2);
00186 }
00187 
00188 inline TimeValue operator+(const TimeValue & t1, const TimeValue & t2) {
00189   TimeValue result(t1);
00190   return (result+=t2);
00191 }
00192 
00193 const TimeValue InfiniteTimeValue =
00194   TimeValue(TimeValue::sec_type_traits::const_max, 0);
00195 
00196 #undef __WISP_BILLION
00197 
00198 __END_NS_SSRC_WISP_UTILITY
00199 
00200 #endif

Savarese Software Research Corporation
Copyright © 2006-2010 Savarese Software Research Corporation. All rights reserved.