From 70399a721cced0c702f6cfe8a08fb9dae45aa18f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 31 Mar 2015 11:22:50 +0200 Subject: [PATCH] Avoid excessive locking and calling tzset in time functions. * libc/time/lcltime_r.c (localtime_r): Call _tzset_unlocked inside TZ lock. * libc/time/mktime.c (mktime): Ditto. * libc/time/strftime.c (strftime, wcsftime): Ditto. Guard against calling _tzset_unlocked more than once (baring recursion). Signed-off-by: Corinna Vinschen --- newlib/ChangeLog | 8 ++++++++ newlib/libc/time/lcltime_r.c | 2 +- newlib/libc/time/mktime.c | 4 ++-- newlib/libc/time/strftime.c | 16 ++++++++++++++-- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 420354ef6..e615421d1 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,11 @@ +2015-03-31 Corinna Vinschen + + * libc/time/lcltime_r.c (localtime_r): Call _tzset_unlocked inside + TZ lock. + * libc/time/mktime.c (mktime): Ditto. + * libc/time/strftime.c (strftime, wcsftime): Ditto. Guard against + calling _tzset_unlocked more than once (baring recursion). + 2015-03-31 Corinna Vinschen * libc/time/local.h (_tzset_unlocked_r): Add prototype. diff --git a/newlib/libc/time/lcltime_r.c b/newlib/libc/time/lcltime_r.c index 8a69e40ee..3342e9906 100644 --- a/newlib/libc/time/lcltime_r.c +++ b/newlib/libc/time/lcltime_r.c @@ -31,8 +31,8 @@ _DEFUN (localtime_r, (tim_p, res), year = res->tm_year + YEAR_BASE; ip = __month_lengths[isleap(year)]; - tzset (); TZ_LOCK; + _tzset_unlocked (); if (_daylight) { if (year == tz->__tzyear || __tzcalc_limits (year)) diff --git a/newlib/libc/time/mktime.c b/newlib/libc/time/mktime.c index 8669fbdfb..44c0257f7 100644 --- a/newlib/libc/time/mktime.c +++ b/newlib/libc/time/mktime.c @@ -197,10 +197,10 @@ _DEFUN(mktime, (tim_p), /* compute total seconds */ tim += (days * _SEC_IN_DAY); - tzset (); - TZ_LOCK; + _tzset_unlocked (); + if (_daylight) { int tm_isdst; diff --git a/newlib/libc/time/strftime.c b/newlib/libc/time/strftime.c index 72f06d32e..9e677346e 100644 --- a/newlib/libc/time/strftime.c +++ b/newlib/libc/time/strftime.c @@ -703,6 +703,7 @@ _DEFUN (strftime, (s, maxsize, format, tim_p), CHAR alt; CHAR pad; unsigned long width; + int tzset_called = 0; struct lc_time_T *_CurrentTimeLocale = __get_current_time_locale (); for (;;) @@ -1283,7 +1284,13 @@ recurse: if (tim_p->tm_isdst >= 0) { long offset; - tzset (); + + TZ_LOCK; + if (!tzset_called) + { + _tzset_unlocked (); + tzset_called = 1; + } #if defined (__CYGWIN__) /* Cygwin must check if the application has been built with or @@ -1302,6 +1309,7 @@ recurse: but have to use __tzrule for daylight savings. */ offset = -tz->__tzrule[tim_p->tm_isdst > 0].offset; #endif + TZ_UNLOCK; len = snprintf (&s[count], maxsize - count, CQ("%+03ld%.2ld"), offset / SECSPERHOUR, labs (offset / SECSPERMIN) % 60L); @@ -1314,8 +1322,12 @@ recurse: size_t size; const char *tznam = NULL; - tzset (); TZ_LOCK; + if (!tzset_called) + { + _tzset_unlocked (); + tzset_called = 1; + } #if defined (__CYGWIN__) /* See above. */ extern const char *__cygwin_gettzname (const struct tm *tmp);