[PROPOSED 1/3] Define fullname only if needed
* localtime.c (union local_storage): Define fullname member only if needed. This saves space on unlikely platforms where sizeof (struct file_analysis) < PATH_MAX, and is closer to FreeBSD. (tzloadbody): Mention fullname only if declared. --- localtime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/localtime.c b/localtime.c index a78962a6..c9836b2d 100644 --- a/localtime.c +++ b/localtime.c @@ -771,7 +771,7 @@ union local_storage { struct state st; } u; -#ifdef PATH_MAX +#if defined PATH_MAX && !OPENAT_TZDIR && !SUPPRESS_TZDIR /* The name of the file to be opened. */ char fullname[PATH_MAX]; #endif @@ -890,7 +890,7 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags, cp = mempcpy(lsp, tzdirslash, tzdirslashlen); cp = mempcpy(cp, name, namelen); *cp = '\0'; -#ifdef PATH_MAX +#if defined PATH_MAX && !OPENAT_TZDIR && !SUPPRESS_TZDIR name = lsp->fullname; #else name = (char *) lsp; -- 2.48.1
This mimics what is done in FreeBSD localtime.c. * localtime.c (THREAD_SAFE): Default to 0. All uses changed. (once_t, ONCE_INIT, once): New type, macro, and function. (gmtcheck1): New function, with the guts of the old gmtcheck. (gmtcheck): Use it, along with ‘once’. --- localtime.c | 54 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/localtime.c b/localtime.c index c9836b2d..a00cf743 100644 --- a/localtime.c +++ b/localtime.c @@ -44,11 +44,15 @@ struct stat { char st_ctime, st_dev, st_ino; } # define st_ctim st_ctimespec #endif +#ifndef THREAD_SAFE +# define THREAD_SAFE 0 +#endif + #ifndef THREAD_RWLOCK # define THREAD_RWLOCK 0 #endif -#if defined THREAD_SAFE && THREAD_SAFE +#if THREAD_SAFE # include <pthread.h> # ifndef THREAD_PREFER_SINGLE @@ -133,6 +137,27 @@ rd2wrlock(ATTRIBUTE_MAYBE_UNUSED bool threaded) return 0; } +#if THREAD_SAFE +typedef pthread_once_t once_t; +# define ONCE_INIT PTHREAD_ONCE_INIT +#else +typedef bool once_t; +# define ONCE_INIT false +#endif + +static void +once(once_t *once_control, void (*init_routine)(void)) +{ +#if THREAD_SAFE + pthread_once(once_control, init_routine); +#else + if (!*once_control) { + *once_control = true; + init_routine(); + } +#endif +} + /* Unless intptr_t is missing, pacify gcc -Wcast-qual on char const * exprs. Use this carefully, as the casts disable type checking. This is a macro so that it can be used in static initializers. */ @@ -1921,25 +1946,20 @@ tzset(void) #endif static void -gmtcheck(void) +gmtcheck1(void) { - static bool gmt_is_set; - int err = lock(); - if (0 < err) - return; - if (! gmt_is_set) { - if (rd2wrlock(!err) != 0) - return; - if (!THREAD_RWLOCK || !gmt_is_set) { #if ALL_STATE - gmtptr = malloc(sizeof *gmtptr); + gmtptr = malloc(sizeof *gmtptr); #endif - if (gmtptr) - gmtload(gmtptr); - gmt_is_set = true; - } - } - unlock(!err); + if (gmtptr) + gmtload(gmtptr); +} + +static void +gmtcheck(void) +{ + static once_t gmt_once = ONCE_INIT; + once(&gmt_once, gmtcheck1); } #if NETBSD_INSPIRED && !USE_TIMEX_T -- 2.48.1
This should simplify future changes. * localtime.c (is_threaded): New static function. (lock): Use it. --- localtime.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/localtime.c b/localtime.c index a00cf743..1191f810 100644 --- a/localtime.c +++ b/localtime.c @@ -89,6 +89,24 @@ extern int __isthreaded; # endif # endif +/* True if the current process might be multi-threaded, + false if it is definitely single-threaded. + If false, it will be false the next time it is called + unless the caller creates a thread in the meantime. + If true, it might become false the next time it is called + if all other threads exit in the meantime. */ +static bool +is_threaded(void) +{ +# if THREAD_PREFER_SINGLE && HAVE___ISTHREADED + return !!__isthreaded; +# elif THREAD_PREFER_SINGLE && HAVE_SYS_SINGLE_THREADED_H + return !__libc_single_threaded; +# else + return true; +# endif +} + # if THREAD_RWLOCK static pthread_rwlock_t locallock = PTHREAD_RWLOCK_INITIALIZER; static int dolock(void) { return pthread_rwlock_rdlock(&locallock); } @@ -103,13 +121,8 @@ static void dounlock(void) { pthread_mutex_unlock(&locallock); } static int lock(void) { -# if THREAD_PREFER_SINGLE && HAVE___ISTHREADED - if (!__isthreaded) + if (!is_threaded()) return -1; -# elif THREAD_PREFER_SINGLE && HAVE_SYS_SINGLE_THREADED_H - if (__libc_single_threaded) - return -1; -# endif return dolock(); } static void -- 2.48.1
participants (1)
-
Paul Eggert