Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 26 Jan 2004 12:59:39 -0800
From:      steve@Watt.COM (Steve Watt)
To:        hackers@freebsd.org
Cc:        julian@elischer.org
Subject:   Re: send(2) does not block, send(2) man page wrong?
Message-ID:  <200401262059.i0QKxdIi038551@wattres.Watt.COM>
In-Reply-To: <Pine.BSF.4.21.0401261052590.76985-100000@InterJet.elischer.org>
References:  <E1Al8xj-0002aR-00@roo>

next in thread | previous in thread | raw e-mail | index | archive | help
julian@elischer.org wrote:
>do what ping does (ping -f)
>when you get an ENOBUFS do a usleep for 1 mSec.
>and then send it again.

So how, exactly, do you actually sleep for 1mSec?  I recently did some
experiments using nanosleep(), and it seems that the minimum sleep time
is 2 / HZ.  I.e. ask for 100nS, get 20mS (on a 10mS-ticking system).

Mind you, that behavior is precisely aligned with what POSIX says should
happen, since nanosleep() is not allowed to return success before the
specified amount of time has expired, and you might be calling it 5nS
before the clock tick.  But it does make doing correct Tx pacing a bit
more challenging.

Tried the same thing with usleep(10000), same result of ~20mS per
sleep.

Here's the program I tested that with.  Same results on a 4.4-RELEASE
and a 5.2-RELEASE machine.

Numbers from one run:
  4.4-REL: 1501 loops, 30.017931 elapsed, time per loop: 19998.622 us
  5.2-REL: 1501 loops, 30.016053 elapsed, time per loop: 19997.371 us

 - - - 8< - - -

#include <stdio.h>
#include <errno.h>
#include <sys/time.h>

/* Seconds to count loops */
#define RUNTIME 30

int
main(int argc, char **argv)
{
    struct timespec start, now, end, delay, remain;
    double ts, te;
    long loops = 0;
    int rv;

    clock_gettime(CLOCK_REALTIME, &start);
    end.tv_sec = start.tv_sec + RUNTIME;
    end.tv_nsec = start.tv_nsec;

    do {
        delay.tv_sec = 0;
        delay.tv_nsec = 10000;  /* 10uS */

        do {
            rv = nanosleep(&delay, &remain);
            delay = remain;
        } while (rv < 0 && errno == EINTR);

        ++loops;
        clock_gettime(CLOCK_REALTIME, &now);
    } while ((now.tv_sec == end.tv_sec) ?
        (now.tv_nsec < end.tv_nsec) :
        (now.tv_sec < end.tv_sec));

    te = now.tv_sec + (now.tv_nsec / 1000000000.);
    ts = start.tv_sec + (start.tv_nsec / 1000000000.);

    printf("%d loops, %f elapsed, ", loops, te - ts);
    printf("time per loop: %.3f us\n", ((te - ts) / loops) * 1000000.);

    return 0;
}


-- 
Steve Watt KD6GGD  PP-ASEL-IA          ICBM: 121W 56' 57.8" / 37N 20' 14.9"
 Internet: steve @ Watt.COM                         Whois: SW32
   Free time?  There's no such thing.  It just comes in varying prices...



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