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>