W3C home > Mailing lists > Public > www-lib@w3.org > October to December 2001

Re: time_t, ms_t, overflow issues

From: Phil Nitschke <Phil.Nitschke@youramigo.com>
Date: 22 Nov 2001 13:08:59 +1030
To: Ingo Krabbe <i.krabbe@dokom.net>
Cc: <www-lib@w3.org>
Message-ID: <lxelmr4ji4.fsf@YourAmigo.com>
>>>>> "IK" == Ingo Krabbe <ikrabbe@earthling.net> writes:

Thanks for your response, Ingo.  My last set of patches to the library
appear to have been ignored, so it is nice to get a reply this time.

My comments are attached below.

  IK> On 21 Nov 2001, Phil Nitschke wrote:

  >> Hi all,
  >> 
  >> With many architectures still implementing an ms_t in a 32-bit
  >> integer, isn't HTGetTimeInMillis() going to suffer fairly badly
  >> from arithmetic overflow?
  >> 
  >> struct timeval tp; gettimeofday(&tp, NULL); return(tp.tv_sec *
  >> 1000) + (tp.tv_usec / 1000);
  >> 
  >> (This message was written about 1006328788000 milliseconds after
  >> Epoch.)
  >> 
  >> Given that, can any of the code in HTDoConnect() that calls
  >> HTDNS_updateWeigths() be trusted?  Similarly, won't there be
  >> problems with other code that uses ms_t?

  >> (I search the archives, but could not fund these topics being
  >> discussed before.)
  >> 

  IK> This problem was discussed on several systems mailing lists. And
  IK> that's the right point to discuss about that. It is the operating
  IK> systems part to implement gettimeofday in a way that the result
  IK> fits into the data fields.  Of course if you put that numbers into
  IK> a new one you have to count your bits. To display a 32bit time_t
  IK> in milliseconds we need a value which is 1000 times bigger. That
  IK> are about 10 bits. So we need about 42 bits.

  IK> But is it really usefull to calculate with such values ? Results
  IK> in quantum mechanics have up to 15 good digits in very common
  IK> experiments like the speed of light. If you are searching an ant
  IK> you won't look at satellite images, but you will take a magnifing
  IK> glass that concentrates your angle of sight to the near
  IK> surroundings of the ant.

<SNIP> <SNIP> <SNIP>

  IK> If you care for the scale on which you look at a problem, you will
  IK> get enough digits from HTGetTimeInMillis to express your
  IK> results. And if your really need the age of Napoleon in
  IK> milliseconds you should express it as x hours and y milliseconds.

I'm not interested in the age of Napoleon, and I'm not quite the orator
that you are; I'm just a simple C programmer.  So I'll let the source do
the talking.  

Attached below is a program that shows that several times a year, people
who run programs compiled against libwww will get erroneous results.
libwww suffers from PMT (possibly mediocre timing), and you have to
avoid it on those days.

The program basically speeds up time by taking todays date as a starting
point and then incrementing seconds until a problem appears.  The
program uses the same _sort_ of arithmetic and data structures that are
used in many places in libwww.

  >> Why does the HTNet structure need a connecttime field?  Isn't it
  >> asking for trouble to have a time_t connecttime field when the
  >> HTHost structure has a similarly named field implemented as a ms_t?

Ingo's reply did not address this issue... Does anyone else care to comment?


-- 
Phil   +----------------------------------------------------------+(\
     _/_)    YourAmigo Pty Ltd     http://www.YourAmigo.com/      |( \
  _/// /   _ =================  Phone Intl.: +61-8-8211-9211  _   |_) )_
 (((( (|  /_)             mailto:Phil.Nitschke@YourAmigo.com (_\  |/ /)))
  \\\\ \_/ / Address:                            <standard>   \ \_/ ////
   \      /    80 Gilbert Street, Adelaide      <disclaimers>  \      /
    )   _/     South Australia  5000  Australia    <apply>      \_   (
   /   /----------------------------------------------------------\   \
  /   /                                                            \   \

Results:

    Overflow broke at Wed Dec 26 08:25:14 2001
     Performing comparison of: 418 and 4294966714 !!
    Overflow broke at Thu Feb 14 01:28:01 2002
     Performing comparison of: 122 and 4294966418 !!
    Overflow broke at Thu Apr  4 17:30:49 2002
     Performing comparison of: 826 and 4294967122 !!
    Overflow broke at Fri May 24 10:33:36 2002
     Performing comparison of: 530 and 4294966826 !!
    Overflow broke at Sat Jul 13 03:36:23 2002
     Performing comparison of: 234 and 4294966530 !!
    Overflow broke at Sat Aug 31 20:39:11 2002
     Performing comparison of: 938 and 4294967234 !!
    Overflow broke at Sun Oct 20 13:41:58 2002
     Performing comparison of: 642 and 4294966938 !!
    Overflow broke at Mon Dec  9 07:44:45 2002
     Performing comparison of: 346 and 4294966642 !!
    Overflow broke at Tue Jan 28 00:47:32 2003
     Performing comparison of: 50 and 4294966346 !!
    Overflow broke at Tue Mar 18 17:50:20 2003
     Performing comparison of: 754 and 4294967050 !!

Platform:

    Linux strife 2.4.4 #1 Tue May 22 11:04:41 CST 2001 i686 unknown

Source:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>

typedef unsigned long ms_t;

ms_t HTGetTimeInMillis2 (const struct timeval * tp)
{
  return(tp->tv_sec * 1000) + (tp->tv_usec / 1000);
}

void do_tests (struct timeval * tp)
{
  ms_t prev_time, new_time;

  prev_time = HTGetTimeInMillis2 (tp);
  tp->tv_sec += 3;

  for (;;)
    {
      tp->tv_sec++;
      new_time = HTGetTimeInMillis2 (tp);

      if (new_time <= prev_time)
	break;

      prev_time = new_time;
    }

  printf ("Overflow broke at %s Performing comparison of: %lu and %lu !!\n",
	  ctime ((time_t *)&tp->tv_sec), new_time, prev_time);
}

int main (void)
{
  int i;
  struct timeval tp;

  gettimeofday(&tp, NULL);

  for (i = 0; i < 10; i++)
    do_tests (&tp);

  exit (0);
}
Received on Wednesday, 21 November 2001 21:39:24 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 23 April 2007 18:18:40 GMT