summaryrefslogtreecommitdiff
path: root/lib/igt_aux.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-03-21 16:09:56 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2016-03-21 16:26:04 +0000
commit8520037e5479c1b9ca20a560bbc695d2969d4e1b (patch)
treedb17e838f112d83229902c686ca7e3caa3c6747e /lib/igt_aux.c
parentf1a3d0d96f8cd281446d5a79e11a29173057e730 (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.c23
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;