summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-12 14:27:51 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-12 14:27:51 +0300
commit9ed89c17dee752154c36d71cae93d20cccfc71ef (patch)
treea32cd894643ff6f6ebce83dd745bd24b35eb6520 /src/common
parentaedd863e6f66fd446227e9b107bc9c1970092634 (diff)
perf: optimize hot-path loops, data structures, and cache locality
Diffstat (limited to 'src/common')
-rw-r--r--src/common/backend.c8
-rw-r--r--src/common/input.c9
-rw-r--r--src/common/loop.c54
3 files changed, 49 insertions, 22 deletions
diff --git a/src/common/backend.c b/src/common/backend.c
index 4c755bd..c8d2caf 100644
--- a/src/common/backend.c
+++ b/src/common/backend.c
@@ -217,9 +217,13 @@ bool yasl_surface_present(struct yasl_surface *s, const struct yasl_framebuffer
fb->size.x <= 0 || fb->size.y <= 0 ||
damage->n < -1 || damage->n > YASL_DAMAGE_MAX)
return false;
- struct yasl_damage_list clipped = {.n = damage->n};
- if (damage->n >= 0) {
+ struct yasl_damage_list clipped;
+ clipped.n = damage->n;
+ if (damage->n < 0) {
+ clipped.bounds = damage->bounds;
+ } else {
clipped.n = 0;
+ clipped.bounds = (struct yasl_rect2i){0};
for (int i = 0; i < damage->n; i++) {
struct yasl_rect2i r = damage->rects[i];
if (r.width < 0 || r.height < 0) return false;
diff --git a/src/common/input.c b/src/common/input.c
index eac4d1a..ff578e3 100644
--- a/src/common/input.c
+++ b/src/common/input.c
@@ -53,8 +53,13 @@ bool input_queue_push(struct input_queue *q, const struct yasl_input_event *ev)
goto failed;
struct yasl_input_event *events = malloc(capacity * sizeof(*events));
if (!events) goto failed;
- for (size_t i = 0; i < q->count; i++)
- events[i] = q->events[(q->head + i) % q->capacity];
+ if (q->events && q->count > 0) {
+ size_t first = q->capacity - q->head;
+ if (first > q->count) first = q->count;
+ memcpy(events, q->events + q->head, first * sizeof(*events));
+ if (q->count > first)
+ memcpy(events + first, q->events, (q->count - first) * sizeof(*events));
+ }
free(q->events);
q->events = events;
q->capacity = capacity;
diff --git a/src/common/loop.c b/src/common/loop.c
index a63df16..18d62b1 100644
--- a/src/common/loop.c
+++ b/src/common/loop.c
@@ -25,9 +25,9 @@ struct yasl_fd_source {
struct yasl_timer_source {
yasl_timer_cb fn;
void *ud;
- yasl_timer_id id;
uint64_t interval_ns;
uint64_t deadline_ns;
+ yasl_timer_id id;
bool deleted;
};
@@ -330,13 +330,18 @@ int yasl_loop_step(struct yasl_loop *l, int timeout_ms)
for (int i = 0; i < count; i++) {
if (pcopy[i].revents) {
short revents = pcopy[i].revents;
- // Verify that the source was not deleted by an earlier callback in this step
+ // Fast-path: check if source is still at index i before linear scan
bool valid = false;
- for (int j = 0; j < l->count; j++) {
- if (l->fds[j].id == scopy[i].id) {
- l->pollfds[j].revents = 0;
- valid = true;
- break;
+ if (i < l->count && l->fds[i].id == scopy[i].id) {
+ l->pollfds[i].revents = 0;
+ valid = true;
+ } else {
+ for (int j = 0; j < l->count; j++) {
+ if (l->fds[j].id == scopy[i].id) {
+ l->pollfds[j].revents = 0;
+ valid = true;
+ break;
+ }
}
}
if (valid && scopy[i].fn) {
@@ -367,18 +372,31 @@ int yasl_loop_step(struct yasl_loop *l, int timeout_ms)
uint64_t next_interval = timer_src.fn(ud, tid, interval);
handled++;
- for (int j = 0; j < l->timer_count; j++) {
- if (l->timers[j].id == tid) {
- if (next_interval == 0 || l->timers[j].deleted) {
- l->timers[j].deleted = true;
- } else {
- l->timers[j].interval_ns = next_interval;
- if (l->timers[j].deadline_ns + next_interval > now)
- l->timers[j].deadline_ns += next_interval;
- else
- l->timers[j].deadline_ns = now + next_interval;
+ // Fast-path: timer is usually still at index i unless an earlier timer was deleted
+ if (i < l->timer_count && l->timers[i].id == tid) {
+ if (next_interval == 0 || l->timers[i].deleted) {
+ l->timers[i].deleted = true;
+ } else {
+ l->timers[i].interval_ns = next_interval;
+ if (l->timers[i].deadline_ns + next_interval > now)
+ l->timers[i].deadline_ns += next_interval;
+ else
+ l->timers[i].deadline_ns = now + next_interval;
+ }
+ } else {
+ for (int j = 0; j < l->timer_count; j++) {
+ if (l->timers[j].id == tid) {
+ if (next_interval == 0 || l->timers[j].deleted) {
+ l->timers[j].deleted = true;
+ } else {
+ l->timers[j].interval_ns = next_interval;
+ if (l->timers[j].deadline_ns + next_interval > now)
+ l->timers[j].deadline_ns += next_interval;
+ else
+ l->timers[j].deadline_ns = now + next_interval;
+ }
+ break;
}
- break;
}
}
}