3 Copyright (c) 2007, Arvid Norberg
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the distribution.
15 * Neither the name of the author nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
33 #ifndef TORRENT_TIME_HPP_INCLUDED
34 #define TORRENT_TIME_HPP_INCLUDED
37 #include <boost/version.hpp>
45 inline char const* time_now_string()
47 time_t t
= std::time(0);
48 tm
* timeinfo
= std::localtime(&t
);
50 std::strftime(str
, 200, "%b %d %X", timeinfo
);
54 std::string
log_time();
57 #if (!defined (__MACH__) && !defined (_WIN32) && (!defined(_POSIX_MONOTONIC_CLOCK) \
58 || _POSIX_MONOTONIC_CLOCK < 0)) || defined (TORRENT_USE_BOOST_DATE_TIME)
60 #include <boost/date_time/posix_time/posix_time_types.hpp>
61 #include "libtorrent/assert.hpp"
65 typedef boost::posix_time::ptime ptime
;
66 typedef boost::posix_time::time_duration time_duration
;
67 inline ptime
time_now()
68 { return boost::posix_time::microsec_clock::universal_time(); }
69 inline ptime
min_time()
70 { return boost::posix_time::ptime(boost::posix_time::min_date_time
); }
71 inline ptime
max_time()
72 { return boost::posix_time::ptime(boost::posix_time::max_date_time
); }
73 inline time_duration
seconds(int s
) { return boost::posix_time::seconds(s
); }
74 inline time_duration
milliseconds(int s
) { return boost::posix_time::milliseconds(s
); }
75 inline time_duration
microsec(int s
) { return boost::posix_time::microsec(s
); }
76 inline time_duration
minutes(int s
) { return boost::posix_time::minutes(s
); }
77 inline time_duration
hours(int s
) { return boost::posix_time::hours(s
); }
79 inline int total_seconds(time_duration td
)
80 { return td
.total_seconds(); }
81 inline int total_milliseconds(time_duration td
)
82 { return td
.total_milliseconds(); }
83 inline boost::int64_t total_microseconds(time_duration td
)
84 { return td
.total_microseconds(); }
90 #if BOOST_VERSION < 103500
91 #include <asio/time_traits.hpp>
93 #include <boost/asio/time_traits.hpp>
95 #include <boost/cstdint.hpp>
96 #include "libtorrent/assert.hpp"
100 // libtorrent time_duration type
104 time_duration
operator/(int rhs
) const { return time_duration(diff
/ rhs
); }
105 explicit time_duration(boost::int64_t d
) : diff(d
) {}
106 time_duration
& operator-=(time_duration
const& c
) { diff
-= c
.diff
; return *this; }
107 time_duration
& operator+=(time_duration
const& c
) { diff
+= c
.diff
; return *this; }
108 time_duration
operator+(time_duration
const& c
) { return time_duration(diff
+ c
.diff
); }
112 inline bool is_negative(time_duration dt
) { return dt
.diff
< 0; }
113 inline bool operator<(time_duration lhs
, time_duration rhs
)
114 { return lhs
.diff
< rhs
.diff
; }
115 inline bool operator<=(time_duration lhs
, time_duration rhs
)
116 { return lhs
.diff
<= rhs
.diff
; }
117 inline bool operator>(time_duration lhs
, time_duration rhs
)
118 { return lhs
.diff
> rhs
.diff
; }
119 inline bool operator>=(time_duration lhs
, time_duration rhs
)
120 { return lhs
.diff
>= rhs
.diff
; }
122 // libtorrent time type
126 explicit ptime(boost::int64_t t
): time(t
) {}
127 ptime
& operator+=(time_duration rhs
) { time
+= rhs
.diff
; return *this; }
128 ptime
& operator-=(time_duration rhs
) { time
-= rhs
.diff
; return *this; }
132 inline bool operator>(ptime lhs
, ptime rhs
)
133 { return lhs
.time
> rhs
.time
; }
134 inline bool operator>=(ptime lhs
, ptime rhs
)
135 { return lhs
.time
>= rhs
.time
; }
136 inline bool operator<=(ptime lhs
, ptime rhs
)
137 { return lhs
.time
<= rhs
.time
; }
138 inline bool operator<(ptime lhs
, ptime rhs
)
139 { return lhs
.time
< rhs
.time
; }
140 inline bool operator!=(ptime lhs
, ptime rhs
)
141 { return lhs
.time
!= rhs
.time
;}
142 inline bool operator==(ptime lhs
, ptime rhs
)
143 { return lhs
.time
== rhs
.time
;}
144 inline time_duration
operator-(ptime lhs
, ptime rhs
)
145 { return time_duration(lhs
.time
- rhs
.time
); }
146 inline ptime
operator+(ptime lhs
, time_duration rhs
)
147 { return ptime(lhs
.time
+ rhs
.diff
); }
148 inline ptime
operator+(time_duration lhs
, ptime rhs
)
149 { return ptime(rhs
.time
+ lhs
.diff
); }
150 inline ptime
operator-(ptime lhs
, time_duration rhs
)
151 { return ptime(lhs
.time
- rhs
.diff
); }
154 inline ptime
min_time() { return ptime(0); }
155 inline ptime
max_time() { return ptime((std::numeric_limits
<boost::int64_t>::max
)()); }
156 int total_seconds(time_duration td
);
157 int total_milliseconds(time_duration td
);
158 boost::int64_t total_microseconds(time_duration td
);
162 #if BOOST_VERSION >= 103500
168 struct time_traits
<libtorrent::ptime
>
170 typedef libtorrent::ptime time_type
;
171 typedef libtorrent::time_duration duration_type
;
172 static time_type
now()
173 { return time_type(libtorrent::time_now()); }
174 static time_type
add(time_type t
, duration_type d
)
175 { return time_type(t
.time
+ d
.diff
);}
176 static duration_type
subtract(time_type t1
, time_type t2
)
177 { return duration_type(t1
- t2
); }
178 static bool less_than(time_type t1
, time_type t2
)
180 static boost::posix_time::time_duration
to_posix_duration(
182 { return boost::posix_time::microseconds(libtorrent::total_microseconds(d
)); }
185 #if BOOST_VERSION >= 103500
189 #if defined(__MACH__)
191 #include <mach/mach_time.h>
192 #include <boost/cstdint.hpp>
193 #include "libtorrent/assert.hpp"
195 // high precision timer for darwin intel and ppc
201 inline boost::int64_t absolutetime_to_microseconds(boost::int64_t at
)
203 static mach_timebase_info_data_t timebase_info
= {0,0};
204 if (timebase_info
.denom
== 0)
205 mach_timebase_info(&timebase_info
);
206 // make sure we don't overflow
207 TORRENT_ASSERT((at
>= 0 && at
>= at
/ 1000 * timebase_info
.numer
/ timebase_info
.denom
)
208 || (at
< 0 && at
< at
/ 1000 * timebase_info
.numer
/ timebase_info
.denom
));
209 return at
/ 1000 * timebase_info
.numer
/ timebase_info
.denom
;
212 inline boost::int64_t microseconds_to_absolutetime(boost::int64_t ms
)
214 static mach_timebase_info_data_t timebase_info
= {0,0};
215 if (timebase_info
.denom
== 0)
217 mach_timebase_info(&timebase_info
);
218 TORRENT_ASSERT(timebase_info
.numer
> 0);
219 TORRENT_ASSERT(timebase_info
.denom
> 0);
221 // make sure we don't overflow
222 TORRENT_ASSERT((ms
>= 0 && ms
<= ms
* timebase_info
.denom
/ timebase_info
.numer
* 1000)
223 || (ms
< 0 && ms
> ms
* timebase_info
.denom
/ timebase_info
.numer
* 1000));
224 return ms
* timebase_info
.denom
/ timebase_info
.numer
* 1000;
228 inline int total_seconds(time_duration td
)
230 return aux::absolutetime_to_microseconds(td
.diff
)
233 inline int total_milliseconds(time_duration td
)
235 return aux::absolutetime_to_microseconds(td
.diff
)
238 inline boost::int64_t total_microseconds(time_duration td
)
240 return aux::absolutetime_to_microseconds(td
.diff
);
243 inline ptime
time_now() { return ptime(mach_absolute_time()); }
245 inline time_duration
microsec(boost::int64_t s
)
247 return time_duration(aux::microseconds_to_absolutetime(s
));
249 inline time_duration
milliseconds(boost::int64_t s
)
251 return time_duration(aux::microseconds_to_absolutetime(s
* 1000));
253 inline time_duration
seconds(boost::int64_t s
)
255 return time_duration(aux::microseconds_to_absolutetime(s
* 1000000));
257 inline time_duration
minutes(boost::int64_t s
)
259 return time_duration(aux::microseconds_to_absolutetime(s
* 1000000 * 60));
261 inline time_duration
hours(boost::int64_t s
)
263 return time_duration(aux::microseconds_to_absolutetime(s
* 1000000 * 60 * 60));
267 #elif defined(_WIN32)
269 #ifndef WIN32_LEAN_AND_MEAN
270 #define WIN32_LEAN_AND_MEAN
273 #include "libtorrent/assert.hpp"
279 inline boost::int64_t performance_counter_to_microseconds(boost::int64_t pc
)
281 static LARGE_INTEGER performace_counter_frequency
= {0,0};
282 if (performace_counter_frequency
.QuadPart
== 0)
283 QueryPerformanceFrequency(&performace_counter_frequency
);
286 // make sure we don't overflow
287 boost::int64_t ret
= (pc
* 1000 / performace_counter_frequency
.QuadPart
) * 1000;
288 TORRENT_ASSERT((pc
>= 0 && pc
>= ret
) || (pc
< 0 && pc
< ret
));
290 return (pc
* 1000 / performace_counter_frequency
.QuadPart
) * 1000;
293 inline boost::int64_t microseconds_to_performance_counter(boost::int64_t ms
)
295 static LARGE_INTEGER performace_counter_frequency
= {0,0};
296 if (performace_counter_frequency
.QuadPart
== 0)
297 QueryPerformanceFrequency(&performace_counter_frequency
);
299 // make sure we don't overflow
300 boost::int64_t ret
= (ms
/ 1000) * performace_counter_frequency
.QuadPart
/ 1000;
301 TORRENT_ASSERT((ms
>= 0 && ms
<= ret
)
302 || (ms
< 0 && ms
> ret
));
304 return (ms
/ 1000) * performace_counter_frequency
.QuadPart
/ 1000;
308 inline int total_seconds(time_duration td
)
310 return int(aux::performance_counter_to_microseconds(td
.diff
)
313 inline int total_milliseconds(time_duration td
)
315 return int(aux::performance_counter_to_microseconds(td
.diff
)
318 inline boost::int64_t total_microseconds(time_duration td
)
320 return aux::performance_counter_to_microseconds(td
.diff
);
323 inline ptime
time_now()
326 QueryPerformanceCounter(&now
);
327 return ptime(now
.QuadPart
);
330 inline time_duration
microsec(boost::int64_t s
)
332 return time_duration(aux::microseconds_to_performance_counter(s
));
334 inline time_duration
milliseconds(boost::int64_t s
)
336 return time_duration(aux::microseconds_to_performance_counter(
339 inline time_duration
seconds(boost::int64_t s
)
341 return time_duration(aux::microseconds_to_performance_counter(
344 inline time_duration
minutes(boost::int64_t s
)
346 return time_duration(aux::microseconds_to_performance_counter(
349 inline time_duration
hours(boost::int64_t s
)
351 return time_duration(aux::microseconds_to_performance_counter(
352 s
* 1000000 * 60 * 60));
357 #elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
360 #include "libtorrent/assert.hpp"
364 inline int total_seconds(time_duration td
)
366 return td
.diff
/ 1000000;
368 inline int total_milliseconds(time_duration td
)
370 return td
.diff
/ 1000;
372 inline boost::int64_t total_microseconds(time_duration td
)
377 inline ptime
time_now()
380 clock_gettime(CLOCK_MONOTONIC
, &ts
);
381 return ptime(boost::int64_t(ts
.tv_sec
) * 1000000 + ts
.tv_nsec
/ 1000);
384 inline time_duration
microsec(boost::int64_t s
)
386 return time_duration(s
);
388 inline time_duration
milliseconds(boost::int64_t s
)
390 return time_duration(s
* 1000);
392 inline time_duration
seconds(boost::int64_t s
)
394 return time_duration(s
* 1000000);
396 inline time_duration
minutes(boost::int64_t s
)
398 return time_duration(s
* 1000000 * 60);
400 inline time_duration
hours(boost::int64_t s
)
402 return time_duration(s
* 1000000 * 60 * 60);