Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 Dec 2016 11:47:33 -0500
From:      Kurt Lidl <lidl@pix.net>
To:        freebsd-hackers@freebsd.org
Subject:   Re: How to use sem_timedwait?
Message-ID:  <44ad49f5-75ec-7c1d-28dc-25df08c67148@pix.net>
In-Reply-To: <1481776532.1889.461.camel@freebsd.org>
References:  <20161214074228.zh6q5zya2gszw4g6@hal9000.meka.no-ip.org> <1481748960.1889.398.camel@freebsd.org> <20161215002906.mllorgvvuovbdtze@hal9000.meka.no-ip.org> <1481775511.1889.450.camel@freebsd.org> <1481776532.1889.461.camel@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On 12/14/16 11:35 PM, Ian Lepore wrote:
> /*
>  * This tests kevent timer events to make sure that they are properly
>  * metronomic.  That is, each event should occur at the requested
>  * interval following the prior event, and in particular the phase of
>  * event delivery should not drift because of the time it takes to
>  * process the event and schedule the next one in the kernel.  (i.e.,
>  * this is a userland test of kernel kevent timer performance.)
>  * Because it's hard to measure the tiny increments of time between
>  * each sleep, we run a loop that takes several seconds and look for
>  * the total elapsed time to be increment*loopcount plus a tiny bit of
>  * overhead for getting the ending time.
>  */
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <unistd.h>
> #include <errno.h>
> #include <sys/types.h>
> #include <sys/event.h>
> #include <sys/time.h>
>
> int
> main(int argc, char ** argv)
> {
>     int i, interval;
>     int64_t nsec;
>     int kq,num_events;
>     struct kevent inqueue;
>     struct kevent outqueue;
>     struct timespec start,end;
>
>     // argument is timer interval in nanoseconds.
>     if (argc > 1)
>         interval = strtoul(argv[1], NULL, 0);
>     else
>         interval = 1000000;
>
>     if ((kq = kqueue()) == -1) {
>         fprintf(stderr, "kqueue errno = %s", strerror(errno));
>         exit(EXIT_FAILURE);
>     }
>     EV_SET(&inqueue, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE,
>         NOTE_NSECONDS, interval, 0);
>
>     clock_gettime(CLOCK_MONOTONIC_PRECISE, &start);
>
>     for (i = 0; i < 10000000000 / interval; i++) {
>         num_events = kevent(kq, &inqueue, 1, &outqueue, 1, NULL);
>         if (num_events == -1) {
>             fprintf(stderr, "kevent errno = %s", strerror(errno));
>             exit(EXIT_FAILURE);
>         } else if (outqueue.flags & EV_ERROR) {
>             fprintf(stderr, "EV_ERROR: %s\n", strerror(outqueue.data));
>             exit(EXIT_FAILURE);
>         }
>         if (num_events != 1)
>             printf("num_events %d at i %d\n", num_events, i);
>     }
>     clock_gettime(CLOCK_MONOTONIC_PRECISE, &end);
>
>     nsec = (end.tv_sec * 1000000000LL + end.tv_nsec) -
>         (start.tv_sec * 1000000000LL + start.tv_nsec);
>     printf("nsec = %jd for %d loops of %d nsec\n",
>          (intmax_t)nsec, i, interval);
>
>     close(kq);
>     return EXIT_SUCCESS;
> }

When I run this code on a sparc64, it panics the machine!

lidl@ton-148: ./x
panic: trap: fast data access mmu miss (kernel)
KDB: stack backtrace:
vpanic() at vpanic+0xfc
panic() at panic+0x20
trap() at trap+0x554
-- fast data access mmu miss tar=0xc09eda8f %o7=0xc039b344 --
userland() at filt_timerattach+0x78
user trace: trap %o7=0xc039b344
pc 0xc039b378, sp 0xedebe761
done
KDB: enter: panic
[ thread pid 1263 tid 100583 ]
Stopped at      kdb_enter+0x80: ta              %xcc, 1
db>

Oops.

-Kurt




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?44ad49f5-75ec-7c1d-28dc-25df08c67148>