feisty meow concerns codebase  2.140
time_stamp.cpp
Go to the documentation of this file.
1 /*****************************************************************************\
2 * *
3 * Name : time_stamp *
4 * Author : Chris Koeritz *
5 * *
6 *******************************************************************************
7 * Copyright (c) 1995-$now By Author. This program is free software; you can *
8 * redistribute it and/or modify it under the terms of the GNU General Public *
9 * License as published by the Free Software Foundation; either version 2 of *
10 * the License or (at your option) any later version. This is online at: *
11 * http://www.fsf.org/copyleft/gpl.html *
12 * Please send any updates to: fred@gruntose.com *
13 \*****************************************************************************/
14 
15 #include "earth_time.h"
16 #include "time_stamp.h"
17 
19 #include <basis/environment.h>
20 #include <basis/mutex.h>
22 
23 #include <stdlib.h>
24 //#ifdef __WIN32__
25 // #define _WINSOCKAPI_ // make windows.h happy about winsock.
26 // #include <winsock2.h> // timeval.
27 //#endif
28 
29 //#define DEBUG_TIME_STAMP
30 
31 #ifdef DEBUG_TIME_STAMP
32  #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
33  using namespace loggers;
34 #endif
35 
36 using namespace basis;
37 
38 namespace timely {
39 
40 static mutex &__uptime_synchronizer() {
41  static mutex uptiming_syncher;
42  return uptiming_syncher;
43 }
44 
45 basis::astring time_stamp::notarize(bool add_space)
46 {
47  const time_locus the_time = now();
48  astring to_return;
49  the_time.text_form_long(to_return, clock_time::MILITARY | clock_time::MILLISECONDS);
50  if (add_space) to_return += " ";
51  return to_return;
52 }
53 
54 time_stamp::time_stamp() : c_stamp(0) { fill_in_time(); }
55 
57 : c_stamp(0) { reset(offset); }
58 
59 void time_stamp::reset() { fill_in_time(); }
60 
62 {
63  time_representation stump = c_stamp;
64  bool past = false;
65  if (style == STAMP_RELATIVE) {
66  // adjust the returned time by subtracting the current time.
67  stump -= get_time_now();
68  if (negative(stump)) {
69  // if we're negative, just note that the stamp is in the past.
70  past = true;
71  stump = absolute_value(stump);
72  }
73  }
74  time_representation divisor = 3600 * SECOND_ms;
75  basis::un_int hours = basis::un_int(stump / divisor);
76  stump -= divisor * time_representation(hours);
77  divisor /= 60;
78  basis::un_int minutes = basis::un_int(stump / divisor);
79  stump -= divisor * time_representation(minutes);
80  divisor /= 60;
81  basis::un_int seconds = basis::un_int(stump / divisor);
82  stump -= divisor * time_representation(seconds);
83  basis::un_int milliseconds = basis::un_int(stump);
84  // make absolutely sure we are between 0 and 999.
85  milliseconds %= 1000;
86 
87  astring to_return;
88  bool did_hours = false;
89  if (hours) {
90  to_return += astring(astring::SPRINTF, "%uh:", hours);
91  did_hours = true;
92  }
93  if (minutes || did_hours)
94  to_return += astring(astring::SPRINTF, "%02um:", minutes);
95  to_return += astring(astring::SPRINTF, "%02us.%03u", seconds, milliseconds);
96  if (style == STAMP_RELATIVE) {
97  if (past) to_return += " ago";
98  else to_return += " from now";
99  }
100  return to_return;
101 }
102 
103 void time_stamp::fill_in_time()
104 {
105  time_representation current = get_time_now();
106  c_stamp = current; // reset our own time now.
107 }
108 
110 {
111  fill_in_time();
112  c_stamp += offset;
113 }
114 
115 time_stamp::time_representation time_stamp::get_time_now()
116 { return rolling_uptime(); }
117 
118 const double __rollover_point = 2.0 * MAXINT32;
119  // this number is our rollover point for 32 bit integers.
120 
122 {
123  auto_synchronizer l(__uptime_synchronizer());
124  // protect our rollover records.
125 
126  static basis::un_int __last_ticks = 0;
127  static int __rollovers = 0;
128 
129  basis::un_int ticks_up = environment::system_uptime();
130  // acquire the current uptime as a 32 bit unsigned int.
131 
132  if (ticks_up < __last_ticks) {
133  // rollover happened. increment our tracker.
134  __rollovers++;
135  }
136  __last_ticks = ticks_up;
137 
138  return double(__rollovers) * __rollover_point + double(ticks_up);
139 }
140 
141 void time_stamp::fill_timeval_ms(struct timeval &time_out, int duration)
142 {
143  FUNCDEF("fill_timeval_ms");
144  // timeval has tv_sec=seconds, tv_usec=microseconds.
145  if (!duration) {
146  // duration is immediate for the check; just a quick poll.
147  time_out.tv_sec = 0;
148  time_out.tv_usec = 0;
149 #ifdef DEBUG_TIME_STAMP
150  LOG("no duration specified");
151 #endif
152  } else {
153  // a non-zero duration means we need to compute secs and usecs.
154  time_out.tv_sec = duration / 1000;
155  // set the number of seconds from the input in milliseconds.
156  duration -= time_out.tv_sec * 1000;
157  // now take out the chunk we've already recorded as seconds.
158  time_out.tv_usec = duration * 1000;
159  // set the number of microseconds from the remaining milliseconds.
160 #ifdef DEBUG_TIME_STAMP
161  LOG(a_sprintf("duration of %d ms went to %d sec and %d usec.", duration,
162  time_out.tv_sec, time_out.tv_usec));
163 #endif
164  }
165 }
166 
167 } //namespace.
168 
#define LOG(s)
a_sprintf is a specialization of astring that provides printf style support.
Definition: astring.h:440
Provides a dynamically resizable ASCII character string.
Definition: astring.h:35
auto_synchronizer simplifies concurrent code by automatically unlocking.
Definition: mutex.h:113
An object that represents a particular point in time.
Definition: earth_time.h:188
basis::astring text_form_long(int t=clock_time::MERIDIAN, int d=day_in_year::SHORT_MONTH, int y=LONG_YEAR) const
Definition: earth_time.cpp:262
basis::astring text_form(stamp_display_style style=STAMP_RELATIVE) const
returns a simple textual representation of the time_stamp.
Definition: time_stamp.cpp:61
void reset()
sets the stamp time back to now.
Definition: time_stamp.cpp:59
static double rolling_uptime()
give the OS uptime in a more durable form that handles rollovers.
Definition: time_stamp.cpp:121
time_stamp()
creates a time_stamp containing the current time.
Definition: time_stamp.cpp:54
double time_representation
the representation of time for this universe, measured in milliseconds.
Definition: time_stamp.h:42
static void fill_timeval_ms(timeval &time_point, int milliseconds)
returns a timeval system object that represents the "milliseconds".
Definition: time_stamp.cpp:141
#define MAXINT32
Maximum 32-bit integer value.
Definition: definitions.h:75
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Definition: enhance_cpp.h:57
The guards collection helps in testing preconditions and reporting errors.
Definition: array.h:30
const int SECOND_ms
Number of milliseconds in a second.
Definition: definitions.h:120
unsigned int un_int
Abbreviated name for unsigned integers.
Definition: definitions.h:62
bool negative(const type &a)
negative returns true if "a" is less than zero.
Definition: functions.h:43
type absolute_value(type a)
Returns a if a is non-negative, and returns -a otherwise.
Definition: functions.h:33
A logger that sends to the console screen using the standard output device.
#include <time.h>
Definition: earth_time.cpp:37
time_locus now()
returns our current locus in the time continuum.
Definition: earth_time.cpp:352
const double __rollover_point
Definition: time_stamp.cpp:118
Aids in achievement of platform independence.