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 ab06090727a8e627fd08d41725bb2adf2f20f065
Author: Cedric BAIL <[email protected]>
AuthorDate: Mon Aug 3 13:50:34 2026 -0600
termpty: vectorise the autowrapped marking of saved rows
Every row that scrolls into the backlog is walked to flag its cells as
continuing onto the next line. GCC already compiles that to five instructions
per cell -- load the bitfield word, or, store back, advance twelve bytes,
test -- so there was nothing left to gain from rewriting it scalar.
A twelve-byte stride lines up with a sixteen-byte vector every four cells, so
the mask repeats every forty-eight bytes and can be applied as three fixed
vectors, a little over two instructions per cell. That is the record byte-OR
kernel added here; every other stride falls through to its scalar form rather
than pretending to be vectorised.
Which byte carries att.autowrapped depends on how the compiler lays out
Termatt's bitfields, so it is worked out once from a cell that has the bit
set. Hardcoding the offset would have been quietly invalidated by any change
to Termatt. If the probe ever came up empty the cells are marked the slow way:
assert() is compiled out under NDEBUG, and the failure mode of marking nothing
is wrapped lines that stop rejoining, which is not the kind of thing to leave
resting on a layout assumption.
The marking cannot be folded into the copy that follows it:
termpty_text_scroll() only clears the row it just saved when asked to, so the
source has to keep its marks, and glibc's memcpy is already cheap enough that
fusing the two passes would not pay for itself.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---
src/bin/termpty.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 54 insertions(+), 5 deletions(-)
diff --git a/src/bin/termpty.c b/src/bin/termpty.c
index a7f8d521..98852a1f 100644
--- a/src/bin/termpty.c
+++ b/src/bin/termpty.c
@@ -990,11 +990,62 @@ termpty_line_length(const Termcell *cells, ssize_t nb_cells)
}
+/* Flag a run of cells as continuing onto the next line. The byte carrying
+ * att.autowrapped depends on the compiler's bitfield layout, so it is worked
+ * out once from a cell that has the bit set. */
+static void
+_mark_autowrapped(Termcell *cells, ssize_t n)
+{
+ /* NOT_PROBED rather than a zero 'bit', so the probe runs exactly once even
+ * if it ever comes up empty. */
+#define NOT_PROBED ((size_t)-1)
+ static size_t off = NOT_PROBED;
+ static unsigned char bit;
+
+ if (EINA_UNLIKELY(off == NOT_PROBED))
+ {
+ Termcell probe;
+ size_t i;
+
+ memset(&probe, 0, sizeof(probe));
+ probe.att.autowrapped = 1;
+ for (i = 0; i < sizeof(probe); i++)
+ {
+ if (((const unsigned char *)&probe)[i])
+ {
+ off = i;
+ bit = ((const unsigned char *)&probe)[i];
+ break;
+ }
+ }
+ assert(off != NOT_PROBED);
+ }
+
+ if (EINA_UNLIKELY(off == NOT_PROBED))
+ {
+ /* One bitfield bit always lands in some byte, so this is unreachable --
+ * but assert() is gone under NDEBUG, and marking nothing at all would
+ * silently stop wrapped lines from rejoining. Mark them the slow way
+ * instead of trusting the layout. */
+ ssize_t i;
+
+ for (i = 0; i < n; i++)
+ cells[i].att.autowrapped = 1;
+ return;
+ }
+
+ _Static_assert(sizeof(Termcell) == 12,
+ "Termcell size changed: simd_records_or_byte() vectorises a "
+ "12-byte stride and silently falls back to scalar otherwise");
+ simd_records_or_byte(cells, (size_t)n, sizeof(Termcell), off, bit);
+#undef NOT_PROBED
+}
+
void
termpty_text_save_top(Termpty *ty, Termcell *cells, ssize_t w_max)
{
Termsave *ts;
- ssize_t w, i;
+ ssize_t w;
if (ty->backsize == 0)
return;
@@ -1003,10 +1054,8 @@ termpty_text_save_top(Termpty *ty, Termcell *cells, ssize_t w_max)
termpty_backlog_lock();
w = termpty_line_length(cells, w_max);
- for (i = 0; i < w - 1; i++)
- {
- cells[i].att.autowrapped = 1;
- }
+ if (w > 1)
+ _mark_autowrapped(cells, w - 1);
if (ty->backsize > 0)
{
ts = BACKLOG_ROW_GET(ty, 1);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.