Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/thread/src/xtime.cpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 4.6 KB
Line 
1// Copyright (C) 2001-2003
2// William E. Kempf
3//
4//  Distributed under the Boost Software License, Version 1.0. (See accompanying
5//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7#include <boost/thread/detail/config.hpp>
8
9#if defined(BOOST_HAS_FTIME)
10#   define __STDC_CONSTANT_MACROS
11#endif
12
13#include <boost/thread/xtime.hpp>
14
15#if defined(BOOST_HAS_FTIME)
16#   include <windows.h>
17#   include <boost/cstdint.hpp>
18#elif defined(BOOST_HAS_GETTIMEOFDAY)
19#   include <sys/time.h>
20#elif defined(BOOST_HAS_MPTASKS)
21#   include <DriverServices.h>
22#   include <boost/thread/detail/force_cast.hpp>
23#endif
24
25#include <cassert>
26
27namespace boost {
28
29#ifdef BOOST_HAS_MPTASKS
30
31namespace detail
32{
33
34using thread::force_cast;
35
36struct startup_time_info
37{
38    startup_time_info()
39    {
40        // 1970 Jan 1 at 00:00:00
41        static const DateTimeRec k_sUNIXBase = {1970, 1, 1, 0, 0, 0, 0};
42        static unsigned long s_ulUNIXBaseSeconds = 0UL;
43
44        if(s_ulUNIXBaseSeconds == 0UL)
45        {
46            // calculate the number of seconds between the Mac OS base and the
47            // UNIX base the first time we enter this constructor.
48            DateToSeconds(&k_sUNIXBase, &s_ulUNIXBaseSeconds);
49        }
50
51        unsigned long ulSeconds;
52
53        // get the time in UpTime units twice, with the time in seconds in the
54        // middle.
55        uint64_t ullFirstUpTime = force_cast<uint64_t>(UpTime());
56        GetDateTime(&ulSeconds);
57        uint64_t ullSecondUpTime = force_cast<uint64_t>(UpTime());
58
59        // calculate the midpoint of the two UpTimes, and save that.
60        uint64_t ullAverageUpTime = (ullFirstUpTime + ullSecondUpTime) / 2ULL;
61        m_sStartupAbsoluteTime = force_cast<AbsoluteTime>(ullAverageUpTime);
62
63        // save the number of seconds, recentered at the UNIX base.
64        m_ulStartupSeconds = ulSeconds - s_ulUNIXBaseSeconds;
65    }
66
67    AbsoluteTime m_sStartupAbsoluteTime;
68    UInt32 m_ulStartupSeconds;
69};
70
71static startup_time_info g_sStartupTimeInfo;
72
73} // namespace detail
74
75#endif
76
77
78int xtime_get(struct xtime* xtp, int clock_type)
79{
80    if (clock_type == TIME_UTC)
81    {
82#if defined(BOOST_HAS_FTIME)
83        FILETIME ft;
84#   if defined(BOOST_NO_GETSYSTEMTIMEASFILETIME)
85        {
86            SYSTEMTIME st;
87            GetSystemTime(&st);
88            SystemTimeToFileTime(&st,&ft);
89        }
90#   else
91        GetSystemTimeAsFileTime(&ft);
92#   endif
93        static const boost::uint64_t TIMESPEC_TO_FILETIME_OFFSET =
94            UINT64_C(116444736000000000);
95       
96        const boost::uint64_t ft64 =
97            (static_cast<boost::uint64_t>(ft.dwHighDateTime) << 32)
98            + ft.dwLowDateTime;
99
100        xtp->sec = static_cast<xtime::xtime_sec_t>(
101            (ft64 - TIMESPEC_TO_FILETIME_OFFSET) / 10000000
102        );
103
104        xtp->nsec = static_cast<xtime::xtime_nsec_t>(
105            ((ft64 - TIMESPEC_TO_FILETIME_OFFSET) % 10000000) * 100
106        );
107
108        return clock_type;
109#elif defined(BOOST_HAS_GETTIMEOFDAY)
110        struct timeval tv;
111#       ifndef NDEBUG
112        int res =
113#endif           
114        gettimeofday(&tv, 0);
115        assert(0 == res);
116        assert(tv.tv_sec >= 0);
117        assert(tv.tv_usec >= 0);
118        xtp->sec = tv.tv_sec;
119        xtp->nsec = tv.tv_usec * 1000;
120        return clock_type;
121#elif defined(BOOST_HAS_CLOCK_GETTIME)
122        timespec ts;
123#       ifndef NDEBUG
124        int res =
125#       endif           
126        clock_gettime(CLOCK_REALTIME, &ts);
127        assert(0 == res);
128        xtp->sec = ts.tv_sec;
129        xtp->nsec = ts.tv_nsec;
130        return clock_type;
131#elif defined(BOOST_HAS_MPTASKS)
132        using detail::thread::force_cast;
133        // the Mac OS does not have an MP-safe way of getting the date/time,
134        // so we use a delta from the startup time.  We _could_ defer this
135        // and use something that is interrupt-safe, but this would be _SLOW_,
136        // and we need speed here.
137        const uint64_t k_ullNanosecondsPerSecond(1000ULL * 1000ULL * 1000ULL);
138        AbsoluteTime sUpTime(UpTime());
139        uint64_t ullNanoseconds(
140            force_cast<uint64_t>(
141                AbsoluteDeltaToNanoseconds(sUpTime,
142                    detail::g_sStartupTimeInfo.m_sStartupAbsoluteTime)));
143        uint64_t ullSeconds = (ullNanoseconds / k_ullNanosecondsPerSecond);
144        ullNanoseconds -= (ullSeconds * k_ullNanosecondsPerSecond);
145        xtp->sec = detail::g_sStartupTimeInfo.m_ulStartupSeconds + ullSeconds;
146        xtp->nsec = ullNanoseconds;
147        return clock_type;
148#else
149#   error "xtime_get implementation undefined"
150#endif
151    }
152    return 0;
153}
154
155} // namespace boost
156
157// Change Log:
158//   8 Feb 01  WEKEMPF Initial version.
Note: See TracBrowser for help on using the repository browser.