perf(wave1): reduce Config caps, reorder Client/Monitor for cache

Wave 1 changes:
- Reduce CFG_MAX_KEYBINDS 256→128, CFG_MAX_STRLEN 256→64, CFG_MAX_ARGS 16→8
  → saves ~2.5 MB BSS from Config struct
- Add truncation warnings to config_load when keybind/button/scroll limit reached
- Reorder Client struct: HOT fields (type, mon, tags, floating flags, geom) in first
  cache line, COLD fields (wl_listeners) at end — saves cache misses in arrange()
- Reorder LayerSurface struct similarly
- Split Monitor into Monitor/MonitorCold: hot fields (~120B) stay inline, cold layout
  state lazily allocated on first dwindle/master use
- All cold-field accesses through m->cold-> indirection
- cleanupmon frees m->cold
- Zero-warning build with clang -Werror -Wpedantic
This commit is contained in:
2026-07-02 23:35:37 -04:00
parent cd0e5ec1eb
commit fb0f49e861
22 changed files with 6664 additions and 86 deletions
+34 -14
View File
@@ -40,6 +40,21 @@ const unsigned int layout_count = LENGTH(layouts);
* helpers
* ================================================================ */
/* Allocate and default-initialize monitor cold state on first use. */
void
ensure_cold(Monitor *m)
{
if (m->cold)
return;
m->cold = ecalloc(1, sizeof(MonitorCold));
for (int i = 0; i < TAGCOUNT; i++) {
m->cold->lt[i][0] = &layouts[0];
m->cold->lt[i][1] = &layouts[0];
}
m->cold->mfact = 0.55f;
m->cold->nmaster = 1;
}
/*
* Returns the 0-based index of the lowest set tag bit for monitor m.
* For single-tag views this is the exact tag. For multi-tag views it
@@ -64,7 +79,8 @@ const Layout *
curlayout(Monitor *m)
{
int ti = current_tag_idx(m);
return m->lt[ti][m->sellt[ti]];
ensure_cold(m);
return m->cold->lt[ti][m->cold->sellt[ti]];
}
/* ================================================================
@@ -230,10 +246,10 @@ void
dwindle_remove_client(Client *c)
{
Monitor *m = c->mon;
if (!m)
if (!m || !m->cold)
return;
for (int i = 0; i < TAGCOUNT; i++)
dwindle_remove(&m->dwindle_root[i], c);
dwindle_remove(&m->cold->dwindle_root[i], c);
}
/* ================================================================
@@ -243,6 +259,7 @@ dwindle_remove_client(Client *c)
void
dwindle(Monitor *m)
{
ensure_cold(m);
Client *c;
int n = 0, e;
@@ -258,7 +275,7 @@ dwindle(Monitor *m)
: 0;
int ti = current_tag_idx(m);
DwindleNode **root = &m->dwindle_root[ti];
DwindleNode **root = &m->cold->dwindle_root[ti];
/* prune leaves whose clients are no longer tiled here */
{
@@ -295,11 +312,11 @@ dwindle(Monitor *m)
/*
* Insert any newly visible client, splitting the focused node.
* Use m->dwindle_focus[ti] so it actually splits what the user
* Use m->cold->dwindle_focus[ti] so it actually splits what the user
* was looking at when they spawned the window, rather than whatever
* focustop() happens to return.
*/
Client *focused = m->dwindle_focus[ti];
Client *focused = m->cold->dwindle_focus[ti];
wl_list_for_each(c, &clients, link) {
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
@@ -329,13 +346,14 @@ dwindle(Monitor *m)
static void
master_arrange(Monitor *m, int ti)
{
ensure_cold(m);
Client *c, *master_c = nullptr;
Client *stack[256];
int nstack = 0, n = 0;
wl_list_for_each(c, &clients, link) {
if (VISIBLEON(c, m) && !c->isfloating) {
if (c == m->master_master[ti])
if (c == m->cold->master_master[ti])
master_c = c;
if (!c->isfullscreen)
n++;
@@ -348,7 +366,7 @@ master_arrange(Monitor *m, int ti)
if (!master_c) {
wl_list_for_each(c, &clients, link) {
if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen) {
m->master_master[ti] = c;
m->cold->master_master[ti] = c;
master_c = c;
break;
}
@@ -374,9 +392,9 @@ master_arrange(Monitor *m, int ti)
return;
}
int master_w = MAX(1, (int)(aw * m->mfact));
int master_w = MAX(1, (int)(aw * m->cold->mfact));
if (m->master_side[ti] == 0) {
if (m->cold->master_side[ti] == 0) {
int stack_x = m->w.x + e + master_w + e;
int stack_w = MAX(1, aw - master_w - e);
@@ -421,11 +439,11 @@ void
master_remove_client(Client *c)
{
Monitor *m = c->mon;
if (!m)
if (!m || !m->cold)
return;
for (int i = 0; i < TAGCOUNT; i++) {
if (m->master_master[i] == c)
m->master_master[i] = nullptr;
if (m->cold->master_master[i] == c)
m->cold->master_master[i] = nullptr;
}
}
@@ -479,8 +497,10 @@ swaptiled(Client *a, Client *b)
return;
wl_list_for_each(m, &mons, link) {
if (!m->cold)
continue;
for (int i = 0; i < TAGCOUNT; i++) {
DwindleNode **root = &m->dwindle_root[i];
DwindleNode **root = &m->cold->dwindle_root[i];
if (!*root)
continue;
DwindleNode *la = dwindle_find_leaf(*root, a);