Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 05 Aug 1997 11:09:41 -0400 (EDT)
From:      "Mark J. Taylor" <mtaylor@cybernet.com>
To:        "Jamil J. Weatherbee" <jamil@counterintelligence.ml.org>, freebsd-hackers@FreeBSD.ORG
Cc:        freebsd-realtime@FreeBSD.ORG
Subject:   RE: ?? The right way to do a microsecond resolution wait
Message-ID:  <XFMail.970805110941.mtaylor@cybernet.com>
In-Reply-To: <Pine.BSF.3.96.970805013644.501A-100000@counterintelligence.ml.org>

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

I've had compatibility problems with this kind of code in a 'real-time'
environment.  There are all kinds of signals going on.  Some systems
don't restart after an interrupted system call (even if you set the signal
up as such).  And many systems use the itimer for other things (like alarm()).
Having it yanked out from under you is kinda annoying.

I wrote a sleeper routine using select(), as the man page for usleep() suggests.
It does not take any 'extra' system resources (like a valuable timer channel).


For the SGI/IRIX version, I used nanosleep().


If you are interested in the 'select()' version of usleep(), here it is
(free of charge and worth every penny):


double timeGetTime(void)
{
    struct timeval tv;
    double now;

    gettimeofday(&tv, NULL);
    now = (double) tv.tv_sec*1000L+(double) tv.tv_usec/1000;
    return(now);
}


void Sleep(long sleep_msec)
{
#if !defined(vxworks) && !defined(sgi)
    struct timeval tv;
#else
    struct timespec tv;
#endif  /* !vxworks */
    double wakeup_msec, now_msec;

    now_msec = timeGetTime();
    wakeup_msec = now_msec + sleep_msec;
    while (now_msec=timeGetTime(), now_msec < wakeup_msec) {
        tv.tv_sec = (wakeup_msec - now_msec)/1000L;
#if !defined(vxworks) && !defined(sgi)
        tv.tv_usec = ((wakeup_msec-now_msec)-(tv.tv_sec*1000L))*1000L;
        select(0 , NULL, NULL, NULL, &tv);
#else
        tv.tv_nsec = ((wakeup_msec-now_msec)-(tv.tv_sec*1000L))*1000000L;
        nanosleep(&tv, NULL);
#endif  /* !vxworks */
    }

}



On 05-Aug-97 "Jamil J. Weatherbee" wrote:
>
>Is this the best way to do a microsecond resolution wait under freebsd 
>(usleep only appears good to 10,000 microseconds). Doing small waits is an
>important part of realtime software -- something that it would be
>interesting to see addressed, particularily making a usleep that actually
>sleeps microseconds.
>
>
>With the following (unless i am off my rocker) i can get a 4 microsecond
>wait on a ppro 180, a 25 microsecond wait on a pentium 100, and a 12
>microsecond wait on a nexgen-100.
>
>What I want to know is this the best way to get a highly accurate wait in
>a thread of execution, is this even doing what I think it is, and why
>doesnt usleep do something like this? I guess I could use it to output a
>square wave on a paralell pin and look at that with an oscilliscope. For
>the application I use it for the usleeps for the significant portion of
>the time bring the cpu% down from 99% to about 1.5% pretty significant.
>
>
>
>#define USLEEP_RESOLUTION 10000
>
>/* Don't use for times > 2000 seconds */
>void rsleep (long usecs)
>{
>  struct timeval begin_time, cur_time;
>  long elapsed, utm;
>  
>  gettimeofday (&begin_time, NULL);   /* record the starting time */
>
>  if (utm = (usecs / USLEEP_RESOLUTION)*USLEEP_RESOLUTION) usleep (utm);
>  
>   do gettimeofday (&cur_time, NULL);  /* get the current time */
>   while (((cur_time.tv_sec - begin_time.tv_sec) * 1000000 +
>              (cur_time.tv_usec - begin_time.tv_usec)) < usecs);
>     }

--------------------------------------------------------------------
Mark J. Taylor                                  Network R&D Manager
Cybernet Systems                                mtaylor@cybernet.com
727 Airport Blvd.                               PHONE (313) 668-2567
Ann Arbor, MI  48108                            FAX   (313) 668-8780
--------------------------------------------------------------------



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