This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch tymux
in repository terminology.

View the commit online.

commit 340da250ee710ae49a60310e2632eb83cf138bf0
Author: [email protected] <[email protected]>
AuthorDate: Sun Mar 22 14:26:56 2026 -0600

    perf: throttle tymux NOTIFY to display refresh rate
    
    The daemon was flushing the screen to shared memory and sending a
    NOTIFY to all clients on every PTY read event — up to 1000+ times
    per second during fast output. Use an Ecore animator to batch
    flush+notify at the display frame rate (~60 Hz), matching the
    pattern Terminology already uses for its own rendering. This
    reduces `seq 1 100000` from ~3.5s to near-direct performance.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---
 src/bin/termd_tymux.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 57 insertions(+), 5 deletions(-)

diff --git a/src/bin/termd_tymux.c b/src/bin/termd_tymux.c
index 0bd0314a..95768340 100644
--- a/src/bin/termd_tymux.c
+++ b/src/bin/termd_tymux.c
@@ -75,6 +75,9 @@ struct _TermDTymux
    uint32_t        oldest_buf_id;        /* global id of oldest buffer */
    uint32_t        next_buf_id;          /* next global id to assign */
    size_t          last_flushed_backpos; /* backpos at last flush */
+
+   Ecore_Animator *notify_anim;          /* batches flush + NOTIFY at frame rate */
+   Eina_Bool       dirty;                /* screen changed since last flush */
 };
 
 /* ── synthetic Config for headless use ───────────────────────────── */
@@ -345,9 +348,8 @@ static void _client_remove(TermDTymux *sess, TermDClient *client);
 /* ── Termpty callbacks ───────────────────────────────────────────── */
 
 static void
-_pty_change_cb(void *data)
+_tymux_flush_and_notify(TermDTymux *sess)
 {
-   TermDTymux     *sess = data;
    TermSrvMsgNotify  pay;
    Eina_List        *l;
    TermDClient      *c;
@@ -355,8 +357,8 @@ _pty_change_cb(void *data)
    _flush_screen_to_shm(sess);
    _flush_backlog_to_shm(sess);
 
-   pay.write_seq        = atomic_load_explicit(&sess->shm->write_seq,
-                                               memory_order_acquire);
+   pay.write_seq         = atomic_load_explicit(&sess->shm->write_seq,
+                                                memory_order_acquire);
    pay.backlog_buf_count = (uint32_t)sess->backlog_buf_count;
    pay.oldest_buf_id     = sess->oldest_buf_id;
    if (sess->backlog_buf_count > 0)
@@ -365,7 +367,7 @@ _pty_change_cb(void *data)
            sess->backlog_bufs[sess->backlog_buf_count - 1].hdr;
         pay.backlog_head_seq =
            (uint32_t)atomic_load_explicit(&head->write_seq,
-                                          memory_order_acquire);
+                                          memory_order_relaxed);
      }
    else
      pay.backlog_head_seq = 0;
@@ -374,6 +376,30 @@ _pty_change_cb(void *data)
      termsrv_msg_send(c->fd, TSRV_MSG_NOTIFY, &pay, sizeof(pay));
 }
 
+static Eina_Bool
+_tymux_notify_anim_cb(void *data)
+{
+   TermDTymux *sess = data;
+
+   sess->notify_anim = NULL;
+   if (sess->dirty)
+     {
+        sess->dirty = EINA_FALSE;
+        _tymux_flush_and_notify(sess);
+     }
+   return EINA_FALSE;  /* one-shot: delete after firing */
+}
+
+static void
+_pty_change_cb(void *data)
+{
+   TermDTymux *sess = data;
+
+   sess->dirty = EINA_TRUE;
+   if (!sess->notify_anim)
+     sess->notify_anim = ecore_animator_add(_tymux_notify_anim_cb, sess);
+}
+
 static void
 _pty_title_cb(void *data)
 {
@@ -407,6 +433,19 @@ _pty_exit_cb(void *data)
    Eina_List       *l;
    TermDClient     *c;
 
+   /* Cancel any pending animator and flush the last screen state so
+    * clients receive the final output before the EXIT message. */
+   if (sess->notify_anim)
+     {
+        ecore_animator_del(sess->notify_anim);
+        sess->notify_anim = NULL;
+     }
+   if (sess->dirty)
+     {
+        sess->dirty = EINA_FALSE;
+        _tymux_flush_and_notify(sess);
+     }
+
    pay.exit_code = (int32_t)sess->pty->exit_code;
    EINA_LIST_FOREACH(sess->clients, l, c)
      termsrv_msg_send(c->fd, TSRV_MSG_EXIT, &pay, sizeof(pay));
@@ -614,6 +653,19 @@ termd_tymux_free(TermDTymux *sess)
    if (!sess)
      return;
 
+   /* Cancel any pending animator and do a final flush so that clients
+    * connected at free-time receive the last screen state. */
+   if (sess->notify_anim)
+     {
+        ecore_animator_del(sess->notify_anim);
+        sess->notify_anim = NULL;
+     }
+   if (sess->dirty)
+     {
+        sess->dirty = EINA_FALSE;
+        _tymux_flush_and_notify(sess);
+     }
+
    EINA_LIST_FREE(sess->clients, c)
      {
         if (c->handler)

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to