From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27742 invoked by alias); 16 Oct 2007 18:22:57 -0000 Received: (qmail 27726 invoked by uid 22791); 16 Oct 2007 18:22:57 -0000 X-Spam-Check-By: sourceware.org Received: from sunsite.ms.mff.cuni.cz (HELO sunsite.mff.cuni.cz) (195.113.15.26) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 16 Oct 2007 18:22:51 +0000 Received: from sunsite.mff.cuni.cz (localhost.localdomain [127.0.0.1]) by sunsite.mff.cuni.cz (8.13.8/8.13.8) with ESMTP id l9GIQMqd006023; Tue, 16 Oct 2007 20:26:22 +0200 Received: (from jj@localhost) by sunsite.mff.cuni.cz (8.13.8/8.13.8/Submit) id l9GIQM4E006022; Tue, 16 Oct 2007 20:26:22 +0200 Date: Tue, 16 Oct 2007 18:22:00 -0000 From: Jakub Jelinek To: Ulrich Drepper Cc: Glibc hackers Subject: [PATCH] Avoid unnecessary multiple tzset calls in strftime (BZ #5184) Message-ID: <20071016182622.GN2896@sunsite.mff.cuni.cz> Reply-To: Jakub Jelinek Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.2.2i Mailing-List: contact libc-hacker-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sourceware.org X-SW-Source: 2007-10/txt/msg00018.txt.bz2 Hi! For one strftime_l call it is enough to call tzset just once, if we recurse there is no reason to repeat that. As an additional cleanup the internal routine could be perhaps renamed and exported as hidden, so that strftime and wcstime could save 2 insns or so. But that can IMHO be done later on. 2007-10-16 Jakub Jelinek [BZ #5184] * time/strftime_l.c: Include stdbool.h. (my_strftime): New wrapper, old function renamed to... (__strftime_internal): ... new function. Add tzset_called argument, pass it down to recursive calls, don't call tzset () if already true, set to true after call to tzset (). --- libc/time/strftime_l.c.jj 2004-09-14 06:24:53.000000000 +0200 +++ libc/time/strftime_l.c 2007-10-16 19:44:17.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2004, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -84,6 +84,7 @@ extern char *tzname[]; # include # include # include +# include #else # ifndef HAVE_MEMCPY # define memcpy(d, s, n) bcopy ((s), (d), (n)) @@ -453,27 +454,9 @@ static CHAR_T const month_name[][10] = # define ut 0 #endif -#if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET - /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime. - Work around this bug by copying *tp before it might be munged. */ - size_t _strftime_copytm (char *, size_t, const char *, - const struct tm * ut_argument_spec_iso) __THROW; - size_t - my_strftime (s, maxsize, format, tp ut_argument) - CHAR_T *s; - size_t maxsize; - const CHAR_T *format; - const struct tm *tp; - ut_argument_spec - { - struct tm tmcopy; - tmcopy = *tp; - return _strftime_copytm (s, maxsize, format, &tmcopy ut_argument); - } -# undef my_strftime -# define my_strftime _strftime_copytm -#endif - +static size_t __strftime_internal (CHAR_T *, size_t, const CHAR_T *, + const struct tm *, bool ut_argument_spec_iso + LOCALE_PARAM_PROTO) __THROW; /* Write information from TP into S according to the format string FORMAT, writing no more that MAXSIZE characters @@ -481,12 +464,38 @@ static CHAR_T const month_name[][10] = characters written. If S is NULL, nothing will be written anywhere, so to determine how many characters would be written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */ + size_t my_strftime (s, maxsize, format, tp ut_argument LOCALE_PARAM) + CHAR_T *s; + size_t maxsize; + const CHAR_T *format; + const struct tm *tp; + ut_argument_spec + LOCALE_PARAM_DECL +{ +#if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET + /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime. + Work around this bug by copying *tp before it might be munged. */ + struct tm tmcopy; + tmcopy = *tp; + tp = &tmcopy; +#endif + return __strftime_internal (s, maxsize, format, tp, false + ut_argument LOCALE_ARG); +} +#ifdef _LIBC +libc_hidden_def (my_strftime) +#endif + +static size_t +__strftime_internal (s, maxsize, format, tp, tzset_called ut_argument + LOCALE_PARAM) CHAR_T *s; size_t maxsize; const CHAR_T *format; const struct tm *tp; + bool tzset_called; ut_argument_spec LOCALE_PARAM_DECL { @@ -559,7 +568,9 @@ my_strftime (s, maxsize, format, tp ut_a /* POSIX.1 requires that local time zone information is used as though strftime called tzset. */ # if HAVE_TZSET - tzset (); + if (!tzset_called) + tzset (); + tzset_called = true; # endif } #endif @@ -834,10 +845,12 @@ my_strftime (s, maxsize, format, tp ut_a subformat: { CHAR_T *old_start = p; - size_t len = my_strftime (NULL, (size_t) -1, subfmt, - tp ut_argument LOCALE_ARG); - add (len, my_strftime (p, maxsize - i, subfmt, - tp ut_argument LOCALE_ARG)); + size_t len = __strftime_internal (NULL, (size_t) -1, subfmt, + tp, tzset_called ut_argument + LOCALE_ARG); + add (len, __strftime_internal (p, maxsize - i, subfmt, + tp, tzset_called ut_argument + LOCALE_ARG)); if (to_uppcase) while (old_start < p) @@ -1409,9 +1422,6 @@ my_strftime (s, maxsize, format, tp ut_a *p = L_('\0'); return i; } -#ifdef _LIBC -libc_hidden_def (my_strftime) -#endif #ifdef emacs Jakub