From e10c70e81c8371438093ea594eea20d31747bf71 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 14 Feb 2015 09:58:43 +0000 Subject: [PATCH xserver 1/2] present: Improve scaling of vblank handler With large numbers of queued vblank, the list iteration on every interupt dominates processing time. If we reorder the list to be in ascending event order, then not only is also likely to be in order for notification queries (i.e. the notification will be near the start of the list), we can also stop iterating when past the target event_id. Signed-off-by: Chris Wilson --- present/present.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/present/present.c b/present/present.c index 55f6aa7..97ad783 100644 --- a/present/present.c +++ b/present/present.c @@ -517,19 +517,22 @@ present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) void present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc) { - present_vblank_ptr vblank, tmp; + present_vblank_ptr vblank; int s; if (!event_id) return; DebugPresent(("\te %lld ust %lld msc %lld\n", event_id, ust, msc)); - xorg_list_for_each_entry_safe(vblank, tmp, &present_exec_queue, event_queue) { - if (vblank->event_id == event_id) { + xorg_list_for_each_entry(vblank, &present_exec_queue, event_queue) { + int64_t match = event_id - vblank->event_id; + if (match == 0) { present_execute(vblank, ust, msc); return; } + if (match < 0) + break; } - xorg_list_for_each_entry_safe(vblank, tmp, &present_flip_queue, event_queue) { + xorg_list_for_each_entry(vblank, &present_flip_queue, event_queue) { if (vblank->event_id == event_id) { present_flip_notify(vblank, ust, msc); return; @@ -943,7 +946,7 @@ present_pixmap(WindowPtr window, vblank->pixmap->drawable.id, vblank->window->drawable.id, target_crtc, vblank->flip, vblank->sync_flip, vblank->serial)); - xorg_list_add(&vblank->event_queue, &present_exec_queue); + xorg_list_append(&vblank->event_queue, &present_exec_queue); vblank->queued = TRUE; if (msc_is_after(target_msc, crtc_msc)) { ret = present_queue_vblank(screen, target_crtc, vblank->event_id, target_msc); @@ -967,7 +970,7 @@ no_mem: void present_abort_vblank(ScreenPtr screen, RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) { - present_vblank_ptr vblank, tmp; + present_vblank_ptr vblank; if (crtc == NULL) present_fake_abort_vblank(screen, event_id, msc); @@ -978,14 +981,17 @@ present_abort_vblank(ScreenPtr screen, RRCrtcPtr crtc, uint64_t event_id, uint64 (*screen_priv->info->abort_vblank) (crtc, event_id, msc); } - xorg_list_for_each_entry_safe(vblank, tmp, &present_exec_queue, event_queue) { - if (vblank->event_id == event_id) { + xorg_list_for_each_entry(vblank, &present_exec_queue, event_queue) { + int64_t match = event_id - vblank->event_id; + if (match == 0) { xorg_list_del(&vblank->event_queue); vblank->queued = FALSE; return; } + if (match < 0) + break; } - xorg_list_for_each_entry_safe(vblank, tmp, &present_flip_queue, event_queue) { + xorg_list_for_each_entry(vblank, &present_flip_queue, event_queue) { if (vblank->event_id == event_id) { xorg_list_del(&vblank->event_queue); return; -- 2.5.0