Date: Tue, 11 Apr 2006 18:36:20 +0100 (BST) From: martin0406@lispworks.com To: freebsd-threads@freebsd.org Subject: pthread timing granularity with compat5x on FreeBSD 6.0 Message-ID: <200604111736.k3BHaK4k099972@lwfs1-cam.cam.lispworks.com>
next in thread | raw e-mail | index | archive | help
Hi there, Is there some known issue with the granularity of scheduling when running FreeBSD 5.x executables on FreeBSD 6.0 with compat5x? The sample code below, describes the problem. Any clues could be appreciated. My config is as follows: kern.osrelease: 6.0-RELEASE kern.osrevision: 199506 kern.version: FreeBSD 6.0-RELEASE #0: Thu Nov 3 09:36:13 UTC 2005 root@x64.samsco.home:/usr/obj/usr/src/sys/GENERIC hw.model: AMD Athlon(tm) 64 X2 Dual Core Processor 4400+ ------------------------------------------------------------------------------ /* This code demonstrate a problem with sleeping on FreeBSD 6.0 when running code that was compiled on FreeBSD 5.x, when another pthread is busy. The function LoopingSignaler tries to sleep for a fixed period of time. When this is compiled on FreeBSD 5 and run on FreeBSD 5, it sleeps for approximately the right time. When it is compiled on FreeBSD 5 and run on FreeBSD 6 it seems to sleep in "granules" of ~157 ms when competing for CPU time with another thread. To test: compile on FreeBSD 5 by gcc -pthread we.c run on FreeBSD 6 a.out [millseconds] The test starts a pthread that sleeps in a loop reporting the length of time it slept. The main thread then calls usleep for a while, and finally starts to use the cpu heavily (empty while loop). As long it is usleeping, the sleep time of the other pthread is correct. Once it starts using cpu, the sleep time increase to the granule boundary. The sleeping thread prints the time it slept in miliiseconds, first in cpu time (by times(2), and then elapsed time by gettimeofday(2)). By default it tries to sleep for 50 milliseocnds. */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <pthread.h> #include <errno.h> #include <sys/time.h> #include <sys/times.h> #include <unistd.h> #include <signal.h> void *LoopingSignaler(void *arg) { long tick_per_second = sysconf(_SC_CLK_TCK); clock_t start_sleep; struct timeval tm; int count = 100; int millis = (int) arg; while(count--) { int use_select = count & 1; struct timeval in; struct timespec ain, aout; struct tms tmbuf; in.tv_sec = 0; in.tv_usec = millis * 1000; ain.tv_sec = 0; ain.tv_nsec = millis * 1000000; /* Record the start times */ times(&tmbuf); gettimeofday(&tm, NULL); start_sleep = tmbuf.tms_utime; /* Sleep in two different ways. */ if (use_select) select(1, NULL , NULL , NULL, &in); else nanosleep(&ain, &aout); /* Display time spent sleeping */ { clock_t diff; long millis_sleep, millis_real; struct timeval etm; times(&tmbuf); gettimeofday(&etm, NULL); diff = tmbuf.tms_utime - start_sleep; millis_sleep = (diff * 1000) / tick_per_second; { int secdiff = etm.tv_sec - tm.tv_sec; int micsdiff = etm.tv_usec - tm.tv_usec; millis_real = (micsdiff + secdiff * 1000000) / 1000; } printf("%s slept for %d / %d\n", use_select ? " select": "nanosleep", millis_sleep, millis_real); } } exit(0); } int main(int argc, char **argv) { int millis = 50; pthread_t pt; pthread_attr_t attr; int res; if (argc > 1) millis = atoi(argv[1]); pthread_attr_init(&attr); res = pthread_create(&pt, &attr, &LoopingSignaler, (void *)millis); /* initial test with the main thread idle */ usleep(millis * 1000 * 20); printf("\nfinished usleep\n\n"); /* second test with the main thread busy */ while(1) {}; return 0; } ------------------------------------------------------------------------------ __Martin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200604111736.k3BHaK4k099972>