mirror of
https://gitlab.freedesktop.org/emersion/libliftoff.git
synced 2024-11-16 19:47:55 +01:00
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:
parent
d98ae24328
commit
7ceaf440e2
1 changed files with 40 additions and 0 deletions
40
alloc.c
40
alloc.c
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue