@@ -1847,6 +1847,15 @@ static bool sync_deps(struct workload *wrk, struct w_step *w)
return synced;
}
+static void
+timespec_add_us(struct timespec *ts, unsigned int us)
+{
+ uint64_t ns = ts->tv_sec * NSEC_PER_SEC + ts->tv_nsec + us * 1000;
+
+ ts->tv_sec = ns / NSEC_PER_SEC;
+ ts->tv_nsec = ns % NSEC_PER_SEC;
+}
+
static void *run_workload(void *data)
{
struct workload *wrk = (struct workload *)data;
@@ -1873,20 +1882,21 @@ static void *run_workload(void *data)
for (i = 0, w = wrk->steps; wrk->run && (i < wrk->nr_steps);
i++, w++) {
enum intel_engine_id engine = w->engine;
- int do_sleep = 0;
+ struct timespec now;
if (w->type == DELAY) {
- do_sleep = w->delay;
+ clock_gettime(CLOCK_MONOTONIC, &now);
} else if (w->type == PERIOD) {
- struct timespec now;
+ int remain_us;
clock_gettime(CLOCK_MONOTONIC, &now);
- do_sleep = w->period -
- elapsed_us(&wrk->repeat_start, &now);
- if (do_sleep < 0) {
+ remain_us = w->period -
+ elapsed_us(&wrk->repeat_start,
+ &now);
+ if (remain_us < 0) {
if (verbose > 1)
- printf("%u: Dropped period @ %u/%u (%dus late)!\n",
- wrk->id, count, i, do_sleep);
+ printf("%u: Missed period @ %u/%u (%dus late)!\n",
+ wrk->id, count, i, -remain_us);
continue;
}
} else if (w->type == SYNC) {
@@ -1936,8 +1946,21 @@ static void *run_workload(void *data)
continue;
}
- if (do_sleep || w->type == PERIOD) {
- usleep(do_sleep);
+ if (w->type == DELAY || w->type == PERIOD) {
+ struct timespec end;
+ unsigned int us;
+
+ if (w->type == PERIOD) {
+ end = wrk->repeat_start;
+ us = w->period;
+ } else {
+ end = now;
+ us = w->delay;
+ }
+
+ timespec_add_us(&end, us);
+ clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME,
+ &end, NULL);
continue;
}