How to use sem_timedwait?

Kurt Lidl lidl at pix.net
Thu Dec 15 16:47:34 UTC 2016


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 at 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



More information about the freebsd-hackers mailing list