From e548f836d93f02fd02615f3e9c5bb3e62aec0e4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jurko=20Gospodneti=C4=87?= Date: Sat, 14 Jul 2012 17:17:09 +0000 Subject: [PATCH] Boost Jam's internal timestamp data structure now holds a member for nanosecond information. This information is still always set to 0 but, if set, is used when needed. Updated Boost Jam's header cache file format to hold the new extended timestamp information (bumped format version up to 5). [SVN r79506] --- src/engine/execunix.c | 4 ++-- src/engine/filent.c | 9 +++++---- src/engine/filesys.c | 4 ++-- src/engine/fileunix.c | 8 ++++---- src/engine/hcache.c | 32 ++++++++++++++++++++------------ src/engine/jam.c | 2 +- src/engine/make1.c | 2 +- src/engine/timestamp.c | 15 ++++++++++----- src/engine/timestamp.h | 6 ++++-- 9 files changed, 49 insertions(+), 33 deletions(-) diff --git a/src/engine/execunix.c b/src/engine/execunix.c index 51890b13b..140dee8ae 100644 --- a/src/engine/execunix.c +++ b/src/engine/execunix.c @@ -184,7 +184,7 @@ void exec_cmd /* Start the command */ - timestamp_init( &cmdtab[ slot ].start_dt, time( 0 ) ); + timestamp_init( &cmdtab[ slot ].start_dt, time( 0 ), 0 ); if ( 0 < globs.timeout ) { @@ -506,7 +506,7 @@ void exec_wait() time_info.user = (double)( new_time.tms_cutime - old_time.tms_cutime ) / CLOCKS_PER_SEC; timestamp_copy( &time_info.start, &cmdtab[ i ].start_dt ); - timestamp_init( &time_info.end, time( 0 ) ); + timestamp_init( &time_info.end, time( 0 ), 0 ); old_time = new_time; } diff --git a/src/engine/filent.c b/src/engine/filent.c index e41bc4218..f796b298b 100644 --- a/src/engine/filent.c +++ b/src/engine/filent.c @@ -111,7 +111,7 @@ int file_collect_dir_content_( file_info_t * const d ) ff->is_dir = !ff->is_file; ff->size = finfo->ff_fsize; timestamp_init( &ff->time, ( finfo->ff_ftime << 16 ) | - finfo->ff_ftime ); + finfo->ff_ftime, 0 ); } } while ( !findnext( finfo ) ); @@ -142,7 +142,7 @@ int file_collect_dir_content_( file_info_t * const d ) ff->is_file = finfo->attrib & _A_SUBDIR ? 0 : 1; ff->is_dir = !ff->is_file; ff->size = finfo->size; - timestamp_init( &ff->time, finfo->time_write ); + timestamp_init( &ff->time, finfo->time_write, 0 ); } } while ( !_findnext( handle, finfo ) ); @@ -339,7 +339,7 @@ void file_archscan( char const * archive, scanback func, void * closure ) { OBJECT * const member = object_new( buf ); timestamp time; - timestamp_init( &time, (time_t)lar_date ); + timestamp_init( &time, (time_t)lar_date, 0 ); (*func)( closure, member, 1 /* time valid */, &time ); object_free( member ); } @@ -388,7 +388,8 @@ void filetime_to_timestamp( FILETIME const ft, timestamp * const time ) /* For resolutions finer than 1 second use the following: * nsec = (int)( in % 10000000 ) * 100; */ - timestamp_init( time, (time_t)( ( in / 10000000 ) - secs_between_epochs ) ); + timestamp_init( time, (time_t)( ( in / 10000000 ) - secs_between_epochs ), 0 + ); } #endif /* OS_NT */ diff --git a/src/engine/filesys.c b/src/engine/filesys.c index 64df006ba..b09bb9617 100644 --- a/src/engine/filesys.c +++ b/src/engine/filesys.c @@ -205,7 +205,7 @@ file_info_t * file_query( OBJECT * const path ) * confusion with non-existing paths. */ if ( timestamp_empty( &ff->time ) ) - timestamp_init( &ff->time, 1 ); + timestamp_init( &ff->time, 1, 0 ); } return ff; } @@ -231,7 +231,7 @@ int file_query_posix_( file_info_t * const info ) info->is_file = statbuf.st_mode & S_IFREG ? 1 : 0; info->is_dir = statbuf.st_mode & S_IFDIR ? 1 : 0; info->size = statbuf.st_size; - timestamp_init( &info->time, statbuf.st_mtime ); + timestamp_init( &info->time, statbuf.st_mtime, 0 ); return 0; } diff --git a/src/engine/fileunix.c b/src/engine/fileunix.c index a677e6a35..68d80a9de 100644 --- a/src/engine/fileunix.c +++ b/src/engine/fileunix.c @@ -276,7 +276,7 @@ void file_archscan( char const * archive, scanback func, void * closure ) { OBJECT * const member = object_new( buf ); timestamp time; - timestamp_init( &time, (time_t)lar_date ); + timestamp_init( &time, (time_t)lar_date, 0 ); (*func)( closure, member, 1 /* time valid */, &time ); object_free( member ); } @@ -335,7 +335,7 @@ static void file_archscan_small( int fd, char const * archive, scanback func, { OBJECT * const member = object_new( buf ); timestamp time; - timestamp_init( &time, (time_t)lar_date ); + timestamp_init( &time, (time_t)lar_date, 0 ); (*func)( closure, member, 1 /* time valid */, &time ); object_free( member ); } @@ -370,7 +370,7 @@ static void file_archscan_big( int fd, char const * archive, scanback func, read( fd, &ar_hdr, sizeof( ar_hdr ) ) >= sizeof( ar_hdr.hdr ) ) { long lar_date; - int lar_namlen; + int lar_namlen; sscanf( ar_hdr.hdr.ar_namlen, "%d" , &lar_namlen ); sscanf( ar_hdr.hdr.ar_date , "%ld" , &lar_date ); @@ -386,7 +386,7 @@ static void file_archscan_big( int fd, char const * archive, scanback func, { OBJECT * const member = object_new( buf ); timestamp time; - timestamp_init( &time, (time_t)lar_date ); + timestamp_init( &time, (time_t)lar_date, 0 ); (*func)( closure, member, 1 /* time valid */, &time ); object_free( member ); } diff --git a/src/engine/hcache.c b/src/engine/hcache.c index f2f5fdcc7..3cf15f776 100644 --- a/src/engine/hcache.c +++ b/src/engine/hcache.c @@ -22,7 +22,7 @@ * * The dependency file format is an ASCII file with 1 line per target. Each line * has the following fields: - * @boundname@ timestamp @file@ @file@ @file@ ... + * @boundname@ timestamp_sec timestamp_nsec @file@ @file@ @file@ ... */ #ifdef OPT_HEADER_CACHE_EXT @@ -61,7 +61,7 @@ static HCACHEDATA * hcachelist = 0; static int queries = 0; static int hits = 0; -#define CACHE_FILE_VERSION "version 4" +#define CACHE_FILE_VERSION "version 5" #define CACHE_RECORD_HEADER "header" #define CACHE_RECORD_END "end" @@ -201,7 +201,8 @@ void hcache_init() HCACHEDATA cachedata; HCACHEDATA * c; OBJECT * record_type = 0; - OBJECT * time_str = 0; + OBJECT * time_secs_str = 0; + OBJECT * time_nsecs_str = 0; OBJECT * age_str = 0; OBJECT * includes_count_str = 0; OBJECT * hdrscan_count_str = 0; @@ -233,18 +234,20 @@ void hcache_init() } cachedata.boundname = read_netstring( f ); - time_str = read_netstring( f ); + time_secs_str = read_netstring( f ); + time_nsecs_str = read_netstring( f ); age_str = read_netstring( f ); includes_count_str = read_netstring( f ); - if ( !cachedata.boundname || !time_str || !age_str || - !includes_count_str ) + if ( !cachedata.boundname || !time_secs_str || !time_nsecs_str || + !age_str || !includes_count_str ) { fprintf( stderr, "invalid %s\n", hcachename ); goto cleanup; } - timestamp_init( &cachedata.time, atoi( object_str( time_str ) ) ); + timestamp_init( &cachedata.time, atoi( object_str( time_secs_str ) ), + atoi( object_str( time_nsecs_str ) ) ); cachedata.age = atoi( object_str( age_str ) ) + 1; count = atoi( object_str( includes_count_str ) ); @@ -305,7 +308,8 @@ void hcache_init() ++header_count; object_free( record_type ); - object_free( time_str ); + object_free( time_secs_str ); + object_free( time_nsecs_str ); object_free( age_str ); object_free( includes_count_str ); object_free( hdrscan_count_str ); @@ -314,7 +318,8 @@ void hcache_init() cleanup: if ( record_type ) object_free( record_type ); - if ( time_str ) object_free( time_str ); + if ( time_secs_str ) object_free( time_secs_str ); + if ( time_nsecs_str ) object_free( time_nsecs_str ); if ( age_str ) object_free( age_str ); if ( includes_count_str ) object_free( includes_count_str ); if ( hdrscan_count_str ) object_free( hdrscan_count_str ); @@ -363,7 +368,8 @@ void hcache_done() { LISTITER iter; LISTITER end; - char time_str[ 30 ]; + char time_secs_str[ 30 ]; + char time_nsecs_str[ 30 ]; char age_str[ 30 ]; char includes_count_str[ 30 ]; char hdrscan_count_str[ 30 ]; @@ -377,12 +383,14 @@ void hcache_done() c->includes ) ); sprintf( hdrscan_count_str, "%lu", (long unsigned)list_length( c->hdrscan ) ); - sprintf( time_str, "%lu", (long unsigned)c->time.secs ); + sprintf( time_secs_str, "%lu", (long unsigned)c->time.secs ); + sprintf( time_nsecs_str, "%lu", (long unsigned)c->time.nsecs ); sprintf( age_str, "%lu", (long unsigned)c->age ); write_netstring( f, CACHE_RECORD_HEADER ); write_netstring( f, object_str( c->boundname ) ); - write_netstring( f, time_str ); + write_netstring( f, time_secs_str ); + write_netstring( f, time_nsecs_str ); write_netstring( f, age_str ); write_netstring( f, includes_count_str ); for ( iter = list_begin( c->includes ), end = list_end( c->includes ); diff --git a/src/engine/jam.c b/src/engine/jam.c index 622a050da..6277320d3 100644 --- a/src/engine/jam.c +++ b/src/engine/jam.c @@ -388,7 +388,7 @@ int main( int argc, char * * argv, char * * arg_environ ) /* Set JAMDATE. */ { timestamp current; - timestamp_init( ¤t, time( 0 ) ); + timestamp_init( ¤t, time( 0 ), 0 ); var_set( root_module(), constant_JAMDATE, list_new( outf_time( ¤t ) ), VAR_SET ); } diff --git a/src/engine/make1.c b/src/engine/make1.c index a441f6717..1ab67a7ca 100644 --- a/src/engine/make1.c +++ b/src/engine/make1.c @@ -513,7 +513,7 @@ static void make1c( state const * const pState ) if ( globs.noexec || cmd->noop ) { timing_info time_info = { 0 }; - timestamp_init( &time_info.start, time( 0 ) ); + timestamp_init( &time_info.start, time( 0 ), 0 ); timestamp_copy( &time_info.end, &time_info.start ); make1c_closure( t, EXEC_CMD_OK, &time_info, "", "", EXIT_OK ); } diff --git a/src/engine/timestamp.c b/src/engine/timestamp.c index 051e063b0..db400c6e1 100644 --- a/src/engine/timestamp.c +++ b/src/engine/timestamp.c @@ -71,12 +71,14 @@ static char * time_progress[] = void timestamp_clear( timestamp * const time ) { - time->secs = 0; + time->secs = time->nsecs = 0; } int timestamp_cmp( timestamp const * const lhs, timestamp const * const rhs ) { + if ( lhs->secs == rhs->secs ) + return lhs->nsecs - rhs->nsecs; return lhs->secs - rhs->secs; } @@ -84,12 +86,13 @@ int timestamp_cmp( timestamp const * const lhs, timestamp const * const rhs ) void timestamp_copy( timestamp * const target, timestamp const * const source ) { target->secs = source->secs; + target->nsecs = source->nsecs; } int timestamp_empty( timestamp const * const time ) { - return !time->secs; + return !time->secs && !time->nsecs; } @@ -97,7 +100,7 @@ int timestamp_empty( timestamp const * const time ) * timestamp_from_path() - return timestamp for a path, if present */ -void timestamp_from_path( timestamp * const time, OBJECT * path ) +void timestamp_from_path( timestamp * const time, OBJECT * const path ) { PROFILE_ENTER( timestamp ); @@ -218,9 +221,11 @@ void timestamp_from_path( timestamp * const time, OBJECT * path ) } -void timestamp_init( timestamp * const time, time_t const secs ) +void timestamp_init( timestamp * const time, time_t const secs, int const nsecs + ) { time->secs = secs; + time->nsecs = nsecs; } @@ -240,7 +245,7 @@ char const * timestamp_str( timestamp const * const time ) char format[ 500 ]; strftime( format, sizeof( result ) / sizeof( *result ), "%Y-%m-%d %H:%M:%S.%%09d +0000", gmtime( &time->secs ) ); - sprintf( result, format, 0 ); + sprintf( result, format, time->nsecs ); return result; } diff --git a/src/engine/timestamp.h b/src/engine/timestamp.h index a83fb9dc3..66e9af128 100644 --- a/src/engine/timestamp.h +++ b/src/engine/timestamp.h @@ -18,14 +18,16 @@ typedef struct timestamp { time_t secs; + int nsecs; } timestamp; void timestamp_clear( timestamp * const time ); int timestamp_cmp( timestamp const * const lhs, timestamp const * const rhs ); void timestamp_copy( timestamp * const target, timestamp const * const source ); int timestamp_empty( timestamp const * const time ); -void timestamp_from_path( timestamp * const time, OBJECT * path ); -void timestamp_init( timestamp * const time, time_t const secs ); +void timestamp_from_path( timestamp * const time, OBJECT * const path ); +void timestamp_init( timestamp * const time, time_t const secs, int const nsecs + ); void timestamp_max( timestamp * const max, timestamp const * const lhs, timestamp const * const rhs ); char const * timestamp_str( timestamp const * const time );