select/poll/usleep precision on FreeBSD vs Linux vs OSX
Luigi Rizzo
rizzo at iet.unipi.it
Thu Mar 1 00:44:04 UTC 2012
On Thu, Mar 01, 2012 at 11:33:46AM +1100, Bruce Evans wrote:
> On Wed, 29 Feb 2012, Luigi Rizzo wrote:
>
> >I have always been annoyed by the fact that FreeBSD rounds timeouts
> >in select/usleep/poll in very conservative ways, so i decided to
> >try how other systems behave in this respect. Attached is a simple
> >program that you should be able to compile and run on various OS
> >and see what happens.
>
> Many are broken, indeed.
>
> The simple program isn't attached.
attachment stripped by the mailing list, retrying to put it inline
(and comments on a followup email)
----
/*
* test minimum select time
*
* ./prog usec [method [duration]]
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <poll.h>
enum { M_SELECT =0 , M_POLL, M_USLEEP };
static const char *names[] = { "select", "poll", "usleep" };
int
main(int argc, char *argv[])
{
struct timeval ta, tb;
int usec = 1, total = 0, method = M_SELECT, count = 0;
if (argc > 1)
usec = atoi(argv[1]);
if (usec <= 0)
usec = 1;
else if (usec > 500000)
usec = 500000;
if (argc > 2) {
if (!strcmp(argv[2], "poll"))
method = M_POLL;
else if (!strcmp(argv[2], "usleep"))
method = M_USLEEP;
}
if (argc > 3)
total = atoi(argv[3]);
if (total < 1)
total = 1;
else if (total > 10)
total = 10;
fprintf(stderr, "testing %s for %dus over %ds\n",
names[method], usec, total);
gettimeofday(&ta, NULL);
for (;;) {
if (method == M_SELECT) {
struct timeval to = { 0, usec };
select(0, NULL, NULL, NULL, &to);
} else if (method == M_POLL) {
poll(NULL, 0, usec/1000);
} else {
usleep(usec);
}
count++;
gettimeofday(&tb, NULL);
timersub(&tb, &ta, &tb);
if (tb.tv_sec > total)
break;
}
fprintf(stderr, "%dus actually took %dus\n",
usec, (int)(tb.tv_sec * 1000000 + tb.tv_usec) / count );
return 0;
}
-----
More information about the freebsd-arch
mailing list