summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 13:26:07 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:16 -0300
commitbe5f559939fc11cbfba95b4a7d518816bec8677a (patch)
tree75373c54379f10416339e59157cb411088ebba1b
parent34cddaea7db5081743fca928e6e50842e23cc5db (diff)
downloadpardes-be5f559939fc11cbfba95b4a7d518816bec8677a.tar.gz
pardes-be5f559939fc11cbfba95b4a7d518816bec8677a.zip
The GUI's idle wakeup copies no 20 KB message batch
Queue.take built its batch (queue capacity plus room, some 20 KB) and returned it by value on every wakeup, a memset and a memcpy of it though the queue was empty; it led the idle profile. drainQueue now fills a batch the Shell keeps, and an empty queue leaves it untouched. Co-Authored-By: Claude Opus 5.5 <[email protected]>
-rw-r--r--src/gui/gui.zig18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/gui/gui.zig b/src/gui/gui.zig
index d935b5fd..e110b3ab 100644
--- a/src/gui/gui.zig
+++ b/src/gui/gui.zig
@@ -1061,9 +1061,19 @@ const Queue = struct {
}
fn take(q: *Queue) MessageBatch {
+ var batch: MessageBatch = .{};
+ q.takeInto(&batch);
+ return batch;
+ }
+
+ /// `take` into a batch the caller keeps: an idle wakeup copies nothing
+ /// (the batch is some 20 KB, and was built and returned by value each
+ /// time).
+ fn takeInto(q: *Queue, batch: *MessageBatch) void {
+ batch.len = 0;
q.lock();
defer q.unlock();
- var batch: MessageBatch = .{};
+ if (q.len == 0 and !q.files_changed and q.completion_len == 0) return;
while (q.len > 0) {
batch.items[batch.len] = q.items[q.head];
batch.len += 1;
@@ -1080,7 +1090,6 @@ const Queue = struct {
batch.len += q.completion_len;
q.completion_len = 0;
std.debug.assert(libc.pthread_cond_broadcast(&q.space) == .SUCCESS);
- return batch;
}
fn discardCompletions(q: *Queue) void {
@@ -3999,6 +4008,8 @@ const Shell = struct {
ptys: *[pardes.MAX_PANES]?Pty,
gens: *[pardes.MAX_PANES]u32,
queue: *Queue,
+ /// What drainQueue takes each wakeup, kept rather than rebuilt.
+ batch: MessageBatch = .{},
pipe_tasks: *PipeTasks,
inotify_fd: c_int,
watches: *file_watch.Table,
@@ -4153,7 +4164,8 @@ const Shell = struct {
s.reconcilePtys();
// After this batch's output, which an exit is told behind.
defer s.takeExits();
- var msgs = s.queue.take();
+ s.queue.takeInto(&s.batch);
+ const msgs = &s.batch;
var check_files = false;
for (msgs.slice()) |m| switch (m) {
.output => |o| {