On 02/14/2015 10:58 AM, Chris Wilson wrote:
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 <[email protected]>
---
  present/present.c | 24 +++++++++++++++---------
  1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/present/present.c b/present/present.c
index ba88f79..b132f4d 100644
--- a/present/present.c
+++ b/present/present.c
@@ -482,19 +482,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;
@@ -887,7 +890,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 ((pixmap && target_msc >= crtc_msc) || (!pixmap && target_msc > 
crtc_msc)) {
          ret = present_queue_vblank(screen, target_crtc, vblank->event_id, 
target_msc);
@@ -911,7 +914,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);
@@ -922,14 +925,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;


Looks good to me, also no problems during testing on top of current master, so

Reviewed-and-tested-by: Mario Kleiner <[email protected]>

-mario


_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to