]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/tools/build/src/engine/timestamp.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / tools / build / src / engine / timestamp.cpp
CommitLineData
7c673cae
FG
1/*
2 * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
3 *
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
6
7/* This file is ALSO:
8 * Copyright 2001-2004 David Abrahams.
20effc67 9 * Copyright 2020 Nikita Kniazev.
7c673cae
FG
10 * Distributed under the Boost Software License, Version 1.0.
11 * (See accompanying file LICENSE_1_0.txt or
12 * http://www.boost.org/LICENSE_1_0.txt)
13 */
14
15/*
16 * timestamp.c - get the timestamp of a file or archive member
17 *
18 * External routines:
19 * timestamp_from_path() - return timestamp for a path, if present
20 * timestamp_done() - free timestamp tables
21 *
22 * Internal routines:
7c673cae
FG
23 * free_timestamps() - worker function for freeing timestamp table contents
24 */
25
26#include "jam.h"
27#include "timestamp.h"
28
29#include "filesys.h"
30#include "hash.h"
31#include "object.h"
32#include "pathsys.h"
f67539c2 33#include "jam_strings.h"
7c673cae
FG
34#include "output.h"
35
36
37/*
38 * BINDING - all known files
39 */
40
41typedef struct _binding
42{
43 OBJECT * name;
44 short flags;
45
46#define BIND_SCANNED 0x01 /* if directory or arch, has been scanned */
47
48 short progress;
49
50#define BIND_INIT 0 /* never seen */
51#define BIND_NOENTRY 1 /* timestamp requested but file never found */
52#define BIND_SPOTTED 2 /* file found but not timed yet */
53#define BIND_MISSING 3 /* file found but can not get timestamp */
54#define BIND_FOUND 4 /* file found and time stamped */
55
56 /* update time - cleared if the there is nothing to bind */
57 timestamp time;
58} BINDING;
59
60static struct hash * bindhash = 0;
61
7c673cae
FG
62
63#ifdef OS_NT
64/*
65 * timestamp_from_filetime() - Windows FILETIME --> timestamp conversion
66 *
67 * Lifted shamelessly from the CPython implementation.
68 */
69
70void timestamp_from_filetime( timestamp * const t, FILETIME const * const ft )
71{
72 /* Seconds between 1.1.1601 and 1.1.1970 */
73 static __int64 const secs_between_epochs = 11644473600;
74
75 /* We can not simply cast and dereference a FILETIME, since it might not be
76 * aligned properly. __int64 type variables are expected to be aligned to an
77 * 8 byte boundary while FILETIME structures may be aligned to any 4 byte
78 * boundary. Using an incorrectly aligned __int64 variable may cause a
79 * performance penalty on some platforms or even exceptions on others
80 * (documented on MSDN).
81 */
82 __int64 in;
83 memcpy( &in, ft, sizeof( in ) );
84
85 /* FILETIME resolution: 100ns. */
86 timestamp_init( t, (time_t)( ( in / 10000000 ) - secs_between_epochs ),
87 (int)( in % 10000000 ) * 100 );
88}
89#endif /* OS_NT */
90
91
92void timestamp_clear( timestamp * const time )
93{
94 time->secs = time->nsecs = 0;
95}
96
97
98int timestamp_cmp( timestamp const * const lhs, timestamp const * const rhs )
99{
f67539c2
TL
100 return int(
101 lhs->secs == rhs->secs
7c673cae 102 ? lhs->nsecs - rhs->nsecs
f67539c2 103 : lhs->secs - rhs->secs );
7c673cae
FG
104}
105
106
107void timestamp_copy( timestamp * const target, timestamp const * const source )
108{
109 target->secs = source->secs;
110 target->nsecs = source->nsecs;
111}
112
113
114void timestamp_current( timestamp * const t )
115{
116#ifdef OS_NT
117 /* GetSystemTimeAsFileTime()'s resolution seems to be about 15 ms on Windows
118 * XP and under a millisecond on Windows 7.
119 */
120 FILETIME ft;
121 GetSystemTimeAsFileTime( &ft );
122 timestamp_from_filetime( t, &ft );
11fdf7f2
TL
123#elif defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME) && \
124 (!defined(__GLIBC__) || (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 17))
125 /* Some older versions of XCode define _POSIX_TIMERS, but don't actually
126 * have clock_gettime. Check CLOCK_REALTIME as well. Prior to glibc 2.17,
127 * clock_gettime requires -lrt. This is a non-critical feature, so
128 * we just disable it to keep bootstrapping simple.
129 */
130 struct timespec ts;
131 clock_gettime( CLOCK_REALTIME, &ts );
132 timestamp_init( t, ts.tv_sec, ts.tv_nsec );
7c673cae
FG
133#else /* OS_NT */
134 timestamp_init( t, time( 0 ), 0 );
135#endif /* OS_NT */
136}
137
138
139int timestamp_empty( timestamp const * const time )
140{
141 return !time->secs && !time->nsecs;
142}
143
144
145/*
146 * timestamp_from_path() - return timestamp for a path, if present
147 */
148
149void timestamp_from_path( timestamp * const time, OBJECT * const path )
150{
151 PROFILE_ENTER( timestamp );
152
7c673cae
FG
153 if ( file_time( path, time ) < 0 )
154 timestamp_clear( time );
155
156 PROFILE_EXIT( timestamp );
157}
158
159
160void timestamp_init( timestamp * const time, time_t const secs, int const nsecs
161 )
162{
163 time->secs = secs;
164 time->nsecs = nsecs;
165}
166
167
168void timestamp_max( timestamp * const max, timestamp const * const lhs,
169 timestamp const * const rhs )
170{
171 if ( timestamp_cmp( lhs, rhs ) > 0 )
172 timestamp_copy( max, lhs );
173 else
174 timestamp_copy( max, rhs );
175}
176
177
178static char const * timestamp_formatstr( timestamp const * const time,
179 char const * const format )
180{
181 static char result1[ 500 ];
182 static char result2[ 500 ];
183 strftime( result1, sizeof( result1 ) / sizeof( *result1 ), format, gmtime(
184 &time->secs ) );
185 sprintf( result2, result1, time->nsecs );
186 return result2;
187}
188
189
190char const * timestamp_str( timestamp const * const time )
191{
192 return timestamp_formatstr( time, "%Y-%m-%d %H:%M:%S.%%09d +0000" );
193}
194
195
196char const * timestamp_timestr( timestamp const * const time )
197{
198 return timestamp_formatstr( time, "%H:%M:%S.%%09d" );
199}
200
201
7c673cae
FG
202/*
203 * free_timestamps() - worker function for freeing timestamp table contents
204 */
205
206static void free_timestamps( void * xbinding, void * data )
207{
208 object_free( ( (BINDING *)xbinding )->name );
209}
210
211
212/*
213 * timestamp_done() - free timestamp tables
214 */
215
216void timestamp_done()
217{
218 if ( bindhash )
219 {
220 hashenumerate( bindhash, free_timestamps, 0 );
221 hashdone( bindhash );
222 }
223}
224
225/*
226 * timestamp_delta_seconds() - seconds from time a to b.
227 */
228double timestamp_delta_seconds( timestamp const * const a , timestamp const * const b )
229{
20effc67 230 return difftime(b->secs, a->secs) + (b->nsecs - a->nsecs) * 1.0E-9;
7c673cae 231}