[Perf] (MG_Remote/Transport): the per-op reply-wait split also lands in the exit summary, because a spawn client never prints a frame line

- The tally added beside this is only useful if somebody can read it where the problem is. The
  handoff says why that was hard: under spawn the client does not advance the frame window, so the
  per-frame P65LinkMetrics lines never print, and a SIGKILL takes the exit-time dump with it -
  "only the dump at exit, and SIGKILL does not get it".
- LinkMetricsEnd writes the split on its own line from the one place a client that ends the
  ordinary way always reaches: P65LinkMetrics kind=per-op wait_replies=N by_op=<id>=<count>,... .
  Ids stay raw (this file includes only <cstdint> and friends, not the op table) and the reader
  names them: 2 ResourceCreate, 3 ResourceRespecify, 47 SetTextureParams, 48 ResourceSubData. The
  mapping is written down in mgl-device/README.md, which is the page the device run reads.
This commit is contained in:
BZLZHH
2026-09-25 20:20:04 +08:00
parent ce0235b190
commit 618395529f
@@ -111,6 +111,25 @@ void LinkMetricsPresent() {
void LinkMetricsEnd() {
if (!metrics.active) return;
Emit("summary", metrics.total, ClockNs() - metrics.started, ThreadCpuNs() - metrics.cpuStarted);
// AND THE PER-OP SPLIT AT THE SAME INSTANT, on its own line. The handoff wanted this number
// and could not get it: under spawn the client does not advance the frame window, so the
// per-frame lines never print, and a SIGKILL takes the exit-time dump with it. The summary is
// written from the one place a client that ends the ordinary way always reaches. `op` is raw -
// this file does not include the op table - and the reader names rows with WireOpName.
char split[1024];
std::size_t at = 0;
for (std::uint32_t op = 1; op < LinkMetricsMaxOps && at < sizeof(split); ++op) {
const std::uint64_t waits = metrics.total.waitRepliesByOp[op];
if (waits == 0) continue;
const int n = std::snprintf(split + at, sizeof(split) - at, "%s%u=%llu", at == 0 ? "" : ",",
static_cast<unsigned>(op),
static_cast<unsigned long long>(waits));
if (n < 0 || static_cast<std::size_t>(n) >= sizeof(split) - at) break;
at += static_cast<std::size_t>(n);
}
MGLOG_I("P65LinkMetrics kind=per-op wait_replies=%llu by_op=%s",
static_cast<unsigned long long>(metrics.total.waitReplies),
at == 0 ? "(none)" : split);
metrics.active = false;
}
void LinkMetricsServerPresent(std::uint64_t serial) {