Commit Graph

2 Commits

Author SHA1 Message Date
b879558947 feat(proc): 共享段 arena 容量可配置(启动期生效,需重启内核)
## 改了什么

- `proc.NewHostWithArenaSize(bytes)`:按给定容量建段;保留 `NewHost()`
  以兼容默认 4MB。
- 容量低于分配器最小尺寸时**返回明确错误**,不静默回落默认值
  (否则"我配了 32MB"会悄悄变成"仍是 4MB")。
- 删除 `arenaPublishSize` 变量:自从容量改为入参后已无人读取,
  留一个"看着能改、改了没效果"的开关比没有更危险。
- `core.plugin.shm_arena_mb`(默认 4,clamp 1..256):播种 + 定义 +
  `Registry.arenaBytesFromConfig()` 读取。越界时记日志说明被 clamp。

## 为什么容量只能在启动时决定

arena 是统一区域里一段连续 mmap,而 `SharedRef` 存**绝对偏移**。
变大需要 remap,而每个 plugin.bin 子进程可能正在读同一页 ——
跨进程 munmap 会让它 SIGSEGV。该路径历史上三次被明确搁置。
⇒ 本改动只决定"这次启动开多大",配置项描述里已写明需重启。

## 判据(`internal/plugin/proc/test/arena_contract_test.go`)

    TestArenaHostHonoursRequestedCapacity
      给定 8MB → 能写入并读回 4MB(证明容量真的生效)
    TestArenaHostRejectsTooSmallCapacity
      64 字节 → 明确报错

变异验证:
    忽略传入容量、总用默认 4MB   → 4MB 写入报「超出 arena 容量 4194228」
    过小容量改为静默回落默认     → 判据红

    go build ./... / go vet ./...                  PASS
    python3 .github/scripts/check-ci-gates.py      PASS
    go test ./... -count=1 -race                   51 包 / 100 包无测试 / 0 FAIL
    gofmt -l                                       干净
2026-11-14 11:32:03 +08:00
d0e4f10b53 test(proc): arena 共享内存的模块职责判据(面向接口)
只用公开入口 proc.NewHost() 与 Host.Arena() 的导出方法;断言只看
"写入的字节能否原样读出 / 操作成功与否 / 空间能否被再次使用",
不碰块头布局、空闲链结构、内部字段。

    写入→读出→归还→同尺寸再写入
    超限请求失败且不破坏分配器
    非 owner 归还被拒、块仍可读
    旧 generation 读取报错(不返回错位数据)
    插件退出回收后空间可复用
    回收不波及内核自有块
    伪造 offset 被拒
    重复归还被拒
    碎片化导致大请求失败(钉住现状)

变异验证:
    Free 不标记为空闲      → 第二次 Put「空间不足」红
    去掉归属校验           → 非 owner 归还被接受
    去掉 generation 校验   → 过期引用被接受

## 实测发现的真实碎片故障

4MB 段内用 1MB 大块与小块交替铺满、释放三个大块后:

    used=64 total=4194308 blocks=8
    请求 2096090 字节 → arena: 空间不足(请求 2096090 字节,容量 4194228)

空闲总量远超请求,但被小块隔开 ⇒ first-fit 拿不到连续块。
Exchange Arena 只有邻块合并,没有整体整理(唯一的 Compact 属于
StageContext 段,不是这块内存)。

## 未完成(见 todo.md §7.2)

块搬运会改变 SharedRef.Offset,而持 ref 的是插件侧/调用栈局部变量,
内核无法批量改写 ⇒ 整理会使命中窗口内所有 ref 失效。需先决定形态
(仅内核自有块 / 零活跃窗口 / 改分配策略),再实现。

    go test ./internal/plugin/proc/test -count=1 -race   PASS
    go build ./... / go vet ./...                       PASS
    gofmt -l                                            干净
2026-11-14 11:20:42 +08:00