help-glpk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-glpk] things I don't understand in src/env/time.c + bugs + sug


From: Heinrich Schuchardt
Subject: Re: [Help-glpk] things I don't understand in src/env/time.c + bugs + suggested patch
Date: Sat, 28 Jan 2017 14:35:34 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Icedove/45.6.0

On 01/28/2017 01:31 PM, David Monniaux wrote:
> Over glpk-4.61
> 
> src/env/time.c contains:
> 
> double glp_time(void)
> {     struct timeval tv;
>       struct tm *tm;
>       int j;
>       double t;
>       gettimeofday(&tv, NULL);
>       tm = gmtime(&tv.tv_sec);
>       j = jday(tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year);
>       xassert(j >= 0);
>       t = ((((double)(j - EPOCH) * 24.0 + (double)tm->tm_hour) * 60.0 +
>          (double)tm->tm_min) * 60.0 + (double)tm->tm_sec) * 1000.0 +
>          (double)(tv.tv_usec / 1000);
>       return t;
> }
> 
> This code suffers from several problems:
> - The division tv.tv_usec / 1000 is integer division, then converted to
> double; why not simply multiply by 1E-3, which is more precise?
> - It uses gmtime, which is not reentrant (as opposed to gmtime_r). In
> fact, my attention was called to this function because of error reports
> by Valgrind's DRD race condition analyser ran on code using glpk from
> different threads.

It is a shame that glibc does not define _tmbuf as thread local memory.

gmtime_r is not C standard but POSIX specific.
The relevant C11 function is gmtime_s.

It should be supported with GCC 4.7 and later.
So probably we should check for gmtime_s in configure.ac.

> 
> I also do not understand why it is useful to use such a function,
> calling jday() to convert Julian days, whereas the following returns the
> same result:
> 
> double glp_time(void)
> {     struct timeval tv;
>        gettimeofday(&tv, NULL);
>       return tv.tv_sec + 1E3 * tv.tv_usec * 1E-3;

1E3 * 1E-3 = 1.
You wouldn't add seconds and microseconds without scaling.

tv_sec is counting from 0 to 59 (or 60 if you have leap second).
Why do you want to return the same values for 11:01:00 and 11:02:00?

> }
> 
> What am I missing?
> 
> If I'm missing nothing, this patch simplifies the code:
> 
> --- glpk-4.61-orig/src/env/time.c    2017-01-22 08:00:00.000000000 +0100
> +++ glpk-4.61-time-patched/src/env/time.c    2017-01-28
> 13:09:07.367464607 +0100
> @@ -53,17 +53,8 @@
>  
>  double glp_time(void)
>  {     struct timeval tv;
> -      struct tm *tm;
> -      int j;
> -      double t;
>        gettimeofday(&tv, NULL);
> -      tm = gmtime(&tv.tv_sec);
> -      j = jday(tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year);
> -      xassert(j >= 0);
> -      t = ((((double)(j - EPOCH) * 24.0 + (double)tm->tm_hour) * 60.0 +
> -         (double)tm->tm_min) * 60.0 + (double)tm->tm_sec) * 1000.0 +
> -         (double)(tv.tv_usec / 1000);
> -      return t;
> +      return tv.tv_sec + 1E3 * tv.tv_usec * 1E-3;
>  }
>  
>  /* MS Windows version *************************************************/
> @@ -92,17 +83,7 @@
>  #include <time.h>
>  
>  double glp_time(void)
> -{     time_t timer;
> -      struct tm *tm;
> -      int j;
> -      double t;
> -      timer = time(NULL);
> -      tm = gmtime(&timer);
> -      j = jday(tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year);
> -      xassert(j >= 0);
> -      t = ((((double)(j - EPOCH) * 24.0 + (double)tm->tm_hour) * 60.0 +
> -         (double)tm->tm_min) * 60.0 + (double)tm->tm_sec) * 1000.0;
> -      return t;
> +{      return time(NULL) * 1E3;
>  }
>  
>  #endif
> 
> Regards
> 
> 
> 
> _______________________________________________
> Help-glpk mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/help-glpk
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]