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