Obtained from: my old fix for 1.1.5
Improve hzto(): Round up instead of down and then add 1 tick. This fixes sleep(1) sometimes sleeping for < 1 second and usleep(10000) sometimes sleeping for as little as 1 usec + syscall time. Don't do all the calculations at splhigh(). Don't depend on `tick' being a multiple of 1000. Don't lose accuracy for `sec' between 0x7fffffff / 1000 - 1000 and 0x7fffffff / hz. Don't assume that longs are 32 bits or that ints have the same size as longs.
This commit is contained in:
parent
d2ee1a1856
commit
6976af69e8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=5081
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
|
||||
* $Id: kern_clock.c,v 1.9 1994/10/02 17:35:10 phk Exp $
|
||||
* $Id: kern_clock.c,v 1.10 1994/10/16 03:52:12 wollman Exp $
|
||||
*/
|
||||
|
||||
/* Portions of this software are covered by the following: */
|
||||
@ -748,28 +748,54 @@ int
|
||||
hzto(tv)
|
||||
struct timeval *tv;
|
||||
{
|
||||
register long ticks, sec;
|
||||
register unsigned long ticks;
|
||||
register long sec, usec;
|
||||
int s;
|
||||
|
||||
/*
|
||||
* If number of milliseconds will fit in 32 bit arithmetic,
|
||||
* then compute number of milliseconds to time and scale to
|
||||
* ticks. Otherwise just compute number of hz in time, rounding
|
||||
* times greater than representible to maximum value.
|
||||
* If the number of usecs in the whole seconds part of the time
|
||||
* difference fits in a long, then the total number of usecs will
|
||||
* fit in an unsigned long. Compute the total and convert it to
|
||||
* ticks, rounding up and adding 1 to allow for the current tick
|
||||
* to expire. Rounding also depends on unsigned long arithmetic
|
||||
* to avoid overflow.
|
||||
*
|
||||
* Delta times less than 25 days can be computed ``exactly''.
|
||||
* Maximum value for any timeout in 10ms ticks is 250 days.
|
||||
* Otherwise, if the number of ticks in the whole seconds part of
|
||||
* the time difference fits in a long, then convert the parts to
|
||||
* ticks separately and add, using similar rounding methods and
|
||||
* overflow avoidance. This method would work in the previous
|
||||
* case but it is slightly slower and assumes that hz is integral.
|
||||
*
|
||||
* Otherwise, round the time difference down to the maximum
|
||||
* representable value.
|
||||
*
|
||||
* If ints have 32 bits, then the maximum value for any timeout in
|
||||
* 10ms ticks is 248 days.
|
||||
*/
|
||||
s = splhigh();
|
||||
s = splclock();
|
||||
sec = tv->tv_sec - time.tv_sec;
|
||||
if (sec <= 0x7fffffff / 1000 - 1000)
|
||||
ticks = ((tv->tv_sec - time.tv_sec) * 1000 +
|
||||
(tv->tv_usec - time.tv_usec) / 1000) / (tick / 1000);
|
||||
else if (sec <= 0x7fffffff / hz)
|
||||
ticks = sec * hz;
|
||||
else
|
||||
ticks = 0x7fffffff;
|
||||
usec = tv->tv_usec - time.tv_usec;
|
||||
splx(s);
|
||||
if (usec < 0) {
|
||||
sec--;
|
||||
usec += 1000000;
|
||||
}
|
||||
if (sec < 0) {
|
||||
#ifdef DIAGNOSTIC
|
||||
printf("hzto: negative time difference %ld sec %ld usec\n",
|
||||
sec, usec);
|
||||
#endif
|
||||
ticks = 1;
|
||||
} else if (sec <= LONG_MAX / 1000000)
|
||||
ticks = (sec * 1000000 + (unsigned long)usec + (tick - 1))
|
||||
/ tick + 1;
|
||||
else if (sec <= LONG_MAX / hz)
|
||||
ticks = sec * hz
|
||||
+ ((unsigned long)usec + (tick - 1)) / tick + 1;
|
||||
else
|
||||
ticks = LONG_MAX;
|
||||
if (ticks > INT_MAX)
|
||||
ticks = INT_MAX;
|
||||
return (ticks);
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
|
||||
* $Id: kern_clock.c,v 1.9 1994/10/02 17:35:10 phk Exp $
|
||||
* $Id: kern_clock.c,v 1.10 1994/10/16 03:52:12 wollman Exp $
|
||||
*/
|
||||
|
||||
/* Portions of this software are covered by the following: */
|
||||
@ -748,28 +748,54 @@ int
|
||||
hzto(tv)
|
||||
struct timeval *tv;
|
||||
{
|
||||
register long ticks, sec;
|
||||
register unsigned long ticks;
|
||||
register long sec, usec;
|
||||
int s;
|
||||
|
||||
/*
|
||||
* If number of milliseconds will fit in 32 bit arithmetic,
|
||||
* then compute number of milliseconds to time and scale to
|
||||
* ticks. Otherwise just compute number of hz in time, rounding
|
||||
* times greater than representible to maximum value.
|
||||
* If the number of usecs in the whole seconds part of the time
|
||||
* difference fits in a long, then the total number of usecs will
|
||||
* fit in an unsigned long. Compute the total and convert it to
|
||||
* ticks, rounding up and adding 1 to allow for the current tick
|
||||
* to expire. Rounding also depends on unsigned long arithmetic
|
||||
* to avoid overflow.
|
||||
*
|
||||
* Delta times less than 25 days can be computed ``exactly''.
|
||||
* Maximum value for any timeout in 10ms ticks is 250 days.
|
||||
* Otherwise, if the number of ticks in the whole seconds part of
|
||||
* the time difference fits in a long, then convert the parts to
|
||||
* ticks separately and add, using similar rounding methods and
|
||||
* overflow avoidance. This method would work in the previous
|
||||
* case but it is slightly slower and assumes that hz is integral.
|
||||
*
|
||||
* Otherwise, round the time difference down to the maximum
|
||||
* representable value.
|
||||
*
|
||||
* If ints have 32 bits, then the maximum value for any timeout in
|
||||
* 10ms ticks is 248 days.
|
||||
*/
|
||||
s = splhigh();
|
||||
s = splclock();
|
||||
sec = tv->tv_sec - time.tv_sec;
|
||||
if (sec <= 0x7fffffff / 1000 - 1000)
|
||||
ticks = ((tv->tv_sec - time.tv_sec) * 1000 +
|
||||
(tv->tv_usec - time.tv_usec) / 1000) / (tick / 1000);
|
||||
else if (sec <= 0x7fffffff / hz)
|
||||
ticks = sec * hz;
|
||||
else
|
||||
ticks = 0x7fffffff;
|
||||
usec = tv->tv_usec - time.tv_usec;
|
||||
splx(s);
|
||||
if (usec < 0) {
|
||||
sec--;
|
||||
usec += 1000000;
|
||||
}
|
||||
if (sec < 0) {
|
||||
#ifdef DIAGNOSTIC
|
||||
printf("hzto: negative time difference %ld sec %ld usec\n",
|
||||
sec, usec);
|
||||
#endif
|
||||
ticks = 1;
|
||||
} else if (sec <= LONG_MAX / 1000000)
|
||||
ticks = (sec * 1000000 + (unsigned long)usec + (tick - 1))
|
||||
/ tick + 1;
|
||||
else if (sec <= LONG_MAX / hz)
|
||||
ticks = sec * hz
|
||||
+ ((unsigned long)usec + (tick - 1)) / tick + 1;
|
||||
else
|
||||
ticks = LONG_MAX;
|
||||
if (ticks > INT_MAX)
|
||||
ticks = INT_MAX;
|
||||
return (ticks);
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
|
||||
* $Id: kern_clock.c,v 1.9 1994/10/02 17:35:10 phk Exp $
|
||||
* $Id: kern_clock.c,v 1.10 1994/10/16 03:52:12 wollman Exp $
|
||||
*/
|
||||
|
||||
/* Portions of this software are covered by the following: */
|
||||
@ -748,28 +748,54 @@ int
|
||||
hzto(tv)
|
||||
struct timeval *tv;
|
||||
{
|
||||
register long ticks, sec;
|
||||
register unsigned long ticks;
|
||||
register long sec, usec;
|
||||
int s;
|
||||
|
||||
/*
|
||||
* If number of milliseconds will fit in 32 bit arithmetic,
|
||||
* then compute number of milliseconds to time and scale to
|
||||
* ticks. Otherwise just compute number of hz in time, rounding
|
||||
* times greater than representible to maximum value.
|
||||
* If the number of usecs in the whole seconds part of the time
|
||||
* difference fits in a long, then the total number of usecs will
|
||||
* fit in an unsigned long. Compute the total and convert it to
|
||||
* ticks, rounding up and adding 1 to allow for the current tick
|
||||
* to expire. Rounding also depends on unsigned long arithmetic
|
||||
* to avoid overflow.
|
||||
*
|
||||
* Delta times less than 25 days can be computed ``exactly''.
|
||||
* Maximum value for any timeout in 10ms ticks is 250 days.
|
||||
* Otherwise, if the number of ticks in the whole seconds part of
|
||||
* the time difference fits in a long, then convert the parts to
|
||||
* ticks separately and add, using similar rounding methods and
|
||||
* overflow avoidance. This method would work in the previous
|
||||
* case but it is slightly slower and assumes that hz is integral.
|
||||
*
|
||||
* Otherwise, round the time difference down to the maximum
|
||||
* representable value.
|
||||
*
|
||||
* If ints have 32 bits, then the maximum value for any timeout in
|
||||
* 10ms ticks is 248 days.
|
||||
*/
|
||||
s = splhigh();
|
||||
s = splclock();
|
||||
sec = tv->tv_sec - time.tv_sec;
|
||||
if (sec <= 0x7fffffff / 1000 - 1000)
|
||||
ticks = ((tv->tv_sec - time.tv_sec) * 1000 +
|
||||
(tv->tv_usec - time.tv_usec) / 1000) / (tick / 1000);
|
||||
else if (sec <= 0x7fffffff / hz)
|
||||
ticks = sec * hz;
|
||||
else
|
||||
ticks = 0x7fffffff;
|
||||
usec = tv->tv_usec - time.tv_usec;
|
||||
splx(s);
|
||||
if (usec < 0) {
|
||||
sec--;
|
||||
usec += 1000000;
|
||||
}
|
||||
if (sec < 0) {
|
||||
#ifdef DIAGNOSTIC
|
||||
printf("hzto: negative time difference %ld sec %ld usec\n",
|
||||
sec, usec);
|
||||
#endif
|
||||
ticks = 1;
|
||||
} else if (sec <= LONG_MAX / 1000000)
|
||||
ticks = (sec * 1000000 + (unsigned long)usec + (tick - 1))
|
||||
/ tick + 1;
|
||||
else if (sec <= LONG_MAX / hz)
|
||||
ticks = sec * hz
|
||||
+ ((unsigned long)usec + (tick - 1)) / tick + 1;
|
||||
else
|
||||
ticks = LONG_MAX;
|
||||
if (ticks > INT_MAX)
|
||||
ticks = INT_MAX;
|
||||
return (ticks);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user