diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-03-21 16:09:56 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2016-03-21 16:26:04 +0000 |
commit | 8520037e5479c1b9ca20a560bbc695d2969d4e1b (patch) | |
tree | db17e838f112d83229902c686ca7e3caa3c6747e /lib/igt_aux.c | |
parent | f1a3d0d96f8cd281446d5a79e11a29173057e730 (diff) |
lib: Measure the cost of calling timer_settimer() for sigiter
We wish to delay the first signal from the igt_sigiter_ioctl
sufficiently to skip over the timer_settime() and into the drmIoctl
kernel context before firing. If we fire too early, we will think that
the ioctl doesn't respond to signals and ignore it in future. If we fire
too late, we won't probe the ioctl for signal handling at all. Let's try
measuring the timer_settime() call time as a first approximation.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'lib/igt_aux.c')
-rw-r--r-- | lib/igt_aux.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/lib/igt_aux.c b/lib/igt_aux.c index da21f10f..b4c301e5 100644 --- a/lib/igt_aux.c +++ b/lib/igt_aux.c @@ -161,8 +161,10 @@ static bool igt_sigiter_start(struct igt_sigiter *iter, bool enable) igt_ioctl = drmIoctl; if (enable) { + struct timespec start, end; struct sigevent sev; struct sigaction act; + struct itimerspec its; igt_ioctl = sig_ioctl; __igt_sigiter.tid = gettid(); @@ -178,8 +180,25 @@ static bool igt_sigiter_start(struct igt_sigiter *iter, bool enable) act.sa_flags = SA_SIGINFO; igt_assert(sigaction(SIGRTMIN, &act, NULL) == 0); - __igt_sigiter.offset.tv_sec = 0; - __igt_sigiter.offset.tv_nsec = 50; + /* Try to find the approximate delay required to skip over + * the timer_setttime and into the following ioctl() to try + * and avoid the timer firing before we enter the drmIoctl. + */ + igt_assert(clock_gettime(CLOCK_MONOTONIC, &start) == 0); + memset(&its, 0, sizeof(its)); + igt_assert(timer_settime(__igt_sigiter.timer, 0, &its, NULL) == 0); + igt_assert(clock_gettime(CLOCK_MONOTONIC, &end) == 0); + + __igt_sigiter.offset.tv_sec = end.tv_sec - start.tv_sec; + __igt_sigiter.offset.tv_nsec = end.tv_nsec - start.tv_nsec; + if (__igt_sigiter.offset.tv_nsec < 0) { + __igt_sigiter.offset.tv_nsec += NSEC_PER_SEC; + __igt_sigiter.offset.tv_sec -= 1; + } + + igt_debug("Initial delay for interruption: %ld.%09lds\n", + __igt_sigiter.offset.tv_sec, + __igt_sigiter.offset.tv_nsec); } return true; |