time_stamp.cpp

Go to the documentation of this file.
00001 /*****************************************************************************\
00002 *                                                                             *
00003 *  Name   : time_stamp                                                        *
00004 *  Author : Chris Koeritz                                                     *
00005 *                                                                             *
00006 *******************************************************************************
00007 * Copyright (c) 1995-$now By Author.  This program is free software; you can  *
00008 * redistribute it and/or modify it under the terms of the GNU General Public  *
00009 * License as published by the Free Software Foundation; either version 2 of   *
00010 * the License or (at your option) any later version.  This is online at:      *
00011 *     http://www.fsf.org/copyleft/gpl.html                                    *
00012 * Please send any updates to: fred@gruntose.com                               *
00013 \*****************************************************************************/
00014 
00015 #include "earth_time.h"
00016 #include "time_stamp.h"
00017 
00018 #include <basis/environment.h>
00019 #include <basis/mutex.h>
00020 
00021 #include <stdlib.h>
00022 #ifdef __WIN32__
00023   #define _WINSOCKAPI_  // make windows.h happy about winsock.
00024 //  #include <windows.h>
00025   #include <winsock2.h>  // timeval.
00026 #endif
00027 
00028 using namespace basis;
00029 
00030 namespace timely {
00031 
00032 static mutex &__uptime_synchronizer() {
00033   static mutex uptiming_syncher;
00034   return uptiming_syncher;
00035 }
00036 
00037 basis::astring time_stamp::notarize(bool add_space)
00038 {
00039   const time_locus the_time = now();
00040   astring to_return;
00041   the_time.text_form_long(to_return, clock_time::MILITARY | clock_time::MILLISECONDS);
00042   if (add_space) to_return += " ";
00043   return to_return;
00044 }
00045 
00046 time_stamp::time_stamp() : c_stamp(0) { fill_in_time(); }
00047 
00048 time_stamp::time_stamp(time_representation offset)
00049 : c_stamp(0) { reset(offset); }
00050 
00051 void time_stamp::reset() { fill_in_time(); }
00052 
00053 astring time_stamp::text_form(stamp_display_style style) const
00054 {
00055   time_representation stump = c_stamp;
00056   bool past = false;
00057   if (style == STAMP_RELATIVE) {
00058     // adjust the returned time by subtracting the current time.
00059     stump -= get_time_now();
00060     if (negative(stump)) {
00061       // if we're negative, just note that the stamp is in the past.
00062       past = true;
00063       stump = absolute_value(stump);
00064     }
00065   }
00066   time_representation divisor = 3600 * SECOND_ms;
00067   basis::un_int hours = basis::un_int(stump / divisor);
00068   stump -= divisor * time_representation(hours);
00069   divisor /= 60;
00070   basis::un_int minutes = basis::un_int(stump / divisor);
00071   stump -= divisor * time_representation(minutes);
00072   divisor /= 60;
00073   basis::un_int seconds = basis::un_int(stump / divisor);
00074   stump -= divisor * time_representation(seconds);
00075   basis::un_int milliseconds = basis::un_int(stump);
00076   // make absolutely sure we are between 0 and 999.
00077   milliseconds %= 1000;
00078 
00079   astring to_return;
00080   bool did_hours = false;
00081   if (hours) {
00082     to_return += astring(astring::SPRINTF, "%uh:", hours);
00083     did_hours = true;
00084   }
00085   if (minutes || did_hours)
00086     to_return += astring(astring::SPRINTF, "%02um:", minutes);
00087   to_return += astring(astring::SPRINTF, "%02us.%03u", seconds, milliseconds);
00088   if (style == STAMP_RELATIVE) {
00089     if (past) to_return += " ago";
00090     else to_return += " from now";
00091   }
00092   return to_return;
00093 }
00094 
00095 void time_stamp::fill_in_time()
00096 {
00097   time_representation current = get_time_now();
00098   c_stamp = current;  // reset our own time now.
00099 }
00100 
00101 void time_stamp::reset(time_representation offset)
00102 {
00103   fill_in_time();
00104   c_stamp += offset;
00105 }
00106 
00107 time_stamp::time_representation time_stamp::get_time_now()
00108 { return rolling_uptime(); }
00109 
00110 const double __rollover_point = 2.0 * MAXINT32;
00111   // this number is our rollover point for 32 bit integers.
00112 
00113 double time_stamp::rolling_uptime()
00114 {
00115   auto_synchronizer l(__uptime_synchronizer());
00116     // protect our rollover records.
00117 
00118   static basis::un_int __last_ticks = 0;
00119   static int __rollovers = 0;
00120 
00121   basis::un_int ticks_up = environment::system_uptime();
00122     // acquire the current uptime as a 32 bit unsigned int.
00123 
00124   if (ticks_up < __last_ticks) {
00125     // rollover happened.  increment our tracker.
00126     __rollovers++;
00127   }
00128   __last_ticks = ticks_up;
00129 
00130   return double(__rollovers) * __rollover_point + double(ticks_up);
00131 }
00132 
00133 timeval time_stamp::fill_timeval_ms(int duration)
00134 {
00135   timeval time_out;  // timeval has tv_sec=seconds, tv_usec=microseconds.
00136   if (!duration) {
00137     // duration is immediate for the check; just a quick poll.
00138     time_out.tv_sec = 0;
00139     time_out.tv_usec = 0;
00140 #ifdef DEBUG_PORTABLE
00141 //    LOG("no duration specified");
00142 #endif
00143   } else {
00144     // a non-zero duration means we need to compute secs and usecs.
00145     time_out.tv_sec = duration / 1000;
00146     // set the number of seconds from the input in milliseconds.
00147     duration -= time_out.tv_sec * 1000;
00148     // now take out the chunk we've already recorded as seconds.
00149     time_out.tv_usec = duration * 1000;
00150     // set the number of microseconds from the remaining milliseconds.
00151 #ifdef DEBUG_PORTABLE
00152 //    LOG(isprintf("duration of %d ms went to %d sec and %d usec.", duration,
00153 //        time_out.tv_sec, time_out.tv_usec));
00154 #endif
00155   }
00156   return time_out;
00157 }
00158 
00159 } //namespace.
00160 
Generated on Sat Jan 28 04:22:35 2012 for hoople2 project by  doxygen 1.6.3