Re: patch for wanna-build (sysinfo/getloadavg)
Robert Millan <zeratul2@wanadoo.es> writes:
> On Thu, Jul 24, 2003 at 12:14:57AM +0100, Roger Leigh wrote:
>> Robert Millan <zeratul2@wanadoo.es> writes:
>>
>> > Some days ago I posted this small patch for building wanna-build on
>> > GNU, and asked for revision, but didn't get any response.
>> >
>> > It attempts to replace the linux-specific sysinfo() with getloadavg(),
>> > but there's a type conversion issue and i'd like to make sure i did it
>> > correctly, please could anyone verify this:
>> >
>> > --- wanna-build.old/buildd-mail-wrapper.c 1999-07-21 14:53:22.000000000 +0200
>> > +++ wanna-build/buildd-mail-wrapper.c 2003-07-15 21:06:59.000000000 +0200
>> [...]
>>
>> This seems rather complex! Why not just do something like:
>> waittime = (long) (loadavg[0] / 16384) * 6 + 20;
>>
>> If you don't need SI_LOAD_SHIFT (Linux-specific??), it can probably be
>> even simpler.
>
> Can I cast a double to long like that? What kind of truncating happens if
> loadavg[0] is bigger than LONG_MAX? Does a division with 2^14 garantee it
> will fit nicely?
I've written a simple test program. It seems any cast from
double->long will set LONG_MIN/LONG_MAX if it would result in an
double->overflow. Thus,
+ if (loadavg[0] > LONG_MAX)
+ load = LONG_MAX;
+ else
+ load = (long) loadavg[0];
can be replaced with
load = (long) loadavg[0].
This was tested on Debian unstable (Linux 2.4.21 with glibc 2.3.1).
For some reason, I only ever got LONG_MIN to be returned, even when
the overflow was positive! I'm not sure if this is a problem with my
code, or a glibc bug, or whatever.
Here's the test program. You'll need to link with -lreadline.
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#include <readline/readline.h>
int main(void)
{
char *input = NULL;
double big;
long fixed;
while(1)
{
if (input)
{
free(input);
input = NULL;
}
input = readline("Enter a number: ");
big = strtod(input, NULL);
if (errno == ERANGE)
{
fprintf(stderr, "Number is out of range: ");
if (big == 0)
fprintf(stderr, "FP underflow\n");
else
fprintf(stderr, "FP overflow\n");
continue;
}
printf("double: %g\n", big);
fixed = (long) big;
if (fixed == LONG_MIN || fixed == LONG_MAX)
{
fprintf(stderr, "Number is out of range for type \"long\": ");
if (fixed == LONG_MIN)
fprintf(stderr, "LONG_MIN");
else
fprintf(stderr, "LONG_MAX");
fprintf(stderr, ": %ld\n", fixed);
continue;
}
printf("long: %ld\n", fixed);
}
return 0;
}
--
Roger Leigh
Printing on GNU/Linux? http://gimp-print.sourceforge.net/
GPG Public Key: 0x25BFB848 available on public keyservers
Reply to: