Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/thread/src/xtime.cpp @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

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