Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Mar 2012 02:02:19 +0100
From:      Luigi Rizzo <rizzo@iet.unipi.it>
To:        Bruce Evans <brde@optusnet.com.au>
Cc:        arch@FreeBSD.org
Subject:   Re: select/poll/usleep precision on FreeBSD vs Linux vs OSX
Message-ID:  <20120301010219.GA14508@onelab2.iet.unipi.it>
In-Reply-To: <20120301071145.O879@besplex.bde.org>
References:  <20120229194042.GA10921@onelab2.iet.unipi.it> <20120301071145.O879@besplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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;
}
-----



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120301010219.GA14508>