Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 Sep 1999 18:45:58 -0400 (EDT)
From:      Mikhail Teterin <mi@misha.cisco.com>
To:        FreeBSD-gnats-submit@freebsd.org
Cc:        lawlopez@cisco.com
Subject:   kern/13644: select(2) timer inaccurate, especially with -pthread
Message-ID:  <199909082245.SAA11837@misha.cisco.com>

next in thread | raw e-mail | index | archive | help

>Number:         13644
>Category:       kern
>Synopsis:       select(2) timer inaccurate, especially with -pthread
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Sep  8 15:50:00 PDT 1999
>Closed-Date:
>Last-Modified:
>Originator:     Mikhail Teterin
>Release:        FreeBSD 3.2-STABLE i386
>Organization:
Virtual Estates, Inc.
>Environment:

>Description:

	The select's man-page says:
		If  timeout  is  a   non-nil  pointer,  it  specifies  a
		maximum interval to wait  for the selection to complete.
		If  timeout   is  a  nil  pointer,   the  select  blocks
		indefinitely.  To effect  a poll,  the timeout  argument
		should  be non-nil,  pointing to  a zero-valued  timeval
		structure.

	In fact, the select on an empty list of file descriptors -- as
	done in TCL's Tcl_Sleep, for example, will always add about 10
	msec and another 10 if compiled with -pthread.

>How-To-Repeat:

Consider a program:

#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h> 

struct timeval t1, t2, timeout;

main() {
	timeout.tv_sec = 0;
	for(timeout.tv_usec = 2000; timeout.tv_usec < 40000; timeout.tv_usec += 1000) {
		if(gettimeofday(&t1, NULL)) perror("gettimeofday");
		select(0, NULL, NULL, NULL, &timeout);
		if(gettimeofday(&t2, NULL)) perror("gettimeofday");
		printf("Slept for %d instead of %d microseconds\n",
			t2.tv_usec - t1.tv_usec +
				(t2.tv_sec - t1.tv_sec)*1000*1000,
			timeout.tv_usec);
	}
	if(gettimeofday(&t1, NULL)) perror("gettimeofday");
	if(gettimeofday(&t2, NULL)) perror("gettimeofday");
	printf("The gettimeofday overhead is %d usec\n",
		t2.tv_usec - t1.tv_usec);
}

The output of this program compiled as usual is:

	Slept for 11248 instead of 2000 microseconds
	Slept for 19507 instead of 3000 microseconds
	Slept for 20103 instead of 4000 microseconds
	Slept for 19939 instead of 5000 microseconds
	Slept for 19910 instead of 6000 microseconds
	Slept for 19984 instead of 7000 microseconds
	Slept for 19986 instead of 8000 microseconds
	Slept for 20058 instead of 9000 microseconds
	Slept for 19980 instead of 10000 microseconds
	Slept for 29905 instead of 11000 microseconds
	Slept for 30010 instead of 12000 microseconds
	Slept for 29970 instead of 13000 microseconds
	Slept for 29988 instead of 14000 microseconds
	Slept for 30045 instead of 15000 microseconds
	Slept for 30011 instead of 16000 microseconds
	Slept for 29887 instead of 17000 microseconds
	Slept for 29991 instead of 18000 microseconds
	Slept for 29970 instead of 19000 microseconds
	Slept for 30067 instead of 20000 microseconds
	Slept for 39947 instead of 21000 microseconds
	Slept for 40019 instead of 22000 microseconds
	Slept for 39910 instead of 23000 microseconds
	Slept for 39981 instead of 24000 microseconds
	Slept for 40055 instead of 25000 microseconds
	Slept for 39914 instead of 26000 microseconds
	Slept for 40057 instead of 27000 microseconds
	Slept for 39910 instead of 28000 microseconds
	Slept for 39979 instead of 29000 microseconds
	Slept for 40054 instead of 30000 microseconds
	Slept for 49973 instead of 31000 microseconds
	Slept for 49993 instead of 32000 microseconds
	Slept for 50002 instead of 33000 microseconds
	Slept for 50000 instead of 34000 microseconds
	Slept for 49972 instead of 35000 microseconds
	Slept for 49994 instead of 36000 microseconds
	Slept for 50069 instead of 37000 microseconds
	Slept for 49904 instead of 38000 microseconds
	Slept for 49966 instead of 39000 microseconds
	The gettimeofday overhead is 5 usec

and with the ``-pthread'' flag:

	Slept for 21687 instead of 2000 microseconds
	Slept for 29719 instead of 3000 microseconds
	Slept for 30010 instead of 4000 microseconds
	Slept for 29971 instead of 5000 microseconds
	Slept for 29986 instead of 6000 microseconds
	Slept for 30050 instead of 7000 microseconds
	Slept for 29987 instead of 8000 microseconds
	Slept for 29911 instead of 9000 microseconds
	Slept for 29974 instead of 10000 microseconds
	Slept for 29990 instead of 11000 microseconds
	Slept for 40072 instead of 12000 microseconds
	Slept for 40015 instead of 13000 microseconds
	Slept for 39904 instead of 14000 microseconds
	Slept for 39974 instead of 15000 microseconds
	Slept for 39987 instead of 16000 microseconds
	Slept for 39989 instead of 17000 microseconds
	Slept for 40187 instead of 18000 microseconds
	Slept for 39783 instead of 19000 microseconds
	Slept for 39970 instead of 20000 microseconds
	Slept for 39987 instead of 21000 microseconds
	Slept for 49996 instead of 22000 microseconds
	Slept for 49967 instead of 23000 microseconds
	Slept for 49996 instead of 24000 microseconds
	Slept for 49972 instead of 25000 microseconds
	Slept for 50143 instead of 26000 microseconds
	Slept for 49825 instead of 27000 microseconds
	Slept for 49994 instead of 28000 microseconds
	Slept for 49973 instead of 29000 microseconds
	Slept for 49996 instead of 30000 microseconds
	Slept for 49970 instead of 31000 microseconds
	Slept for 59979 instead of 32000 microseconds
	Slept for 59991 instead of 33000 microseconds
	Slept for 60000 instead of 34000 microseconds
	Slept for 60000 instead of 35000 microseconds
	Slept for 59979 instead of 36000 microseconds
	Slept for 59983 instead of 37000 microseconds
	Slept for 59994 instead of 38000 microseconds
	Slept for 60119 instead of 39000 microseconds
	The gettimeofday overhead is 5 usec

Using usleep instead of select gives pretty similar numbers :(

>Fix:

	The numbers appear to be constant, so one can specify a smaller
	timeout to actually get it right. But the values will have to be
	different with and without the -pthread flag.

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




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