This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository terminology.
View the commit online.
commit 945263456654722cbb583f11295dfd85a567671f
Author: Cedric BAIL <[email protected]>
AuthorDate: Mon Aug 3 13:28:55 2026 -0600
termptyops: clear a row with memset when nothing needs per-cell work
termpty_cells_clear() is the hottest function in the intake profile -- 21% of
the work on short-line output -- and built a template cell then filled the
row one 12-byte struct at a time, testing each destination for a link and a
media block as it went.
Clearing to default attributes makes every cell all zero bytes, so when this
terminal has never created a link or a block the whole row is one memset. The
template is compared against zero rather than field by field, so adding a bit
to Termatt cannot silently make the fast path wrong.
No NEON here: glibc's aarch64 memset is already vectorised, and this drops
cells_clear from 21% of the profile to 4%.
Also guard against a negative count, which the per-cell loop simply ignored
but memset would take as an enormous unsigned size. No caller passes one, but
several compute it from a width.
Co-Authored-By: Claude Opus 5 <[email protected]>
---
src/bin/termptyops.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/src/bin/termptyops.c b/src/bin/termptyops.c
index 55c7f809..ed744a07 100644
--- a/src/bin/termptyops.c
+++ b/src/bin/termptyops.c
@@ -24,13 +24,30 @@
void
termpty_cells_clear(Termpty *ty, Termcell *cells, int count)
{
+ static const Termcell zero_cell = { 0 };
Termcell src;
+ /* memset() would take a negative count as an enormous unsigned one, where
+ * the per-cell loop below simply does nothing. No caller passes one today,
+ * but several compute it from a width. */
+ if (count <= 0) return;
+
memset(&src, 0, sizeof(src));
src.codepoint = 0;
src.att = ty->termstate.att;
src.att.link_id = 0;
+ /* Clearing to default attributes makes every cell all-zero, so the row is
+ * one memset. Only when no link or block exists, since overwriting either
+ * adjusts a refcount. The template is compared against zero rather than
+ * field by field, so adding a bit to Termatt cannot make this wrong. */
+ if (EINA_LIKELY((ty->hl.size == 0) && (ty->block.blocks == NULL) &&
+ (memcmp(&src, &zero_cell, sizeof(src)) == 0)))
+ {
+ memset(cells, 0, count * sizeof(Termcell));
+ return;
+ }
+
termpty_cell_fill(ty, &src, cells, count);
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.