emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 9661c82920: Lower the roundtrip overhead of x-get-atom-name by 50


From: Po Lu
Subject: master 9661c82920: Lower the roundtrip overhead of x-get-atom-name by 50% for common atoms
Date: Wed, 25 May 2022 08:29:56 -0400 (EDT)

branch: master
commit 9661c82920cf2b75300266bbd9da9e45b9471173
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Lower the roundtrip overhead of x-get-atom-name by 50% for common atoms
    
    * src/xselect.c (Fx_get_atom_name):
    * src/xterm.c (x_dnd_begin_drag_and_drop): Use that instead.  Don't
    sync to handle errors if using `x_get_atom_name' resulted in no
    protocol request being made.
    (x_get_atom_name): New function.
    * src/xterm.h: Update prototypes.
---
 src/xselect.c | 12 ++++++---
 src/xterm.c   | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++------
 src/xterm.h   |  1 +
 3 files changed, 83 insertions(+), 11 deletions(-)

diff --git a/src/xselect.c b/src/xselect.c
index 3acfcbe94b..6cb279f9e8 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -2458,21 +2458,25 @@ If the value is 0 or the atom is not known, return the 
empty string.  */)
   char empty[] = "";
   Lisp_Object ret = Qnil;
   Display *dpy = FRAME_X_DISPLAY (f);
+  struct x_display_info *dpyinfo;
   Atom atom;
-  bool had_errors_p;
+  bool had_errors_p, need_sync;
+
+  dpyinfo = FRAME_DISPLAY_INFO (f);
 
   CONS_TO_INTEGER (value, Atom, atom);
 
   block_input ();
   x_catch_errors (dpy);
-  name = atom ? XGetAtomName (dpy, atom) : empty;
-  had_errors_p = x_had_errors_p (dpy);
+  name = (atom ? x_get_atom_name (dpyinfo, atom,
+                                 &need_sync) : empty);
+  had_errors_p = need_sync && x_had_errors_p (dpy);
   x_uncatch_errors_after_check ();
 
   if (!had_errors_p)
     ret = build_string (name);
 
-  if (atom && name) XFree (name);
+  if (atom && name) xfree (name);
   if (NILP (ret)) ret = empty_unibyte_string;
 
   unblock_input ();
diff --git a/src/xterm.c b/src/xterm.c
index 3ca0c15897..1997cc77dc 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -10238,7 +10238,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, 
Atom xaction,
   XTextProperty prop;
   xm_drop_start_message dmsg;
   Lisp_Object frame_object, x, y, frame, local_value;
-  bool signals_were_pending;
+  bool signals_were_pending, need_sync;
 #ifdef HAVE_XKB
   XkbStateRec keyboard_state;
 #endif
@@ -10800,14 +10800,20 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time 
time, Atom xaction,
     {
       block_input ();
       x_catch_errors (FRAME_X_DISPLAY (f));
-      atom_name = XGetAtomName (FRAME_X_DISPLAY (f),
-                               x_dnd_action);
-      x_uncatch_errors ();
+      atom_name = x_get_atom_name (FRAME_DISPLAY_INFO (f),
+                                  x_dnd_action, &need_sync);
+
+      if (need_sync)
+       x_uncatch_errors ();
+      else
+       /* No protocol request actually happened, so avoid the extra
+          sync by calling x_uncatch_errors_after_check instead.  */
+       x_uncatch_errors_after_check ();
 
       if (atom_name)
        {
          action = intern (atom_name);
-         XFree (atom_name);
+         xfree (atom_name);
        }
       else
        action = Qnil;
@@ -23599,8 +23605,10 @@ x_destroy_window (struct frame *f)
 }
 
 /* Intern NAME in DPYINFO, but check to see if the atom was already
-   interned, and use that instead.  If PREDEFINED_ONLY, return None if
-   the atom was not already interned at connection setup.  */
+   interned when the X connection was opened, and use that instead.
+
+   If PREDEFINED_ONLY, return None if the atom was not interned during
+   connection setup or is predefined.  */
 Atom
 x_intern_cached_atom (struct x_display_info *dpyinfo,
                      const char *name, bool predefined_only)
@@ -23666,6 +23674,65 @@ x_intern_cached_atom (struct x_display_info *dpyinfo,
   return XInternAtom (dpyinfo->display, name, False);
 }
 
+/* Whether or not a request to the X server happened is placed in
+   NEED_SYNC.  */
+char *
+x_get_atom_name (struct x_display_info *dpyinfo, Atom atom,
+                bool *need_sync)
+{
+  char *dpyinfo_pointer, *name, *value;
+  int i;
+  Atom ref_atom;
+
+  dpyinfo_pointer = (char *) dpyinfo;
+  value = NULL;
+  *need_sync = false;
+
+  switch (atom)
+    {
+    case XA_PRIMARY:
+      return xstrdup ("PRIMARY");
+
+    case XA_SECONDARY:
+      return xstrdup ("SECONDARY");
+
+    case XA_INTEGER:
+      return xstrdup ("INTEGER");
+
+    case XA_ATOM:
+      return xstrdup ("ATOM");
+
+    case XA_CARDINAL:
+      return xstrdup ("CARDINAL");
+
+    case XA_WINDOW:
+      return xstrdup ("WINDOW");
+
+    default:
+      for (i = 0; i < ARRAYELTS (x_atom_refs); ++i)
+       {
+         ref_atom = *(Atom *) (dpyinfo_pointer
+                               + x_atom_refs[i].offset);
+
+         if (atom == ref_atom)
+           return xstrdup (x_atom_refs[i].name);
+       }
+
+      name = XGetAtomName (dpyinfo->display, atom);
+      *need_sync = true;
+
+      if (name)
+       {
+         value = xstrdup (name);
+         XFree (name);
+       }
+
+      break;
+    }
+
+  return value;
+}
+
 
 /* Setting window manager hints.  */
 
diff --git a/src/xterm.h b/src/xterm.h
index fba775d96b..daeb1a4575 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1538,6 +1538,7 @@ extern void x_set_pending_dnd_time (Time);
 extern void x_own_selection (Lisp_Object, Lisp_Object, Lisp_Object);
 extern Atom x_intern_cached_atom (struct x_display_info *, const char *,
                                  bool);
+extern char *x_get_atom_name (struct x_display_info *, Atom, bool *);
 
 #ifdef USE_GTK
 extern bool xg_set_icon (struct frame *, Lisp_Object);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]