From c05a1ecfb91df2691d20f8ba66b5b5a7df5d27a3 Mon Sep 17 00:00:00 2001 From: Keith Marshall Date: Thu, 18 Oct 2018 09:50:58 +0100 Subject: [PATCH] Map compile-time constant references for POSIX clocks. --- mingwrt/ChangeLog | 25 +++++++++++++++++++++++++ mingwrt/include/time.h | 22 +++++++++++++++------- mingwrt/mingwex/clockapi.c | 27 ++++++++++++++++----------- mingwrt/mingwex/clockapi.h | 6 +++--- mingwrt/mingwex/clockres.c | 4 ++-- mingwrt/mingwex/clockset.c | 4 ++-- mingwrt/mingwex/clocktime.c | 2 +- 7 files changed, 64 insertions(+), 26 deletions(-) diff --git a/mingwrt/ChangeLog b/mingwrt/ChangeLog index 637c78a..899e62b 100644 --- a/mingwrt/ChangeLog +++ b/mingwrt/ChangeLog @@ -1,3 +1,28 @@ +2018-10-18 Keith Marshall + + Map compile-time constant references for POSIX clocks. + + * include/time.h (CLOCK_REALTIME, CLOCK_MONOTONIC): Redefine, using... + (__MINGW_POSIX_CLOCKAPI): ...this new macro; it converts clock indices + to odd-valued compile-time constant pseudo-pointers, (distinguishable + from real pointers which are always even-valued), which may be passed + as clockid_t references in POSIX clock API function calls. + + * mingwex/clockapi.h (struct __clockid__): Specify 4-byte alignment. + (__clock_api_is_valid): Change return type to "clockid_t". + + * mingwex/clockapi.c (__clock_api_is_valid): Return an even-valued, + non-NULL, "clockid_t" reference pointer, or "NULL" if invalid; use... + (clock_reference): ...this new static inline function, to convert... + (CLOCK_REALTIME, CLOCK_MONOTONIC): ...these odd-valued pseudo-pointers + to their actual run-time pointer equivalents; delete their physical + initializations, which have now become invalid. + + * mingwex/clockres.c (clock_getres) + * mingwex/clocktime.c (clock_gettime) + * mingwex/clockset.c (clock_settime): Update the "clockid_t" argument + to match the real pointer returned by __clock_api_is_valid() + 2018-10-08 Keith Marshall Suppress autoconf detection of _aligned_malloc functions. diff --git a/mingwrt/include/time.h b/mingwrt/include/time.h index 89f4b09..69186f6 100644 --- a/mingwrt/include/time.h +++ b/mingwrt/include/time.h @@ -438,16 +438,24 @@ int nanosleep( const struct timespec *period, struct timespec *residual ) */ typedef struct __clockid__ *clockid_t; -/* The standard clockid_t entities which we choose to support. +/* POSIX prefers to have the standard clockid_t entities defined + * as macros, each of which represents an entity of type clockid_t. + * Since this is not an integer data type, POSIX does not strictly + * require such macros to expand to constant expressions; however, + * some ill-behaved applications, (GCC's Ada implementation is one + * such), depend on such expansions. Thus, although it will incur + * a small additional run-time overhead to interpret them, we map + * such entities in terms of pseudo-pointer references, (which we + * discriminate from real pointer references, which we assume to + * be always to even valued addresses, by forcing odd values for + * the pseudo-pointer references). */ -extern clockid_t const CLOCK_REALTIME; -extern clockid_t const CLOCK_MONOTONIC; +#define __MINGW_POSIX_CLOCKAPI(ID) ((clockid_t)(1 + ((ID) << 1))) -/* Ensure that these clock implementations are detectable via - * preprocessor #ifdef names. +/* The standard clockid_t entities which we choose to support. */ -#define CLOCK_REALTIME CLOCK_REALTIME -#define CLOCK_MONOTONIC CLOCK_MONOTONIC +#define CLOCK_REALTIME __MINGW_POSIX_CLOCKAPI (0) +#define CLOCK_MONOTONIC __MINGW_POSIX_CLOCKAPI (1) /* Prototypes for the standard POSIX functions which provide the * API to these standard clockid_t entities. diff --git a/mingwrt/mingwex/clockapi.c b/mingwrt/mingwex/clockapi.c index 20b8da0..9d122ae 100644 --- a/mingwrt/mingwex/clockapi.c +++ b/mingwrt/mingwex/clockapi.c @@ -48,11 +48,6 @@ static struct __clockid__ clock_api[] = } }; -/* Publicly visible references to the preceding (opaque) clock definitions. - */ -clockid_t const CLOCK_REALTIME = &clock_api[CLOCK_TYPE_REALTIME]; -clockid_t const CLOCK_MONOTONIC = &clock_api[CLOCK_TYPE_MONOTONIC]; - CLOCK_INLINE int64_t clock_api_getres_interval( clockid_t clock_api ) { @@ -122,24 +117,34 @@ int64_t clock_api_getres_interval( clockid_t clock_api ) return clock_api->resolution = ((uint64_t)(clock_api_invalid_error())); } -int __clock_api_is_valid( clockid_t clock_id ) +CLOCK_INLINE +clockid_t clock_reference( clockid_t clock_id ) +{ /* Inline helper function to map pseudo-pointer clockid_t entity + * references to their actual implementation data references. + */ + return ((uintptr_t)(clock_id) & 1) + ? & clock_api[(uintptr_t)(clock_id) >> 1] + : clock_id; +} + +clockid_t __clock_api_is_valid( clockid_t clock_id ) { /* Helper function, called by any of clock_getres(), clock_gettime(), * or clock_settime(), to check availability of the specified clock, * initializing it if necessary, returning... */ - if( (clock_id != NULL) + if( ((clock_id = clock_reference( clock_id )) != NULL) && ((unsigned)(clock_id->type) < CLOCK_TYPE_UNIMPLEMENTED) && (clock_api_getres_interval( clock_id ) > 0LL) ) /* - * ...a nominally TRUE value of 1, in the case of a valid clock... + * ...a nominally TRUE value, equivalent to the valid clock_id... */ - return 1; + return clock_id; - /* ...or FALSE (zero), and setting "errno", otherwise. + /* ...or NULL, (nominally FALSE), and setting "errno", otherwise. */ errno = EINVAL; - return 0; + return NULL; } /* $RCSfile$: end of file */ diff --git a/mingwrt/mingwex/clockapi.h b/mingwrt/mingwex/clockapi.h index 64fb9ad..cf68f86 100644 --- a/mingwrt/mingwex/clockapi.h +++ b/mingwrt/mingwex/clockapi.h @@ -6,7 +6,7 @@ * $Id$ * * Written by Keith Marshall - * Copyright (C) 2017, MinGW.org Project + * Copyright (C) 2017, 2018, MinGW.org Project * * * Permission is hereby granted, free of charge, to any person obtaining a @@ -60,7 +60,7 @@ typedef enum #define CLOCK_REALTIME_FREQUENCY (NANOSECONDS_PER_SECOND / 100LL) #define UNIX_EPOCH_AS_FILETIME (11644473600LL * CLOCK_REALTIME_FREQUENCY) -typedef struct __clockid__ +typedef struct __attribute__((__aligned__(4))) __clockid__ { /* Formal definition of the clockid_t structure; (opaque to * user application code). */ @@ -74,7 +74,7 @@ typedef struct __clockid__ * within the scope of the implementation, (so not declared publicly), * this also provides initialization support. */ -extern int __clock_api_is_valid( clockid_t ); +extern clockid_t __clock_api_is_valid( clockid_t ); #define CLOCK_INLINE static __inline__ __attribute__((__always_inline__)) diff --git a/mingwrt/mingwex/clockres.c b/mingwrt/mingwex/clockres.c index b1640ed..9216296 100644 --- a/mingwrt/mingwex/clockres.c +++ b/mingwrt/mingwex/clockres.c @@ -6,7 +6,7 @@ * $Id$ * * Written by Keith Marshall - * Copyright (C) 2017, MinGW.org Project + * Copyright (C) 2017, 2018, MinGW.org Project * * * Permission is hereby granted, free of charge, to any person obtaining a @@ -39,7 +39,7 @@ int clock_getres( clockid_t clock_id, struct timespec *counter ) * recorded within the associated implementation data structure, * together with a "validity check" status code. */ - if( __clock_api_is_valid( clock_id ) ) + if( (clock_id = __clock_api_is_valid( clock_id )) != NULL ) { /* The clock is valid; its resolution must be broken down into * separate seconds and nanoseconds components, but only if the diff --git a/mingwrt/mingwex/clockset.c b/mingwrt/mingwex/clockset.c index d3d9a3a..b82d8b8 100644 --- a/mingwrt/mingwex/clockset.c +++ b/mingwrt/mingwex/clockset.c @@ -6,7 +6,7 @@ * $Id$ * * Written by Keith Marshall - * Copyright (C) 2017, MinGW.org Project + * Copyright (C) 2017, 2018, MinGW.org Project * * * Permission is hereby granted, free of charge, to any person obtaining a @@ -40,7 +40,7 @@ int clock_settime( clockid_t clock_id, const struct timespec *timeval ) * FIXME: Decide which clockid_t entities should support any such * adjustment; for the time being, deny all such requests. */ - errno = ((timeval != NULL) && __clock_api_is_valid( clock_id )) + errno = ((timeval != NULL) && (__clock_api_is_valid( clock_id ) != NULL)) ? EPERM : EINVAL; return -1; } diff --git a/mingwrt/mingwex/clocktime.c b/mingwrt/mingwex/clocktime.c index b078e96..46ea9ab 100644 --- a/mingwrt/mingwex/clocktime.c +++ b/mingwrt/mingwex/clocktime.c @@ -47,7 +47,7 @@ int clock_gettime( clockid_t clock_id, struct timespec *current ) if( current == NULL ) return clock_api_invalid_error(); - if( __clock_api_is_valid( clock_id ) ) + if( (clock_id = __clock_api_is_valid( clock_id )) != NULL ) { /* We must be prepared to retrieve clock frequencies from Windows * APIs, which report either LARGE_INTEGER or FILETIME values, but -- 2.11.0