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>