xref: /llvm-project-15.0.7/libcxx/src/chrono.cpp (revision 3e519524)
1*3e519524SHoward Hinnant //===------------------------- chrono.cpp ---------------------------------===//
2*3e519524SHoward Hinnant //
3*3e519524SHoward Hinnant // ��������������������The LLVM Compiler Infrastructure
4*3e519524SHoward Hinnant //
5*3e519524SHoward Hinnant // This file is distributed under the University of Illinois Open Source
6*3e519524SHoward Hinnant // License. See LICENSE.TXT for details.
7*3e519524SHoward Hinnant //
8*3e519524SHoward Hinnant //===----------------------------------------------------------------------===//
9*3e519524SHoward Hinnant 
10*3e519524SHoward Hinnant #include "chrono"
11*3e519524SHoward Hinnant #include <sys/time.h>        //for gettimeofday and timeval
12*3e519524SHoward Hinnant #include <mach/mach_time.h>  // mach_absolute_time, mach_timebase_info_data_t
13*3e519524SHoward Hinnant 
14*3e519524SHoward Hinnant _LIBCPP_BEGIN_NAMESPACE_STD
15*3e519524SHoward Hinnant 
16*3e519524SHoward Hinnant namespace chrono
17*3e519524SHoward Hinnant {
18*3e519524SHoward Hinnant 
19*3e519524SHoward Hinnant // system_clock
20*3e519524SHoward Hinnant 
21*3e519524SHoward Hinnant system_clock::time_point
22*3e519524SHoward Hinnant system_clock::now()
23*3e519524SHoward Hinnant {
24*3e519524SHoward Hinnant     timeval tv;
25*3e519524SHoward Hinnant     gettimeofday(&tv, 0);
26*3e519524SHoward Hinnant     return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
27*3e519524SHoward Hinnant }
28*3e519524SHoward Hinnant 
29*3e519524SHoward Hinnant time_t
30*3e519524SHoward Hinnant system_clock::to_time_t(const time_point& t)
31*3e519524SHoward Hinnant {
32*3e519524SHoward Hinnant     return time_t(duration_cast<seconds>(t.time_since_epoch()).count());
33*3e519524SHoward Hinnant }
34*3e519524SHoward Hinnant 
35*3e519524SHoward Hinnant system_clock::time_point
36*3e519524SHoward Hinnant system_clock::from_time_t(time_t t)
37*3e519524SHoward Hinnant {
38*3e519524SHoward Hinnant     return system_clock::time_point(seconds(t));
39*3e519524SHoward Hinnant }
40*3e519524SHoward Hinnant 
41*3e519524SHoward Hinnant // monotonic_clock
42*3e519524SHoward Hinnant 
43*3e519524SHoward Hinnant //   mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of
44*3e519524SHoward Hinnant //   nanoseconds since the computer booted up.  MachInfo.numer and MachInfo.denom
45*3e519524SHoward Hinnant //   are run time constants supplied by the OS.  This clock has no relationship
46*3e519524SHoward Hinnant //   to the Gregorian calendar.  It's main use is as a high resolution timer.
47*3e519524SHoward Hinnant 
48*3e519524SHoward Hinnant // MachInfo.numer / MachInfo.denom is often 1 on the latest equipment.  Specialize
49*3e519524SHoward Hinnant //   for that case as an optimization.
50*3e519524SHoward Hinnant 
51*3e519524SHoward Hinnant #pragma GCC visibility push(hidden)
52*3e519524SHoward Hinnant 
53*3e519524SHoward Hinnant static
54*3e519524SHoward Hinnant monotonic_clock::rep
55*3e519524SHoward Hinnant monotonic_simplified()
56*3e519524SHoward Hinnant {
57*3e519524SHoward Hinnant     return mach_absolute_time();
58*3e519524SHoward Hinnant }
59*3e519524SHoward Hinnant 
60*3e519524SHoward Hinnant static
61*3e519524SHoward Hinnant double
62*3e519524SHoward Hinnant compute_monotonic_factor()
63*3e519524SHoward Hinnant {
64*3e519524SHoward Hinnant     mach_timebase_info_data_t MachInfo;
65*3e519524SHoward Hinnant     mach_timebase_info(&MachInfo);
66*3e519524SHoward Hinnant     return static_cast<double>(MachInfo.numer) / MachInfo.denom;
67*3e519524SHoward Hinnant }
68*3e519524SHoward Hinnant 
69*3e519524SHoward Hinnant static
70*3e519524SHoward Hinnant monotonic_clock::rep
71*3e519524SHoward Hinnant monotonic_full()
72*3e519524SHoward Hinnant {
73*3e519524SHoward Hinnant     static const double factor = compute_monotonic_factor();
74*3e519524SHoward Hinnant     return static_cast<monotonic_clock::rep>(mach_absolute_time() * factor);
75*3e519524SHoward Hinnant }
76*3e519524SHoward Hinnant 
77*3e519524SHoward Hinnant typedef monotonic_clock::rep (*FP)();
78*3e519524SHoward Hinnant 
79*3e519524SHoward Hinnant static
80*3e519524SHoward Hinnant FP
81*3e519524SHoward Hinnant init_monotonic_clock()
82*3e519524SHoward Hinnant {
83*3e519524SHoward Hinnant     mach_timebase_info_data_t MachInfo;
84*3e519524SHoward Hinnant     mach_timebase_info(&MachInfo);
85*3e519524SHoward Hinnant     if (MachInfo.numer == MachInfo.denom)
86*3e519524SHoward Hinnant         return &monotonic_simplified;
87*3e519524SHoward Hinnant     return &monotonic_full;
88*3e519524SHoward Hinnant }
89*3e519524SHoward Hinnant 
90*3e519524SHoward Hinnant #pragma GCC visiblity pop
91*3e519524SHoward Hinnant 
92*3e519524SHoward Hinnant monotonic_clock::time_point
93*3e519524SHoward Hinnant monotonic_clock::now()
94*3e519524SHoward Hinnant {
95*3e519524SHoward Hinnant     static FP fp = init_monotonic_clock();
96*3e519524SHoward Hinnant     return time_point(duration(fp()));
97*3e519524SHoward Hinnant }
98*3e519524SHoward Hinnant 
99*3e519524SHoward Hinnant }
100*3e519524SHoward Hinnant 
101*3e519524SHoward Hinnant _LIBCPP_END_NAMESPACE_STD
102