Fixed typos
[ACE_TAO.git] / ACE / ace / Time_Value.cpp
blob77c151e135cf4609f9c736e8b6c5c7f7cb16e299
1 #include "ace/Time_Value.h"
3 #if defined (ACE_HAS_ALLOC_HOOKS)
4 # include "ace/Malloc_Base.h"
5 #endif /* ACE_HAS_ALLOC_HOOKS */
7 #if !defined (__ACE_INLINE__)
8 #include "ace/Time_Value.inl"
9 #endif /* __ACE_INLINE__ */
11 #include "ace/Numeric_Limits.h"
12 #include "ace/If_Then_Else.h"
13 #include "ace/OS_NS_math.h"
14 #include "ace/Time_Policy.h"
16 #ifdef ACE_HAS_CPP98_IOSTREAMS
17 # include <ostream>
18 # include <iomanip>
19 #endif /* ACE_HAS_CPP98_IOSTREAMS */
21 #include <cstdlib>
23 #ifdef ACE_HAS_CPP11
24 # include <cmath>
25 #endif /* ACE_HAS_CPP11 */
27 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
29 /// Static constant representing `zero-time'.
30 /// Note: this object requires static construction.
31 const ACE_Time_Value ACE_Time_Value::zero;
33 /// Constant for maximum time representable. Note that this time
34 /// is not intended for use with select () or other calls that may
35 /// have *their own* implementation-specific maximum time representations.
36 /// Its primary use is in time computations such as those used by the
37 /// dynamic subpriority strategies in the ACE_Dynamic_Message_Queue class.
38 /// Note: this object requires static construction.
39 const ACE_Time_Value ACE_Time_Value::max_time (
40 ACE_Numeric_Limits<time_t>::max (),
41 ACE_ONE_SECOND_IN_USECS - 1);
43 ACE_ALLOC_HOOK_DEFINE (ACE_Time_Value)
45 ACE_Time_Value::~ACE_Time_Value()
48 /// Increment microseconds (the only reason this is here is to allow
49 /// the use of ACE_Atomic_Op with ACE_Time_Value).
50 ACE_Time_Value
51 ACE_Time_Value::operator ++ (int)
53 // ACE_OS_TRACE ("ACE_Time_Value::operator ++ (int)");
54 ACE_Time_Value tv (*this);
55 ++*this;
56 return tv;
59 ACE_Time_Value &
60 ACE_Time_Value::operator ++ (void)
62 // ACE_OS_TRACE ("ACE_Time_Value::operator ++ (void)");
63 this->usec (this->usec () + 1);
64 this->normalize ();
65 return *this;
68 /// Decrement microseconds (the only reason this is here is / to allow
69 /// the use of ACE_Atomic_Op with ACE_Time_Value).
70 ACE_Time_Value
71 ACE_Time_Value::operator -- (int)
73 // ACE_OS_TRACE ("ACE_Time_Value::operator -- (int)");
74 ACE_Time_Value tv (*this);
75 --*this;
76 return tv;
79 ACE_Time_Value &
80 ACE_Time_Value::operator -- (void)
82 // ACE_OS_TRACE ("ACE_Time_Value::operator -- (void)");
83 this->usec (this->usec () - 1);
84 this->normalize ();
85 return *this;
88 #if defined (ACE_WIN32)
89 /// Static constant to remove time skew between FILETIME and POSIX
90 /// time. POSIX and Win32 use different epochs (Jan. 1, 1970 v.s.
91 /// Jan. 1, 1601). The following constant defines the difference
92 /// in 100ns ticks.
93 ///
94 /// In the beginning (Jan. 1, 1601), there was no time and no computer.
95 /// And Bill said: "Let there be time," and there was time....
96 const DWORDLONG ACE_Time_Value::FILETIME_to_timval_skew =
97 ACE_INT64_LITERAL (0x19db1ded53e8000);
99 /// Initializes the ACE_Time_Value object from a Win32 FILETIME
100 ACE_Time_Value::ACE_Time_Value (const FILETIME &file_time)
102 // // ACE_OS_TRACE ("ACE_Time_Value::ACE_Time_Value");
103 this->set (file_time);
106 void ACE_Time_Value::set (const FILETIME &file_time)
108 // Initializes the ACE_Time_Value object from a Win32 FILETIME
109 // Don't use a struct initializer, gcc don't like it.
110 ULARGE_INTEGER _100ns;
111 _100ns.LowPart = file_time.dwLowDateTime;
112 _100ns.HighPart = file_time.dwHighDateTime;
114 _100ns.QuadPart -= ACE_Time_Value::FILETIME_to_timval_skew;
116 // Convert 100ns units to seconds;
117 this->tv_.tv_sec = (time_t) (_100ns.QuadPart / (10000 * 1000));
118 // Convert remainder to microseconds;
119 this->tv_.tv_usec = (suseconds_t) ((_100ns.QuadPart % (10000 * 1000)) / 10);
121 this->normalize ();
124 /// Returns the value of the object as a Win32 FILETIME.
125 ACE_Time_Value::operator FILETIME () const
127 FILETIME file_time;
128 // ACE_OS_TRACE ("ACE_Time_Value::operator FILETIME");
130 ULARGE_INTEGER _100ns;
131 _100ns.QuadPart = (((DWORDLONG) this->tv_.tv_sec * (10000 * 1000) +
132 this->tv_.tv_usec * 10) +
133 ACE_Time_Value::FILETIME_to_timval_skew);
135 file_time.dwLowDateTime = _100ns.LowPart;
136 file_time.dwHighDateTime = _100ns.HighPart;
138 return file_time;
140 #endif /* ACE_WIN32 */
142 ACE_Time_Value
143 ACE_Time_Value::now () const
145 ACE_System_Time_Policy systp;
146 return systp ();
149 ACE_Time_Value
150 ACE_Time_Value::to_relative_time () const
152 ACE_System_Time_Policy systp;
153 return (*this) - systp ();
156 ACE_Time_Value
157 ACE_Time_Value::to_absolute_time () const
159 ACE_System_Time_Policy systp;
160 return (*this) + systp ();
163 ACE_Time_Value *
164 ACE_Time_Value::duplicate () const
166 ACE_Time_Value * tmp = 0;
167 ACE_NEW_RETURN (tmp, ACE_Time_Value (*this), 0);
168 return tmp;
171 void
172 ACE_Time_Value::dump (void) const
176 void
177 ACE_Time_Value::normalize (bool saturate)
179 // ACE_OS_TRACE ("ACE_Time_Value::normalize");
180 if (this->tv_.tv_usec >= ACE_ONE_SECOND_IN_USECS ||
181 this->tv_.tv_usec <= -ACE_ONE_SECOND_IN_USECS)
183 time_t const sec = std::abs(this->tv_.tv_usec) / ACE_ONE_SECOND_IN_USECS * (this->tv_.tv_usec > 0 ? 1 : -1);
184 suseconds_t const usec = static_cast<suseconds_t> (this->tv_.tv_usec - sec * ACE_ONE_SECOND_IN_USECS);
186 if (saturate && this->tv_.tv_sec > 0 && sec > 0 &&
187 ACE_Numeric_Limits<time_t>::max() - this->tv_.tv_sec < sec)
189 this->tv_.tv_sec = ACE_Numeric_Limits<time_t>::max();
190 this->tv_.tv_usec = ACE_ONE_SECOND_IN_USECS - 1;
192 else if (saturate && this->tv_.tv_sec < 0 && sec < 0 &&
193 ACE_Numeric_Limits<time_t>::min() - this->tv_.tv_sec > sec)
195 this->tv_.tv_sec = ACE_Numeric_Limits<time_t>::min();
196 this->tv_.tv_usec = -ACE_ONE_SECOND_IN_USECS + 1;
198 else
200 this->tv_.tv_sec += sec;
201 this->tv_.tv_usec = usec;
205 if (this->tv_.tv_sec >= 1 && this->tv_.tv_usec < 0)
207 --this->tv_.tv_sec;
208 this->tv_.tv_usec += ACE_ONE_SECOND_IN_USECS;
210 // tv_sec in qnxnto is unsigned
211 #if !defined ( __QNX__)
212 else if (this->tv_.tv_sec < 0 && this->tv_.tv_usec > 0)
214 ++this->tv_.tv_sec;
215 this->tv_.tv_usec -= ACE_ONE_SECOND_IN_USECS;
217 #endif /* __QNX__ */
221 ACE_Time_Value &
222 ACE_Time_Value::operator *= (double d)
224 // To work around the lack of precision of a long double to contain
225 // a 64-bits time_t + 6 digits after the decimal point for the usec part,
226 // we perform the multiplication of the 2 timeval parts separately.
228 // This extra precision step is adding a cost when transfering the
229 // seconds resulting from the usec multiplication. This operation
230 // correspond to the normalization process performed in normalize()
231 // but we must absolutly do it here because the usec multiplication
232 // result value could exceed what can be stored in a suseconds_t
233 // type variable.
235 // Since this is a costly operation, we try to detect as soon as
236 // possible if we are having a saturation in order to abort the rest
237 // of the computation.
238 typedef ACE::If_Then_Else<(sizeof (double) > sizeof (time_t)),
239 double,
240 long double>::result_type float_type;
242 float_type sec_total = static_cast<float_type> (this->sec());
243 sec_total *= d;
245 // shall we saturate the result?
246 static const float_type max_int =
247 ACE_Numeric_Limits<time_t>::max() + 0.999999;
248 static const float_type min_int =
249 ACE_Numeric_Limits<time_t>::min() - 0.999999;
251 if (sec_total > max_int)
253 this->set(ACE_Numeric_Limits<time_t>::max(), ACE_ONE_SECOND_IN_USECS-1);
255 else if (sec_total < min_int)
257 this->set(ACE_Numeric_Limits<time_t>::min(), -ACE_ONE_SECOND_IN_USECS+1);
259 else
261 time_t time_sec = static_cast<time_t> (sec_total);
263 float_type usec_total = this->usec();
264 usec_total *= d;
266 // adding usec resulting from tv_sec mult
267 usec_total += (sec_total-time_sec) * ACE_ONE_SECOND_IN_USECS;
269 // extract seconds component of the usec mult
270 sec_total = usec_total / ACE_ONE_SECOND_IN_USECS;
271 // keep remaining usec
272 if (sec_total > 0)
274 usec_total = (sec_total - ACE_OS::floor(sec_total));
276 else
278 usec_total = (sec_total - ACE_OS::ceil(sec_total));
281 sec_total -= usec_total;
282 usec_total *= ACE_ONE_SECOND_IN_USECS;
284 // add the seconds component of the usec mult with the tv_sec mult prod.
285 sec_total += time_sec;
287 // recheck for saturation
288 if (sec_total > max_int)
290 this->set (ACE_Numeric_Limits<time_t>::max(), ACE_ONE_SECOND_IN_USECS - 1);
292 else if (sec_total < min_int)
294 this->set (ACE_Numeric_Limits<time_t>::min(), -ACE_ONE_SECOND_IN_USECS + 1);
296 else
298 time_sec = static_cast<time_t> (sec_total);
299 suseconds_t time_usec = static_cast<suseconds_t> (usec_total);
301 // round up the result to save the last usec
302 if (time_usec > 0 && (usec_total - time_usec) >= 0.5)
304 ++time_usec;
306 else if (time_usec < 0 && (usec_total - time_usec) <= -0.5)
308 --time_usec;
311 this->set (time_sec, time_usec);
314 return *this;
317 #ifdef ACE_HAS_CPP98_IOSTREAMS
318 ostream &operator<<(ostream &o, const ACE_Time_Value &v)
320 char const oldFiller = o.fill ();
321 o.fill ('0');
322 const timeval *tv = v;
323 if (tv->tv_sec)
325 o << tv->tv_sec;
326 if (tv->tv_usec)
327 #ifdef ACE_HAS_CPP11
328 o << '.' << std::setw (6) << std::labs (tv->tv_usec);
329 #else
330 o << '.' << std::setw (6) << ACE_STD_NAMESPACE::labs (tv->tv_usec);
331 #endif
333 else if (tv->tv_usec < 0)
334 o << "-0." << std::setw (6) << - tv->tv_usec;
335 else
337 o << '0';
338 if (tv->tv_usec > 0)
339 o << '.'<< std::setw (6) << tv->tv_usec;
342 o.fill (oldFiller);
343 return o;
345 #endif /* ACE_HAS_CPP98_IOSTREAMS */
347 ACE_END_VERSIONED_NAMESPACE_DECL