[Docs] (P12): the P5E contract records the texture half's paid-off wait, and the round's note carries the measured G1

- CONTRACT-P5E.md 2.5 said "the TEXTURE half keeps its wait because DrainTextureSubData clears the
  level's dirty flag on the accepted reply (D-D5; trailing)". The trailing is paid, so the clause
  now states the three facts that make that answer DERIVABLE on the wire arm (the emission gate IS
  the consumer question the applier's own acceptance belt asks; what remains is a loud bug class;
  a client-cancelled record still answers "not accepted"), where the wait moves to (SEG_STAGE),
  that MGPipeSubDataWantsItsReply stays the one place that decides, and the gate with its red-once.
  ResourceCreate and SetTextureParams are named as analyzed separately rather than swept in.
- notes/p12/DEVICELOST-AND-UPLOAD-WAITS.md: 2.3 now carries the G1 A/B this machine ran - .text
  13872002 bytes on both sides, 31746 symbols, 0 added / 0 removed, no per-symbol difference -
  instead of deferring it to CI, and 3 trades its "G1 not run" item for the device tooling
  (mgl-device/: launch-mc.py, gl-aliases.sh, start-phone-server.sh) the next round needs.
This commit is contained in:
BZLZHH
2026-09-25 20:00:44 +08:00
parent 3b9f536dd2
commit bfd6392668
2 changed files with 30 additions and 7 deletions
+21 -2
View File
@@ -187,8 +187,27 @@ one present credit later than the call after it; P5C §4.2 already assigns order
names the window. **`resource_subdata`:** the BUFFER half passes `wantReply = false` through
`MGPipeRouteResourceSubData` (the Bool is discarded today, `PipeFill.cpp:839`; the server still
posts, the slot is never read — legal, `ReplySlot.h:16, 105`), which is what makes the persistent-map
push (`PersistentMapTracker.cpp:735, 850`) fire-and-forget; the TEXTURE half keeps its wait because
`DrainTextureSubData` clears the level's dirty flag on the accepted reply (D-D5; trailing).
push (`PersistentMapTracker.cpp:735, 850`) fire-and-forget.
**THE TEXTURE HALF'S WAIT IS PAID OFF (P12 — the "trailing" this paragraph used to carry), and the
argument is that its answer is DERIVABLE on the wire arm, not that nobody reads it.**
`DrainTextureSubData` still clears the level's dirty flag on an accepted answer (D-D5); what it no
longer buys is a round trip for it, because (a) the emission is already gated on
`CapsMirrorInstance().ServerConsumes(kMGPipeSubsystemTextureResources)` (`PipeFill.cpp:1719-1740`) —
the same published fact the applier's own acceptance belt reads (`PipeApply.cpp:1408-1419`), so the
one refusal this acceptance exists to carry ("no consumer") cannot be the answer to a record this
client emitted; (b) what remains is a loud bug class (`MGP_TRIP_WIRE_REPORT` for a malformed texture
record, `ResolveResourceIn`'s counted miss for a handle the applier does not hold); and (c) a record
the CLIENT cancelled still answers "not accepted", so the level stays dirty and is retried. **The
wait moves to `SEG_STAGE`**: a run that does not fit reclaims retired bytes and parks on the stage
doorbell, which is proportional to the window rather than to the call count. `MGPipeSubDataWantsItsReply`
(`PipeRoute.h`) stays the ONE place that decides, now with the arm test inside
`MOBILEGL_BUILD_DISAGGREGATED` and the original expression as its fall-through; monolith and every
non-wire arm keep the old answer, which is what G1 measures. Gate:
`RemoteClientControls.TextureUploadsStopOwningAReplyOnTheWireArm` reads back the same `wait_replies`
the P65LinkMetrics line prints (`LinkMetricsReplyWaits`), asserting a pure upload moves it by ZERO
while a `resource_create` row still moves it; red-once with the arm test removed is exit 142.
`ResourceCreate` and `SetTextureParams` stay `kWaitReply` — same question, asked per resource and
per call, analyzed separately rather than swept in here.
### 2.6 Event-ring flow control (ARCHITECTURE §11.7 made real)
@@ -92,15 +92,19 @@ DECLINED 有三条**完全不含损坏**的产生路径,两条在服务端、
谓词里新增的那一支**在 `#if MOBILEGL_BUILD_DISAGGREGATED` 内**,fall-through 是原来那一行表达式;
其余改动全部落在 split-only 的翻译单元(`MG_Remote/**`)或 `PipeFill.cpp` 的 `#if MOBILEGL_BUILD_DISAGGREGATED` 块内。
因此 pull 臂预处理后与改动前**逐字符相同**;G1 的符号/`.text` 断言仍按惯例由 CI 的 pull 车道给出(本机未复核,见 §3)。
因此 pull 臂预处理后与改动前**逐字符相同**。**本机已按 G1 跑过 A/B**:pull 配置(Release、`/usr/bin/c++`、`MOBILEGL_BUILD_DISAGGREGATED=OFF`、`--target MobileGL`)在 `c984d952`(基线)与 `3b9f536d`(本轮)各建一次,结果 `.text` **13872002 = 13872002** 字节、符号 **31746 / 31746**、**0 增 0 删**,逐符号 `comm` 无任何差异(两棵树留在 `build-g1-base/`、`build-g1-head/`,符号表在各自的 `syms.txt`)。
## 3. 本轮**没有**做的(下一轮的直接入口)
1. **真机端到端**:A 需要「进世界不再崩」、B 需要「那一帧墙钟 249 s → 约 20 s」的真机数字。需要重出 APK(`assembleTraceRelease` + 签名)、手机 `90cee93` 起 server、跨机 TCP 起 MC 26.2。
注意 handoff §1.3:**GL 别名软链(`/tmp/mgl` 五个)是必需的**,且本会话的 shell 沙箱给 `/tmp` 挂的是**每次命令全新的 tmpfs**,所以要在同一条命令里建链再跑。
2. **G1 本机复核**:pull 配置完整构建两次(带/不带本轮改动)比 `.text` 与符号集。CI 已断言,本机未跑。
3. **同类第二条**:`ResourceCreate` 与 `SetTextureParams` 也是逐条 kWaitReply(handoff §4.3 末条)。B 只处理了上传那半;这两条要单独分析(创建是按资源一次,参数设置是每次调用——收益与风险不同)。
4. **主机门的环境前提**:本机 shell 沙箱没有 `/dev/dri`,所以任何需要真 EGL pbuffer 的车道(`SpawnLane.EventForfeitPeer`、`TcpLane.EventForfeitPeer`)在本会话里必然红(子进程 `kEglSurface = 12`),与本轮改动无关;`EventForfeitPeerTest.cpp:134` 的注释本来就写明这种 runner 会「every case reds before the ring ever fills」。
注意 handoff §1.3:**GL 别名软链(五个)是必需的**,且本会话的 shell 沙箱给 `/tmp` 挂的是**每次命令全新的 tmpfs**,
所以要在同一条命令里建链再跑。本轮已把这条路径的工具做成持久版本放在仓库外的 `mgl-device/`:
`launch-mc.py`(按版本 JSON 重建启动命令,已干跑校验:95 条 classpath 条目全部存在、Java 25 由 `javaVersion.majorVersion` 选出)、
`gl-aliases.sh`(把五个别名建在 `mgl-device/gl-aliases/`,**不放 build 目录**:那里的 `libEGL.so` 会让 server dlopen 自己)、
`start-phone-server.sh`(装包 + 起 Activity + handoff 那两个就绪判据)。
2. **同类第二条**:`ResourceCreate` 与 `SetTextureParams` 也是逐条 kWaitReply(handoff §4.3 末条)。B 只处理了上传那半,
这两条要单独分析(创建是按资源一次,参数设置是每次调用——收益与风险不同);`CONTRACT-P5E.md` §2.5 已把这一条写成 "analyzed separately"。
3. **主机门的环境前提**:本机 shell 沙箱没有 `/dev/dri`,所以任何需要真 EGL pbuffer 的车道(`SpawnLane.EventForfeitPeer`、`TcpLane.EventForfeitPeer`)在本会话里必然红(子进程 `kEglSurface = 12`),与本轮改动无关;`EventForfeitPeerTest.cpp:134` 的注释本来就写明这种 runner 会「every case reds before the ring ever fills」。
## 4. 证据位置