Add a deadline for liftoff_output_apply()

We don't want libliftoff to take too long.

References: https://gitlab.freedesktop.org/emersion/libliftoff/-/issues/16
This commit is contained in:
Simon Ser 2021-09-30 10:54:10 +02:00
parent d98ae24328
commit 7ceaf440e2

40
alloc.c
View file

@ -1,9 +1,11 @@
#define _POSIX_C_SOURCE 200112L
#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "log.h"
#include "private.h"
@ -76,6 +78,8 @@ struct alloc_result {
struct liftoff_layer **best;
int best_score;
struct timespec started_at;
/* per-output */
bool has_composition_layer;
size_t non_composition_layers_len;
@ -96,6 +100,31 @@ struct alloc_step {
char log_prefix[64];
};
static const int64_t NSEC_PER_SEC = 1000 * 1000 * 1000;
static int64_t
timespec_to_nsec(struct timespec ts)
{
return (int64_t)ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec;
}
static const int64_t ALLOC_TIMEOUT_NSEC = 1000 * 1000; // 1ms
static bool
check_deadline(struct timespec start)
{
struct timespec now;
int64_t deadline;
if (clock_gettime(CLOCK_MONOTONIC, &now) != 0) {
liftoff_log_errno(LIFTOFF_ERROR, "clock_gettime");
return false;
}
deadline = timespec_to_nsec(start) + ALLOC_TIMEOUT_NSEC;
return timespec_to_nsec(now) < deadline;
}
static void
plane_step_init_next(struct alloc_step *step, struct alloc_step *prev,
struct liftoff_layer *layer)
@ -449,6 +478,12 @@ output_choose_layers(struct liftoff_output *output, struct alloc_result *result,
continue;
}
if (!check_deadline(result->started_at)) {
liftoff_log(LIFTOFF_DEBUG, "%s Deadline exceeded",
step->log_prefix);
break;
}
/* Try to use this layer for the current plane */
ret = plane_apply(plane, layer, result->req);
if (ret == -EINVAL) {
@ -815,6 +850,11 @@ liftoff_output_apply(struct liftoff_output *output, drmModeAtomicReq *req,
return -ENOMEM;
}
if (clock_gettime(CLOCK_MONOTONIC, &result.started_at) != 0) {
liftoff_log_errno(LIFTOFF_ERROR, "clock_gettime");
return -errno;
}
/* For each plane, try to find a layer. Don't do it the other
* way around (ie. for each layer, try to find a plane) because
* some drivers want user-space to enable the primary plane