Repository navigation
Releases: Linductor-alkaid/kairo
Release list
kairo v0.7.3
[0.7.3] - 2026-10-29
0.7.3 主体内容(roadmap §5):堆分配优化阶段二(TaskResult 轻量
Future + submit_v2)、返回值语义补齐(取值 CpuGpuTask +
ResultAdapter + ExecutionReport),以及先行落地的分主体在途份额
admission(issue #222 / Mira 台账 EXE-20261028-001)。全部为
additive;submit() 等既有 API 行为与 0.7.2 逐项一致。设计见
docs/design/scheduling_runtime.md §16/§17 与
docs/design/subject_bucket_admission.md。
新增
-
TaskResult 轻量 Future 与
Executor::submit_v2(roadmap §5.0,
堆分配优化阶段二):<kairo/task_result.hpp>单次分配的
promise/future 一体单元——结算仲裁(settled CAS)与值发布(ready
release/acquire)分离,get()快速路径无锁读值(实测命中率 99.7%);
submit_v2与submit语义逐项同构(admission / 空任务拒绝 /
queued soft timeout / 异常与超时观测 / 释放时序),提交上下文与
bind 结果本体并入同一控制块。实测 submit 主路径 4.00
allocs/task / 488 bytes(v0.7.2 submit 为 7.00 / 512;旧路径
不变)。broken promise 契约与 std::promise 析构对齐:
shutdown(false) 丢弃排队任务时 get() 以
future_error(broken_promise) 就绪,不挂死。可观测:
AllocationMetrics追加fast_path_get_count/
slow_path_get_count("快速路径命中率" = fast/(fast+slow))。迁移
策略:opt-in 新 API,submit()不受影响(0.8.0 前不弃用)。 -
取值 CpuGpuTask + ResultAdapter + ExecutionReport(roadmap §5.1):
CpuGpuTask<CpuFunction, GpuFunction, R = void>(末尾默认模板参,
两参拼写与 void 语义逐位不变)+cpu_gpu_task<R>(cpu, gpu)工厂 +
CpuGpuTask::result_adapter()。R 非 void 选中 GPU 时必须显式提供
ResultAdapter<R>::gpu_extract(GPU worker、GPU callable 返回后
调用;async 配置 = launch 完成点,设备搬运与同步责任在用户侧),
否则按 fallback 提交前结构化拒绝或 AllowCpu 回退——宁拒不静默降级
void。submit_auto(CpuGpuTask)泛化为条件返回:void 实例化逐位
不变;非 void 产出ExecutionReport<R>{result, decision}(报告
实际选择路径;回退时 decision 记录回退后最终路径;拒绝时 result
以 runtime_error 就绪、报告即终态)。GPU 结算双保险:kernel 包装
主结算(成功值/异常保真)+ stream 完成计时 sink "恰一条交付"兜底
(校验失败/launch 失败/post-kernel 设备错误/停止排空全路径)。需要
不支持完成计时的 GPU 执行器承接取值任务会被提交前拒绝。 -
分主体在途份额运行期接口:
Executor::set_subject_max_in_flight_tasks(subject, max)
(max == 0解除该主体约束)、get_subject_max_in_flight_tasks()、
get_subject_in_flight_submissions()、get_subject_quota_status()
(SubjectQuotaStatus快照,按 key 排序)。每个已配置主体独立计数在途
提交并以份额约束,与全局max_in_flight_tasks同时生效;仅运行期接口,
ExecutorConfig无初始映射。 -
分桶键进入提交 API:
TaskOptions::subject(空 = 不分桶)+
TaskBuilder::subject()。一期带键路径 =submit_auto(TaskBuilder)与
submit_after*(TaskBuilder);其余提交路径仅全局约束(见 API.md §3.12
覆盖路径说明)。 -
拒绝可区分性(共用 §3.11 拒绝面,不新造异常/failure kind):
ExecutorFailureStatus追加subject_quota_exhausted_count(分桶拒绝时
与capacity_exhausted_count同时递增,前者是后者子集);
ExecutorFailureEvent追加subject字段(分桶拒绝携带键,空 = 总量
拒绝)。分桶拒绝消息Subject in-flight quota exhausted (key=…)。 -
测试:
tests/test_subject_bucket_admission.cpp(standalone)锁定
份额互不影响、分桶/总量拒绝可区分、终态恰好一次释放、热更新/解除、
shutdown 与零回归锚;tests/test_subject_quota_concurrency.cpp
(standalone,参与 TSAN job)锁定并发契约——热更新严格可见性与并发
交错弱一致、解除/重建代际隔离、stress 下无泄漏/无越权/恰好一次释放;
tests/test_api_doc_admission_fields.cpp扩展锁定新字段与 API.md
§3.12。 -
并发契约文档化(PR #223 审查):热更新弱一致语义(接纳快照点 =
注册表查表临界区;set 完成后的新提交必用新份额,交错中的已开始接纳
允许按旧快照完成)与代际语义(活键原位缩放同代;set(key,0) 解除即刻
生效、已接纳落账孤儿计数;同名重建新代从 0 起计不继承残量;查询面只
反映当代)。见docs/design/subject_bucket_admission.mdD-2/D-5。 -
裸形态带键入口(修订 R-1,下游反馈):
submit_auto(kairo::subject("key"), fn)
——裸 callable 写法经SubjectKey标签进入分桶接纳点,与带键
TaskBuilder 形态语义逐位一致;SubjectKey构造 explicit(字面量误用
编译失败而非静默错绑)。SubjectQuotaStatus追加admitted_total
(当前代累计接纳数):份额已配置但该值停在 0 = 键未生效。 -
键脱敏约定与低报警示(修订 R-2/R-3,下游反馈):分桶键逐字复制进
异常消息/failure 事件/状态快照,必须使用不可识别的派生标识,键集清理
责任在调用方(API.md §3.12);解除后同名重建的短暂窗口内
get_subject_in_flight_submissions()低报真实在途(差额上界 = 解除前
份额),已提升为显式调用方注意事项,监控口径 = 超额上界 + 自愈时间。
设计记录见docs/design/subject_bucket_admission.md修订节。
修复
submit_priority_scheduled异常终态的数据竞争(发布前混合负载
soak 的 TSAN 短 soak 实证,45 份同根因报告):任务包装在
promise.set_exception发布之后仍经is_deadline_drop_exception
(rethrow 语义)访问异常对象本体,与消费者线程的 catch/析构并发
——分类移到结算前,DropIfLate 归类与 failure 观测语义逐项不变。
修复后 TSAN soak 零报告(129k 次异常路径同等覆盖)、退出码 0。
稳定性验证(发布门禁)
- 40.2 分钟自适应调度(AdaptiveScheduler 注入)混合负载 soak:
12 通道(submit/submit_v2/submit_auto(TaskBuilder)/cpu_gpu 回退/
SubjectKey/tracked/delayed/cancellable+取消竞态/batch/周期+重排),
54,337,566 提交 == 结算(零丢失),均值 22,546 tasks/s;
RSS 平稳(479 样本回归斜率 1.37 MiB/h,无趋势);观测面单调性
零违规;closure_graveyard_size()==0;池命中率 1.0;TaskResult
快/慢 get 7,832,436/0。24h 级持续 soak 留作 0.7 系列回归项。
kairo v0.7.2
[0.7.2] - 2026-10-19
优先级语义转移到调度器(roadmap §4.0,0.7.x 唯一破坏性变更)+
堆分配优化阶段一(§4.1)+ 反馈覆盖扩展(§4.2)+ 生命周期可靠性
收尾(§4.3)。设计记录见 docs/design/scheduling_runtime.md
§14/§15 与 docs/design/priority_refactoring_decision.md。
变更(Breaking,仅此一项)
Executor::submit_priority已移除(0.7.2-rc1 曾标记
[[deprecated]]):优先级是调度策略维度而非提交协议,统一经
submit_auto(kairo::TaskBuilder(fn).priority(p))表达——与
QoS/deadline 共享同一IScheduler协议(effective_priority_for()
咨询、显式 priority 永不被覆盖)。调度顺序(priority → EDF → FIFO)
与 0.7.1 逐位一致:共享内部实现
submit_priority_scheduled保留(供 facade 复用,非公共协议),
admission 与task_id(facade_submit_priority)不变。submit_batch_priority行为不变、内部改走共享实现:不再经由
submit_priority(已移除),无弃用警告路径。- 内部层
ThreadPool::submit_priority/try_submit_priority*不变。
新增
- 迁移脚本
scripts/migrate_submit_priority.sh:自动改写
submit_priority(P, callable)两参模式(整数字面量映射
TaskPriority枚举,变量经static_cast);带额外绑定参数的调用
保留原样并逐条报告。--dry-run预览。 - 堆分配优化阶段一(roadmap §4.1):submit 主路径
9 → 7 allocs/task(-22%)、768 → 512 bytes/task(-33%)。
① Task 调度节点对象池(PriorityScheduler 内定容 256 Vyukov MPMC
空闲表,单元序号防 ABA,析构-重建严格重置协议;命中率实测串行
100%、并发 99.1%~100%,池满/池空自动回退堆分配,语义零变化);
② facade 提交路径单控制块整合(submit 与
submit_priority/submit_auto(TaskBuilder) 共享路径的 promise/ready、
提交上下文、admission 释放链、资源租约、move-only bind 结果并入
单次分配;包装层捕获从多字段降为单 shared_ptr/裸指针,包装层分配
5 → 2 次)。自动生效、用户无感知、无行为变化。独立验证:hotpath
吞吐 10 轮交错 p=1 +22.6%、p=2..16 容差内,TSAN 15/15 与 ASAN 6/6
零报告。实施记录与草案偏差清单见
docs/design/allocation_optimization_proposal.md§9。 - 可观测性 API:
AllocationMetrics(types.hpp,Task 节点池命中/
未命中累计);Executor::get_allocation_metrics()与
Executor::get_task_pool_hit_rate()(默认池快照,未初始化返回零);
IAsyncExecutor::get_allocation_metrics()虚方法(additive,默认零)。 - 反馈覆盖扩展(roadmap §4.2):measurement contract 扩展到
GPU / lockfree / realtime。① 聚合级执行反馈:AggregateExecutionStats
(executed/over_budget/period 累计计数)+
IRealtimeExecutor::get_aggregate_execution_stats()(默认零)+
Executor::get_aggregate_execution_stats(name)/
get_all_aggregate_execution_stats();realtime 执行线程内仅
relaxed 原子计数(无逐任务回调、RT 无分配约束不破坏),lockfree
超预算计数经 opt-inLockFreeTaskExecutor::set_execution_budget_ns()
(默认 0 = 关闭计时)。② GPU stream 完成回调计时:IGpuExecutor
新增supports_completion_timing()/submit_kernel_with_timing()
与gpu::GpuKernelTimingRecord(每提交恰一条,completion_ns==0
语义为"未知");CudaExecutor async kernel 经cudaLaunchHostFunc
探针观测完成点,回调内不做任何 CUDA 调用、计时数据转交执行器线程
后才调用 sink(CR-153 结构性履行);submit_gpu新增带 sink
overload,submit_auto(CpuGpuTask)在 wants_feedback() 且执行器
支持时自动走计时路径(execution_duration 观测至 stream 完成点,
queue_wait 含执行器内部队列等待),不支持时回落既有 host 侧包装。
独立验证:新测试 19/19,全量回归 178/182(4 失败为预存 flaky,
A/B 定性),TSAN 零告警。实施记录见
docs/design/scheduling_runtime.md§15。
修复(roadmap §4.3 生命周期可靠性收尾)
- CR-054:实时线程内置循环的 stop 改为可中断等待(cv 绝对等待 +
stop 通知),stop 延迟不再随周期线性增长;自停止请求后不再发起新
一轮用户周期回调。 - CR-055:BlockingIO 的用户
wakeup()移出生命周期锁(重入不自
死锁);并发 stop 新增终结栅栏,不再提前返回观测到未终结状态。 - CR-057:SerialExecutionContext 新增
reserve_guarded()RAII 预留
句柄——未 publish 析构自动 abandon,预留永不 publish 不再能卡死整
个上下文的 FIFO 水位;修复 worker 线程内自析构的 terminate 隐患与
shutdown join 判定的数据竞争。 - CR-105:
WorkerHandle经生命周期令牌作失效检测,facade 析构后
操作退化为无操作而非悬垂解引用。 - CR-113 / CR-114:
ThreadPool::resize事务化(线程创建失败整体
回滚,不再留下队列数 ≠ worker 数的半更新状态);worker 线程内缩容
显式拒绝(防自 join)。 - NN-09:
DropPolicy::KeepLatest饱和语义修正为滚动窗口——
只逐出最旧一条(计一次 overwrite),保留最新 capacity 条含新值;
此前会丢弃整个队列内容。"坍缩为最新 1 条"的 mailbox 语义由
LatestMailbox 承担(行为变更,钉死旧行为的测试已同步更新)。 - CR-154:GPU stop 语义显式化——
gpu::GpuStopMode{Drain, Cancel}IGpuExecutor::stop(mode);CUDA/OpenCL 的无参stop()保持各自
0.7.1 默认(排空 / 取消)。
- CR-023:worker 队列 push 的字段拷贝抛出时归还 Task 内存(不再
泄漏)。 - CR-136:
TimerOperationResult新增InternalError(additive)——
定时器 request_cancel/reschedule 的内部异常不再伪装成 NotFound。 - CR-115 / CR-043/129 / CR-116/123/125/126/134:契约文档化——
shutdown join 无超时明示(@warning);Topic::publish 异常契约;
其余 P2 项定性注释落源码,结果回写评审文档。
文档
docs/MIGRATION.md新增 0.7.2 节(语义等价性说明、迁移模式表、
排查清单);docs/API.md§3.2 改写为弃用注记 + TaskBuilder 示例;
website priority 教程(中英)全面改写,choosing-submit-api /
what-is-kairo / decisions / concurrency-antipatterns 同步新表达;
版本与迁移页(中英)新增 0.7.2 开发快照。示例(basic_submit、
tutorial/02_priority)与 facade 层测试调用(8 处)全部迁移。- CI(NN-03):realtime-allocation-guard job 扩为 guard-ON 全量
构建 + realtime/lockfree/object_pool 套件(此前仅 guard 自身测试)。
kairo v0.7.1
[0.7.1] - 2026-10-14
v0.7.1 全部四个阶段:submit_auto 路由智能化(roadmap §3.0.1 含
§3.0.2/§3.0.3)、deadline policy(§3.2)与资源预留 ResourceLease
(§3.1)。全部为 additive(资源预留与自动推断默认关闭);默认行为
与 0.7.0 逐项一致(tests/test_capability_cache.cpp 锁定缓存开/关
的决策一致性,tests/test_deadline_policy.cpp 锁定默认策略 =
0.6.x,tests/test_resource_lease.cpp 锁定未启用预留 = 0.7.0,
tests/test_auto_inference.cpp 锁定默认无推断/DefaultScheduler
不做执行器自动选择)。
调度
-
能力快照 TTL 缓存(submit_auto 路由智能化 §3.0.1):
submit_auto
的 CpuOrGpu / affinity 路由与dispatch_auto的能力消费默认经 TTL
缓存(100ms)读取,命中路径不再逐次锁 Manager 注册表采集。不可变
快照经 M2 同款可移植 RCU 槽发布(scheduling::detail::SnapshotSlot
泛化为SnapshotSlotT<T>,既有别名不变);命中判据为 manager
state_epoch未变且未过 TTL——注册/启停/shutdown 主动失效,TTL 只
兜底 pending_work / GPU 可用内存等运行期数值漂移。facade 的
start_realtime_task/start_blocking_io_worker此前绕过注册表
启停后端,现于成功后调用新增的
ExecutorManager::notify_backend_state_changed()推进 epoch。
命中决策带RoutingDiagnostics::CapabilityCacheHit(1u<<7)位与
RoutingDecision::capability_from_cache字段;SchedulingMetrics
新增capability_cache_hit_count/capability_cache_miss_count
(访问点统计,与决策记录解耦)。控制 API:
Executor::set_capability_cache_ttl()(0 关闭)/
capability_cache_ttl()/invalidate_capability_cache();公开的
get_executor_capabilities()保持实时采集语义不经缓存。
验收(配对 A/B,验收线内置benchmark_scheduling_paths§5):缓存
命中移除端到端 36.6% 采集成本(1415 → 898 ns/op,Windows MSVC
Release;线 warm ≤ 0.9 × fresh)。契约测试
tests/test_capability_cache.cpp(14 用例):计数与来源标记、TTL
过期/关闭/重设、TTL 内注册-启动-停止主动失效、决策一致性矩阵、
并发 + epoch 扰动下 hit+miss 守恒。 -
deadline policy(roadmap §3.2,additive,默认 = 0.6.x):
TaskOptions::deadline_policy(DeadlinePolicy::RunAnyway默认 /
DropIfLate/CancelIfLate)在开始执行时裁决——与 0.6.1
miss-observe 同点、同"严格已过才算错过,恰好相等接受"边界,不影响
提交时点的DeadlineExpired准入拒绝与 EDF 排序。RunAnyway:0.6.x 行为逐位一致(错过仍执行 + DeadlineMissed
failure 事件)。DropIfLate:错过不执行用户代码,future 以
TaskCancelled(TaskCancellationReason::DeadlineMissed)终态就绪;
计deadline_missed_count+ 新增deadline_dropped_count;遵循
取消类约定不进 failure 统计(结算分类器
is_deadline_drop_exception保证不落入 task-exception)。CancelIfLate:错过向协作停止源发请求(非抢占),任务仍启动,
用户代码经新增的kairo::get_stop_token()(<kairo/stop_token.hpp>,
inline thread_local + RAII 守卫,嵌套安全)轮询并自行退出;
非任务上下文返回空令牌。- 依赖传播:tracked 提交新增
submit_after / submit_after_with_handle的 TaskBuilder 重载(携带完整
TaskOptions:deadline/策略/QoS/优先级,QoS→默认优先级映射与
effective_priority_for咨询语义与submit_auto一致)。上游
DropIfLate 丢弃 → 任务图落 Failed(异常TaskCancelled(DeadlineMissed))
→ 下游经既有reclassify_dependency_exception规则收到
TaskCancelled(DependencyCancelled),零新增传播机制。 - 边界:
CpuGpuTask本阶段忽略 policy 字段(维持 feedback 级
miss 观测);无 deadline 时策略字段无效。契约矩阵
tests/test_deadline_policy.cpp(14 用例:边界不漂移、三策略 ×
强制错过、依赖传播矩阵、指标守恒)。
-
资源预留 ResourceLease(roadmap §3.1,additive,默认关闭):
ExecutorConfig::enable_resource_reservation+resource_quota
(新增公开头<kairo/resource_lease.hpp>:GPU 显存/并发槽按
device 分桶、CPU 独占核总量的显式配额)启用后,声明了
resources()的submit_auto(TaskBuilder)与 tracked TaskBuilder
提交在 admission 时从配额真正扣留,闭合多提交在 admission 与执行
之间超卖同一资源的 TOCTOU 窗口;任务终态归还。- 授予全或无:联合需求任一维度不足整体拒绝、零部分授予;GPU 维度
缺 device →InvalidRequirement,device 未配额 →NotConfigured。 - 决策一致性:submit_auto 在记录决策前预留,失败改写为
CapacityPressure+ResourceInfeasible(计入既有
resource_rejected_count);tracked 路径以结构化拒绝结算。 - 终态释放:
detail::TerminalReleaser(CAS 恰好一次 + 析构兜底)
经submit_priority_scheduled/submit_tracked_with_hook新增
的terminal_release参数接入既有 admission 释放链——成功/异常/
协作取消/丢弃/软超时/提交拒绝/shutdown 排空全部路径归还。 - 手动入口:
Executor::try_reserve(req) -> ReservationResult
(RAIIResourceLease,move-only、release 幂等)+ 诊断快照
get_resource_reservation_status();ResourceRequirements新增
gpu_concurrent_slots/cpu_exclusive_cores维度。 - 契约测试
tests/test_resource_lease.cpp(12 用例:opt-in 边界、
手动授予/拒绝/RAII、GPU 各维度、任务绑定终态归还、并发超卖、
终态释放矩阵、tracked 预留、多维全或无)。
- 授予全或无:联合需求任一维度不足整体拒绝、零部分授予;GPU 维度
-
任务特征自动推断与执行器自动选择(roadmap §3.0.2/§3.0.3):
- 自动推断(opt-in,
enable_auto_inference默认关闭;运行期
set_auto_inference_enabled()可调):submit_auto 按任务名
模式与同名任务完成间隔规律(有界 64 键历史表
<kairo/task_inference.hpp>,采样经反馈通道,启用时自动附加
测量包装)产出建议性推断——决策带AutoInferredIntent
(1u<<5)位 +RoutingDecision::inferred_reason+ detail 建议
(blocking → start_worker / 低延迟 → dispatch_auto /
periodic → submit_periodic),路由不被改变(submit_auto 的
future 契约只有默认池能履行——"建议优先于切换"的强制形态);
显式 intent 优先并计auto_inference_rejected_count,建议计
auto_inferred_count。 - 执行器自动选择(随 AdaptiveScheduler 注入 opt-in):
IScheduler新增select_bounded_executor()虚方法(默认返回
空,DefaultScheduler 与既有自定义调度器行为不变);未指定
preferred_executor 的dispatch_auto(LowLatency)由
AdaptiveScheduler 按瞬时队列负载(pending_work/capacity_hint)
选择 lockfree 执行器,并列取名字序,决策带AutoExecutorSelection
(1u<<6)位 +auto_executor_selected_count。选择只用能力
快照(经 TTL 缓存)——lockfree 反馈通道在 v0.7.2 接入前不做
历史负载(冷启动即安全)。 - 契约测试
tests/test_auto_inference.cpp(11 用例:opt-in 边界、
模式注解与路由不变、显式覆盖、运行期开关、推断表 EWMA/periodic/
键空间上界、自动选择单元矩阵与 dispatch 集成、DefaultScheduler
回归守卫)。
- 自动推断(opt-in,
提交路径
submit_fast()评审移除(§3.0.1 收敛):路线图曾规划零路由
快速提交路径;实现后与submit语义重复(等价
submit_priority(NORMAL, ...)),配对实测普通提交通道反而快
31.4%(1881 vs 2473 ns/op,Windows MSVC Release),按 2026-10-14
评审决定移除该 API、保留submit。零路由语义本就由submit
承载(submit 系列从不产出路由决策);§3.0.1 的实际性能收益由
能力快照缓存承载。基准benchmark_scheduling_paths§6 改为
submit vs submit_auto 裸 builder 守卫(submit ≤ 1.05 × bare)。
文档
docs/design/scheduling_runtime.md新增 §10(能力缓存设计语义与验收、
submit_fast 评审移除记录)与 §11(deadline policy 设计语义与验收矩阵);
docs/API.md§3.7/§3.8、docs/MIGRATION.md新增
"从 0.7.0 升级到 0.7.1"(无必需迁移);版本与迁移页新增 0.7.1 开发
快照小节(含 submit_fast 评审移除结论),中英选型页同步纯提交路径
评审结论;docs/skill调度卡(kairo-integration / kairo-maintainer)
同步新 API 与诊断通道。
kairo v0.7.0
[0.7.0] - 2026-10-10
v0.7.0 前置清债(M0,docs/design/roadmap_v0.7.md §2.1):在引入任何
自适应调度代码之前,先消除会污染反馈测量或放大自适应风险的遗留项。
全部为 additive 或纯结构改动;默认行为与 0.6.1 一致。
结构
- executor.cpp 拆分(纯结构,零行为变化):2242 行单体实现按职责
拆为executor_lifecycle/executor_task_graph/executor_timers/
executor_backends/executor_routing五个编译单元,共享辅助提取到
内部头src/kairo/executor_detail.hpp。方法集合(117 个)与导出符号
面逐一核验不变。
线程池
- 可选防饿死 aging(CR-024,additive,默认关闭):
PriorityScheduler::set_aging_policy(enabled, boost_interval_ns)。
开启后 dequeue 在全部非空队列堆顶中按
(有效优先级, EDF, 提交 FIFO)选取——堆顶任务每等待
priority_aging_interval_ns提升一级有效优先级(至多 CRITICAL),
队列内部堆序与任务自身 priority 不改写。关闭时出队路径与 0.6.1
逐位一致。ThreadPoolConfig/ExecutorConfig新增
enable_priority_aging(默认 false)与
priority_aging_interval_ns(默认 100ms)。NN-05 本地队列倒置窗口
维持文档化现状(worker 扫描顺序未变)。
可观测性
- TaskMonitor 分片化与热路径门控(CR-071/CR-163):单把全局 mutex
改为哈希分片(id 映射与 in-flight 快照按 task_id 分 16 片,聚合统计
按 task_type 分 8 片),dropped/evicted/in-flight 计数改原子。
新增热路径快速门:统计采样率为 0 时不触碰 id 映射与统计分片;
in-flight 采样率为 0 或容量为 0 时不触碰 in-flight 分片——两门全关时
record_task_start/complete/timeout零取锁。配套语义补全(对齐
set_enabled(false)):set_sampling_rate(0.0)现在清空 task_id→type 映射:已开始未结算
的统计样本随清空丢弃(语义即"关闭统计采样");set_in_flight_sampling_rate(0.0)现在清空 in-flight 快照(此前
已采样条目会残留至被 complete 擦除)。
in-flight 容量语义微调:分片化后为跨分片软上界(原子计数预留,
并发下至多短暂超限 1-2 条)。验收:采样率 0 时多线程提交吞吐与
关闭监控持平 ±5%(配对实测 ±1.2%)。
提交路径
- 每任务堆分配基线(CR-107,第一阶段):
submit()主路径的
promise 与 ready 标志合并为单控制块(detail::PromiseCell);
generate_task_id经std::to_chars单次拼接;池提交路径消除
monitor_id 中间拷贝。新增benchmark_submit_allocations基准
(替换全局 operator new,确定性计数):submit 路径 10.00 →
9.00 allocs/task(816 → 768 字节/task),tracked 路径 19.13 不变。
剩余分配项受结构约束(move-only 可调用需间接层、双 std::function 是
后端接口、Task 含 atomic、快照字符串是公开契约),留待接口层调整。
任务依赖
- 依赖环检测增量化(CR-052):
TaskDependencyManager引入
Pearce-Kelly 风格增量拓扑序(节点序号 + 反向边表)。加边快路径
O(1)(序约束已满足),不再做锁内全图 DFS;违序时三段式受限重排,
环检测并入同一次遍历。链式建链从 O(n²)(n=4000 约 3.9s)降至
n=20000 约 28ms;与插入序完全相反的最坏形态仍为 O(n²) 纯内存遍历
(与旧实现同阶,facade 真实形态全走快路径)。新增
test_task_dependency_topo(17 用例,含 n=20000 规模回归与固定种子
随机对拍)。
调度
-
DefaultScheduler route() 内部 pipeline 化(M1,纯结构):
route()重构为约束过滤 → 候选生成 → 评分/排序 → 选择四阶段。
新增公开头include/kairo/scheduling_pipeline.hpp:
DeadlineConstraintFilter/GpuResourceConstraintFilter/
ConstraintFilterChain<>(约束过滤,可编译期组合、首个拒绝短路)、
IntentCandidateGenerator(0.6.1 意图路由决策树)、
IdentityScoring(空评分实现)、select_first/
apply_affinity_advisory(选择与 advisory)。各阶段可组合,
后续 AdaptiveScheduler 复用过滤与候选生成、只替换评分。
IScheduler对外接口不变,决策结果与 0.6.1 逐项一致
(契约测试test_scheduling_contract_v061.cpp一字不改通过);
TaskRouter::route()保留为"无过滤/无评分/无 advisory"参考路径。
热路径实测快于 0.6.1 基线(阶段折叠为单一扁平函数,基线 36.5ns →
35-36ns,配对 ABBA 4 轮)。 -
反馈聚合层 FeedbackAggregator(M2,additive,默认零开销):
新增公开头include/kairo/feedback_aggregator.hpp。record()在
worker 线程无锁、无分配、noexcept 地累加执行期样本(EWMA 队列等待
与执行时长、分桶直方图、失败率、deadline 错过),按
(backend, executor_name, qos)分键,per-worker 固定 32 分片(进程级
thread_local 槽位稳定映射)。读方只读周期性合并出的不可变快照
(RCU 风格原子 shared_ptr 指针交换发布,读路径无锁)。键空间有界
(每分片默认 16 槽、上限 64),表满后新键样本丢弃计数——"未知即
宽容"。样本与 0.6.1 测量包装同源:仅注入wants_feedback() == true
的调度器时才有流入,默认调度器行为与开销不变。Executor新增
get_feedback_snapshot()(诊断用),get_snapshot_text()追加
scheduling_feedback.*段。新增benchmark_feedback_aggregator
(--json,验收线内置):record 快路径实测 23.8ns/task(预算
≤100ns);facade 端到端(提交→worker 反馈→聚合转发)与只计数
调度器的差值在调度噪声内不可分辨(±40ns)。基准结果记录于
docs/performance/m2_feedback_aggregator_results.md。 -
AdaptiveScheduler(M3,opt-in 自适应,DefaultScheduler 不变):
新增公开头include/kairo/adaptive_scheduler.hpp。复用 M1 pipeline
产出 0.6.1 基线决策、内嵌 M2 FeedbackAggregator 作决策输入,实现
roadmap §2.4 收窄后的三类可解释决策:- CPU/GPU 历史选择(CpuOrGpu):端到端时延 EWMA 两侧对比,
双侧样本 ≥min_samples才采信历史(不足回退 0.6.1 启发式),
切换需优于在用侧(1 - hysteresis_margin)(防震荡);命中历史
→RoutingReason::AdaptiveHistory+ 诊断位 + detail 携带两侧
EWMA 数值。submit_auto(CpuGpuTask)补齐 CPU/GPU 两侧测量包装
(此前该路径不产生反馈);RequireRequestedBackend不做历史
翻转;facade 对"启发式选 CPU + 非 AllowCpu 拒绝"规则豁免
AdaptiveHistory 决策(启发式路径逐位不变)。 - QoS 感知降载:按 QoS 类对 queue-wait 直方图做窗口差分后
求 p99,连续shed_breach_windows个评估窗口超目标 → 开闸,对
严格更低 QoS 的提交返回结构化拒绝(新增
RoutingReason::LoadShedding+ 诊断位);连续shed_close_windows
个恢复窗口才关闸(开/关对称滞回);证据不足 fail-open。与
max_in_flight_tasks硬上界共存。 - QoS→priority 有界提升:
IScheduler新增
effective_priority_for()(默认原样返回);长期超阈的 QoS 类
默认优先级 +1 级(封顶 CRITICAL),显式 priority 永不被覆盖,
被调整提交计数priority_promoted_count。
SchedulingMetrics新增adaptive_history_count/
load_shedding_rejected_count/priority_promoted_count;Executor
的route_task归一化与指标计数同步扩展。新增
benchmark_adaptive_scheduler(验收线内置):route 纯策略路径配对差
18.8ns(线 ≤150ns)、CpuOrGpu 冷路径 30.5ns(线 ≤250ns)、
on_task_completed 转发 22.6ns(线 ≤150ns)、effective_priority_for
0.74ns;降载场景 Interactive 探针端到端 p99 自适应 1.3-4.2ms vs
DefaultScheduler 10.8-16.9ms(绑核配对,160-168 次结构化拒绝)。
基准结果
记录于docs/performance/m3_adaptive_scheduler_results.md。
- CPU/GPU 历史选择(CpuOrGpu):端到端时延 EWMA 两侧对比,
文档
- 0.7.0 文档与发布同步(roadmap §2.5):
docs/MIGRATION.md新增
"从 0.6.x 升级到 0.7.0"一节(无必需迁移:新头文件、
IScheduler::effective_priority_for默认实现、新 reason/诊断位/计数
的穷举 switch 注意事项);docs/API.md§3.8 追加 0.7.0 开发快照
(pipeline 组件、FeedbackAggregator、AdaptiveScheduler 决策语义与
诊断接口)。网站新增中英文选型页"何时使用 AdaptiveScheduler"
(website/{zh,en}/guides/adaptive-scheduling.md,重点覆盖震荡、
冷启动、不可复现性),版本与迁移页新增 0.7.0 开发快照小节,API
覆盖索引接入调度策略行,GPU 自动选择 / 执行模型 / 调度运行时教程
页补开发快照交叉注记;docs/skill两张调度卡(kairo-integration /
kairo-maintainer)同步 0.7.0 自适应层与测试清单。
性能
- M0 前后基准对比记录见
docs/performance/m0_debt_paydown_results.md:两个既有热路径基准
(benchmark_scheduling_paths/benchmark_thread_pool_hotpath)
配对验证无回归;EDF dequeue 的关闭路径仅增加一次原子读。
kairo v0.6.1
[0.6.1] - 2026-10-06
0.6.1 不扩张调度策略维度,对 0.6.0 建立的 Scheduling Runtime 边界做
稳定化、可观测性补全与工程验证。全部为 additive extension:不改变
提交协议、调度模型语义,也不包含任何自适应调度行为。设计文档:
docs/design/scheduling_runtime.md §6。
Scheduling Runtime 可观测性
- 结构化路由决策:
RoutingDecision新增status
(Accepted/AcceptedDegraded/Rejected,接受/拒绝的权威判据)、
diagnostics位掩码(RoutingDiagnostics::AffinityMismatch/
ResourceInfeasible)与稳定 reason code——过期 deadline 拒绝从泛化
Rejected细化为DeadlineExpired,affinity 不相交从 detail 前缀
升级为AcceptedDegraded+AffinityMismatch。detail仅供人阅读,
不再是程序判断调度结果的唯一接口。新增
routing_status_to_string()/routing_reason_to_string()。 - 0.6.0 风格自定义调度器兼容:只设置拒绝类 reason、未设置 status
的决策由Executor::route_task()归一化为Rejected,行为不漂移。 - 调度指标:
Executor::get_scheduling_metrics()返回
SchedulingMetrics单调计数(accepted / accepted_degraded /
rejected / deadline_rejected / backend_unavailable_rejected /
capacity_rejected / resource_rejected / affinity_mismatch /
deadline_missed / feedback_reported)。计数在
record_routing_decision内以 relaxed 原子无条件累加,不受 CR-106
观测开关影响,无需预先配置即可读取调度健康度。 - 执行期反馈(measurement contract):
SchedulingFeedback扩展
backend / executor_name / queue_wait_ns / execution_duration_ns /
had_deadline / deadline_missed / failure_kind(success 时
FailureKind::None);IScheduler::wants_feedback()(默认 false,
DefaultScheduler不消费)作为热路径开关——关闭时反馈通道零开销,
开启时按任务付 2 次时钟采样 + 一次 worker 线程同步
on_task_completed()(异常隔离)。覆盖实际开始执行的默认池任务;
v0.7.0 前不实现任何基于反馈的自适应策略。
契约锁定与文档治理
- deadline 准入边界锁定:严格已过(
now > deadline)才拒绝,恰好相等
接受;错过仍"记录 miss 但执行"。 - capability snapshot 弱一致语义文档化:未知即宽容(跳过检查)、已知
但不满足即结构化拒绝(ResourceInfeasible诊断位)、admission
feasibility 不等于 execution guarantee(TOCTOU 由后端执行失败报告)。 - CpuGpuTask 的 heuristic-CPU + 非 AllowCpu fallback 组合在记录决策前
修正为Rejected,计数与最终投递结果一致(0.6.0 会先记录 Accepted
再拒绝)。 - 新增
scripts/check_docs_drift.sh并接入 docs CI:扫描当前文档层的
旧命名(executor::/<executor/)、旧 CMake 用法、0.6.0 已删除
API 与失效相对链接;历史快照(横幅标记)与docs/archive/豁免。
修复了扫描发现的 8 处真实漂移(README 失效链接、API.md 相对路径、
design/performance 文档旧 API 名等)。
测试与基准
- 新增
tests/test_scheduling_contract_v061.cpp(独立验证代理编写):
结构化决策/指标/反馈断言、set_scheduler 时序与所有权、shutdown
竞争、高并发 route()、deadline 边界与同时 deadline EDF 稳定性、
capability 缺失退化、旧式拒绝归一化。 - 新增
tests/benchmark_scheduling_paths.cpp:submit_auto 裸/全
spec/feedback 包装、EDF 堆操作、DefaultScheduler route 纯策略 vs
能力快照路径、能力快照采集的调度路径基线。
kairo v0.6.0
[0.6.0] - 2026-10-03
0.6.0 是破坏性变更窗口,包含三部分:项目更名(Executor → kairo)、历史
兼容层全面清理、以及 0.6.0 的核心主题 Scheduling Runtime——调度器与
执行器解耦,并建立统一的 deadline / QoS / affinity / resource 任务调度
模型。设计文档:docs/design/scheduling_runtime.md;迁移指南:
docs/MIGRATION.md 0.6.0 节。
项目更名(Executor → kairo)
项目边界已超出"执行器"单一概念,更名为 kairo;executor 保留为领域概念
(执行后端类名 Executor、ThreadPoolExecutor 等不变,挂于
kairo:: 命名空间):
- 命名空间
executor::→kairo::;include 路径<executor/...>→
<kairo/...>(目录include/kairo/)。 - CMake:
find_package(kairo)、targetkairo::kairo、产物libkairo、
选项/宏EXECUTOR_*→KAIRO_*。 - 打包
libkairo(deb/prefab/Windows zip)、CI artifact/release 命名、
README/website/skill 品牌同步;项目图标更换为docs/kairo.png。
兼容层清理(breaking)
历史版本为迁移期保留的弱 API 全部移除,可诊断的 Result 版本接管主名:
- 7 对 facade API:
initialize_ex → initialize(ExecutorResult)、
wait_for_completion_ex → wait_for_completion(WaitResult)、
register/start_realtime_task_ex、register/start_blocking_io_worker_ex、
register_gpu_executor_ex全部去后缀;旧 bool/void 版本删除。 IRealtimeExecutor::push_task()从 void 改为返回 ExecutorResult
(0.2.2 P-001 的 ABI 兼容约束解除);push_task_ex()删除。- 定时器字符串 ID 体系删除:
submit_delayed返回TimerSubmission、
submit_periodic返回TimerHandle、cancel_task(task_id)由
TimerHandle::cancel()取代;_with_handle拼写随之消失。句柄版取消
后记录保留为 Cancelled 终态(is_running=false,仍可查询),二次取消
返回AlreadyCancelled。 - 4 参 legacy
submit_auto、commis_lock_free()别名、
RealtimeExecutorStatus::memory_locked兼容字段删除。 - 保留:
StopToken/JThread平台兼容层、submit_with_handle/
submit_after_with_handle(TaskHandle 任务图族)。
Scheduling Runtime(核心)
- IScheduler 解耦:路由/准入决策从 facade 内联代码移入可注入的
IScheduler(Executor::set_scheduler()),默认实现DefaultScheduler
组合意图路由(TaskRouter)与调度模型约束。调度器只产出决策,投递仍经
既有后端协议执行;热路径不变式(admission 先于 future、queued 诊断
先于 enqueue、CR-106 惰性能力采集、PA-2 驻停代次唤醒)不回退。 - deadline 模型:
TaskBuilder::deadline()从纯诊断升级为真实调度
输入——同优先级内 EDF 排序;提交时已过期明确拒绝;开始执行时已错过
记录FailureKind::DeadlineMissed(deadline_missed_count),契约
保持"取消是请求不是中断",错过的任务仍执行。 - QoS 模型:
QosClass{BestEffort, Standard, Interactive, Critical}
在未显式设置 priority 时映射默认排队优先级;QoS 定位为排队优先级
preset,不提供抢占、延迟界或实时性保证(确定性周期使用
RealtimeQueue 意图 + 专用实时线程);严格优先级无 aging 的 CR-024
契约文档化(BestEffort 可被饿死,防饿死在应用层拆分)。 - affinity 模型:per-task advisory 亲和提示,与后端绑核集合不相交时
在路由决策 detail 给出AffinityMismatch警告(不拒绝、不重绑线程)。 - resource 模型:声明式
gpu_device/memory_bytes与能力快照核对,
不满足时以BackendUnavailable/CapacityPressure拒绝而非隐式降级;
ExecutorCapability新增绑核集合与 GPU 设备/内存维度。 - 新增公开头:
<kairo/scheduling.hpp>、<kairo/scheduler.hpp>;测试
test_scheduling_runtime32 项行为用例(EDF 排序、准入/错过、QoS 映射、
affinity 诊断、resource 拒绝矩阵、调度器注入)。
executor v0.5.3
[0.5.3] - 2026-10-02
0.5.3 是稳定性与性能维护版本,公开 API 签名与既有语义保持兼容。主线是
2026-09-30 全量代码评审(docs/CODE_REVIEW_2026-09-30.md)四个阶段的落地:
P0 内存安全/挂死/数据竞争 9 项、P1 功能正确性 24 项、构建/打包 8 项、
热路径性能 10 项;随后定时器线程从 1kHz 轮询改造为事件驱动条件等待
(等待 CPU 降约 34 倍,periodic 抖动改善 10-27 倍)。每项修复均先以独立
复现测试确证再修复,并经独立验证通道复验。
修复与改进
代码评审 Phase 1(9 项 P0:内存安全/挂死/数据竞争,PR #202):
- 单例退出 UAF(CR-001):
~Executor在单例模式下经shutdown(true)
排空默认执行器——在途 tracked 任务此前可触碰静态析构期已销毁的 facade
成员(实测 SEGV)。 - before_publish hook 数据竞争(CR-004):
LockFreeTaskExecutor钩子
字段的普通写被生产者线程无同步读取(TSAN 2 处 data race + 空指针调用
SEGV),改为原子不可变快照指针、trampoline 单次加载。 - 参数绑定异常泄漏注册槽(CR-010/011):注册后绑定参数抛异常会永久
泄漏取消注册表槽位、admission 计数与任务图节点(65536 次失败即耗尽
注册表、任务图无界增长),两条 catch 路径均改为完整终态结算;非默认
构造/不可赋值参数类型与reference_wrapper解包语义经 API 兼容探针
保持不变。 - SerialExecutionContext 生命周期 UAF(CR-012):
submit_on闭包改持
shared_ptr<Shared>(pimpl + detach),上下文先于派发销毁不再使 worker
永久阻塞于已释放互斥量;detached 发布以ExecutorStopping结算。 - monitor 回调抛异常挂死 future(CR-020):任务体启动前 monitor 回调
抛异常导致future::get()永久挂起,execute_task的 catch 对未启动
任务触发on_timeout结算。 - 初始化失败后提交挂死(CR-022):初始化失败/回滚后接受的提交永不
执行(future 挂死),task_timeout_ms锁外读取与initialize()竞争。
三条 submit 路径改锁内检查initialized_,超时配置锁内读取。 - CUDA 启动失败队列滞留(CR-002):
start()中途失败留下未消费任务,
后续stop()在wait_for_completion永久挂起;失败路径以
set_exception排空队列,未启动 worker 时排空谓词直接退出。 - OpenCL 重启泄漏(CR-003):restart 覆盖
context_(每次重启泄漏)
并无界追加queues_;重初始化先回收上一代(存活队列逐一clFinish)
再清理。 - 环检测递归爆栈(CR-052):任务图环检测 DFS 持写锁递归,约 4k 深度
即 SIGSEGV(256KB 栈);改为显式栈迭代 DFS。
代码评审 Phase 2(24 项 P1 功能正确性,PR #203),要点:
- KeepLatest/DropOldest 竞争下丢最新值(CR-040):位移路径有界重试,
2s 观测 20999 次虚假拒绝 → 0。 - worker park 丢唤醒(CR-005):park 改
fetch_or;旧代码可把已入队
任务搁置到下一次 push(秒级 P99 尖刺),修复后稳定。 - GPU 内存池对齐破坏(CR-060):块头部不再破坏 256B 对齐(float4
访问出错)。 - GPU 完成集无界增长(CR-062):+72MB/百万任务 → +0.2MB;
remove_task不再留下可运行的依赖者。 - GPU optimizer 配置数据竞争(CR-063):TSAN 10/10/9 处报告 → 0。
- 其余项覆盖线程池、通信原语、GPU 后端、监控与平台工具,全表见评审
文档 "Phase 2 修复执行记录"。
诊断顺序与 CI 稳定性(PR #204):
- queued 诊断先于 enqueue(NN-12):三条 submit 路径此前在 enqueue +
唤醒后锁外补记record_task_queued,worker 可在补记前取走任务执行,
诊断条目以 Queued 状态在任务已运行时创建,快照in_flight_state_counts
缺 Running 键导致map::atabort(注入窗口 10/10 重现)。现移入
mutex_临界区、enqueue 之前,建立 queued→start→complete 严格顺序,
顺带消除 complete 先于补记时诊断表滞留僵尸 Queued 条目;锁序
pool.mutex_ → monitor.mutex_ 保持单向。 - 测试加固:快照测试改
wait_in_flight_drained()(future-vs-cleanup
竞态,满载排水 p99 3.0ms、26 倍裕量);偷取测试竞争窗口改"批次耗尽即
收尾 + 墙钟预算"。
性能
热路径优化(评审 Phase 4,10 项,PR #206;结论均以同参 Release 多轮
中位数口径测量):
- 路由惰性能力采集(CR-106):策略路径不再锁 5 把注册表,观测写入加
快速开关,无回调时移动入库;submit_autovssubmit中位差距
+19.9% → +11.6%。 - 完成通知等待者门控(CR-108):无等待者时每任务 2 次
notify_all
全部消失。 - 等待轮询通知化(CR-109):
try_wait_for_completion从 10ms 盲轮询
(300s = 3 万次全量扫队列)改为通知驱动谓词等待 + 50ms 兜底分片。 - 提交路径单次分配(CR-110):
submit的 promise+ready 双包装合并
单次堆分配。 - 派发器锁分配消除(CR-112):三处
unique_ptr<shared_lock>改
std::optional,每次 dispatch 免一次堆分配。 - lockfree 队列 hook 快速路径(CR-121)+ 批量便签(CR-122):常态推送
零 shared_ptr 原子读(旧 libstdc++ 走内部锁池);批量路径 thread_local
便签免反复分配。 - GPU 参数缓存 O(1) 侵入式 LRU(CR-151):替换 O(n) 扫描;更新已有
key 不再误逐热点。 - 测量口径更正与不改语义决定(CR-102/CR-135):旧基准为 O2 TU 链 O0
库的混合优化口径,评审"基线 65-70%"系该产物(同参 Release 真实差距约
+20% 内);retention 高水位摊销被精确上界契约测试否决,扫描深度插桩
证明恒为 1,语义不变。
定时器事件驱动改造(PR #207,CR-135 后续):
- 1kHz 轮询 → 条件变量等待:schedule/periodic/reschedule/stop 持锁
bumpschedule_epoch_并 notify,调度线程精确睡到堆顶 deadline(堆空
100ms 兜底上界)。等待 CPU 从恒定 0.7-1.0% 单核降至 0.024%(约 34 倍,
收益主体是能耗)。显式wait_until(system_clock)规避 GCC ≥ 10 的
wait_for(duration)/wait_until(steady_clock)均映射到
pthread_cond_clockwait、gcc-11 libtsan 不拦截(PR101978)的误报缺口;
CI TSAN job(g++-11,即约束工具链)补入test_timer_handle作为权威
门禁。取消语义不变:request_cancel仍不唤醒(stale-entry lazy-deletion
契约)。 - periodic 网格锚定:
next = 上一 deadline + P(错过不追补)取代
now + P——旧锚定把唤醒过冲逐周期累积成漂移,旧 1ms 轮询的网格量化
恰好掩盖了它。periodic 抖动 avg 569-642µs → -47~+55µs(改善 10-27 倍)。
构建与打包(评审 Phase 3,8 项,PR #205)
- 覆盖率插桩真正生效(CR-080):库插桩改
executor_apply_coverage_to_target()
函数式显式调用(旧版 include 期if(TARGET executor)恒假,库从未产出
覆盖数据、报告静默失真);插桩库的消费方经 INTERFACE 链接选项继承
--coverage,独立测试目标不再缺 gcov 运行时。 - 版本单一来源(CR-085):6 个打包脚本默认值改从
project(VERSION)
提取;新增生成的executor/version.hpp(构建树 BUILD_INTERFACE 与
install 双路可达)。 - Sanitizer 配置治理(CR-083):Sanitizers.cmake 无条件 include;TSAN
独立于EXECUTOR_ENABLE_SANITIZERS总开关(CI Release+TSAN job 路径
保留);ASAN/TSAN 显式同开在配置期 FATAL_ERROR。 - 安装树完整性(CR-084):
executor/util/纳入安装;GPU 后端头 6 处
源码树相对包含(安装树必断链)改<executor/...>;新增
install_headers_smokectest(临时 prefix 安装 + 全部已安装头探针编译)。 - Windows/共享库守卫(CR-081/082/086):共享库守卫扩到
MSVC OR (WIN32 AND NOT MINGW)(覆盖 clang 工具链);package_windows.ps1
撤销多余Split-Path(包内文档静默缺失);build_windows.ps1 开关透传
(旧版硬编码 OFF 无视入参)。 - ODR 违例结构性消除(NN-01):ThreadPool 测试钩子无条件参与类布局,
EXECUTOR_THREAD_POOL_TEST_HOOKS不再影响布局——混合宏 TU ↔ 库的
ASAN stack-buffer-overflow 根因消除。
文档
- 新增
docs/CODE_REVIEW_2026-09-30.md:全量代码评审与四阶段修复执行
记录——每项缺陷的复现证据、修复方案与复验结论;含三项评审前提被测试
推翻(CR-051/CR-104/CR-102)与一项被测量口径更正(CR-106)的记录。
executor v0.5.2
[0.5.2] - 2026-09-28
0.5.2 以 dependency-driven scheduling 为主线:submit_after 的依赖等待从
"任务立即入队、wrapper 在 worker 上等待条件变量"演进为调度侧唤醒——依赖
未就绪的任务驻留任务图节点、不占用 worker,依赖终态定向级联出队;补全
parked 超时(提交即起算)与 shutdown 终局结算语义,退役 task_graph_cv_
及其惊群唤醒,新增监控 Queued 补记与诊断接口。既有公开提交 API 兼容;
闭包墓地诊断接口 closure_graveyard_size() 为唯一新增公开方法。
新增
- dependency-driven scheduling 第三阶段(PR-3,v0.5.2 主线收口,设计见
docs/design/dependency_driven_scheduling.md):task_graph_cv_退役:依赖图任务运行时不再有任何依赖检查与
条件变量等待(PR-1 起 parked 任务仅在依赖全部成功后入队,终态不可逆),
4 处notify_all惊群唤醒全部删除——每 terminal 唤醒从 O(等待者)
降为 O(1) 定向入队。- 监控 Queued 补记:parked 任务出队入执行器时补记
Queued
生命周期,观测链完整为 DependencyBlocked → Queued → Running。 - closure 墓地观测与终局清空:新增
closure_graveyard_size()
诊断接口;shutdown 终局清空墓地释放常驻引用。 - PA-6 验收基准:新增
tests/benchmark_task_graph_paths
(tracked 提交吞吐 1/2/4/8 生产者、parked fan-out 释放延迟、依赖链
每跳成本、墓地规模);PA-6 数据回填 performance_audit 台账,
"分桶锁"备选确认不再需要。
- dependency-driven scheduling 第二阶段(PR-2,v0.5.2 主线,设计见
docs/design/dependency_driven_scheduling.md):- D1 parked 超时:queued soft timeout 自提交时刻起算,parked 期间
经 facade 一次性定时器(时长取ExecutorConfig::task_timeout_ms,
0 = 不启用维持既有行为)触发,与池队列计时器经 phase CAS 仲裁恰好
一个赢家;parked 获胜即失败结算并级联下游。定时器线程按需启动
(全新 facade 无需先提交 delayed/periodic 预热);输家/赢家闭包的
promise/state 捕获转入 facade 墓地延迟析构,消除定时器线程与消费者
使用异常对象之间的析构竞争(TSAN 实证);record_task_timeout
先于自身 future 结算(统计可见性与级联顺序同一不变式)。 - D2 shutdown 终局结算:shutdown 返回前对全部仍 parked(依赖永不
就绪)的节点统一失败结算,future 不悬空、admission/registry/in-flight
全部释放;serial 派发被池丢弃时 TicketGuard 同步补图终态,parked
下游即时级联。 - serial dispatch 结算顺序对齐:submit_on 全部终态路径 drain bag 化
(on_timeout/成功/协作取消/失败/context 拒绝),失败统计先于级联
写入——与 tracked 路径同一观测不变式。 - retention 交互与 admission 四路径(依赖失败/超时/取消/shutdown)
恰好一次释放的验收测试。
- D1 parked 超时:queued soft timeout 自提交时刻起算,parked 期间
- dependency-driven scheduling 第一阶段(PR-1,v0.5.2 主线,设计见
docs/design/dependency_driven_scheduling.md):submit_after/
submit_after_with_handle从"任务立即入队、wrapper 在 worker 上等
条件变量"演进为"依赖未就绪不入队"——parked 载荷驻留任务图节点
(提交时定格 wrapper/priority/执行器快照),依赖终态经
resolve_task_graph_dependents_locked级联:全部成功按原 priority
调度侧出队,任一失败即时结算依赖异常(任务不占 worker)。
worker 占用与宽依赖饿死/挂死窗口消除(新增免饿死回归测试,旧实现
在该场景挂死);unmet_count驱动定向出队,替代对全部等待者的
notify_all惊群(条件变量本体按计划 PR-3 退役)。
修复与改进
- facade 析构与孤池 worker 的 UAF 闭环(既有窗口,PR-1 时序使其暴露):
stop(false)将池交给 detached 终结线程后,manager 撤下句柄,后续
shutdown(true)(含~Executor路径)此前会完全跳过等待,孤池 worker
收尾(failure 面板/monitor/registry 写入)可与 facade/manager 析构并发
(TSAN 实证 heap-use-after-free)。现改为 retired 保活 + 终局排空:
executor 退休池存入retired_pools_、manager 停机执行器存入
retired_async_executors_,任何shutdown(true)先等退休池 worker 全部
join 再放行析构;stop(false)立即返回契约不变。 - 失败统计先于依赖级联:tracked 任务异常路径中
record_task_exception
提前到级联结算之前——dependent future 就绪时失败面板计数保证可见
(满载下 8/20 观测窗口,修复后 0/40)。
文档
- 待办账实清理(v0.5.x 阶段 21 第一项):对
docs/todolists/15 份计划文档
逐项审计核实(约 326 个未勾项 → 186,且剩余均为真遗留、显式门控(⏸)或
可重跑模板)。要点:主清单阶段 20 P1/P2 回填勾选(随 0.5.0 合入)并新增
阶段 21(dependency-driven scheduling,承接 performance_audit PA-6 的
调度侧唤醒深化);lockfree_queue_optimization §6.2/§6.3 三处失实勾选勘误;
gpu_todolist 约 70 项回填勾选,§3.5 "pinned memory / optimizer" 两处已勾项
经审计证伪加勘误注记(对应 PA-30/PA-31);android/client/mira 三份反馈计划
约 26 项漏勾回填、已决待决项回填,外部门控项(big.LITTLE 真机、heyaki
M6/M7、Mira 回填)显式标注;发布前人工核对项迁入docs/RELEASE_CHECKLIST.md;
android 两项已定决策回写docs/design/android_port.md待决项;修复
website/.vitepress/config.mjs中英导航版本标签滞后(v0.4.0 → v0.5.0)。
修复与改进
- #194 benchmark_thread_pool_hotpath harness 数据竞争修复:Phase 2 延迟采样的
任务闭包原先并发push_back同一 per-producerstd::vector(同一 producer 的
任务可被任意 worker 执行),TSAN 构建下确定性报 data race 并因 vector 内部状态
损坏挂死(30s ctest 超时,重跑仍不终止)。现改为每样本一个预分配槽位,由
(producer, sample index) 唯一寻址:任务闭包只写自己独占的槽,采样路径零共享
容器写入;槽位在shutdown(true)join 全部 worker 后单线程读取。修复后 TSAN
构建对该 benchmark 0 warning;Phase 1 吞吐压测的插桩减速(~20x,实测 220-276s)
通过 TSAN 构建下单独放宽 ctest 超时到 600s 收敛(库代码无涉)。 - #187 残余窗口封口(批量预留误取消):v0.5.0 的倒序预留 + BatchWriting
逃逸把误取消窗口缩到极窄,但在 2-vCPU CI runner 的 gcc-11 Release TSAN 下,
写入循环中段仍可被 scan-ahead 消费者在生产者线程被抢占期间按 64-yield 预算
误判停滞(test_batch_integration间歇失败)。消费者侧取消预算现按认领批量
规模缩放(reservation_wait_yields_ × min(claimed, 1024),claimed 即
enqueue_pos_单次 CAS 认领的槽数):健康批量生产者不再可能被误杀;真停滞
恢复延迟按批量线性、有界(最坏 64×1024 次 yield,亚秒级),停滞契约测试
(小批量 + hook 阻塞)不受影响。
executor v0.5.0
[0.5.0] - 2026-09-13
0.5.0 以任务生命周期语义与跨平台落地为主线:facade 新增任务级协作取消与可取消、
可重排的定时句柄,串行执行上下文与总量有界 admission 转正;Android 适配一期完成
CPU-only 交叉编译与 ARM64 验证;2026-09 性能审查的 P1(线程池提交热路径)与
P2(无锁组件兑现)两阶段重构合入,提交吞吐与 RT jitter 显著改善;停机/生命周期
竞态(P-001~P-008)与 TSAN 可见的数据竞争面收敛。既有主要公开调用方式保持兼容;
ExecutorSnapshot schema 2 → 3(纯新增字段)。
任务协作取消与定时句柄(客户端反馈台账 P1-2/P1-3 收敛,设计见
docs/design/task_cancellation_and_timers.md):facade 新增任务级协作取消与可取消、
可重排的定时句柄;取消是协作请求而非抢占,取消计数进入独立生命周期字段而非
failure 体系。
串行执行上下文与总量有界 admission(Mira 台账 EXE-20260830-001/002/003 收敛,设计见
docs/design/serial_execution_context.md、docs/design/bounded_admission.md):
submit_on/submit_on_with_handle 的 facade wrapper 重构为非阻塞共享状态;
max_in_flight_tasks 为默认异步提交提供跨 scheduler 与本地队列的总量上限。
新增
- 任务级协作取消(C1):新增
include/executor/task_cancellation.hpp
(TaskCancelled/TaskCancellationReason/TaskCancellationResponse/
CancellationStatus)。submit_cancellable/submit_cancellable_priority/
submit_cancellable_after把StopToken注入为 callable 首参数;
request_task_cancel(const TaskHandle&)提供排队取消与运行中协作请求,
幂等且不写 failure 事件;submit_with_handle/submit_after_with_handle
天然获得排队取消能力;取消 registry 有界(默认 65536,
set_cancellation_registry_capacity()可调),容量耗尽明确拒绝。 - 定时句柄(T1):新增
include/executor/timer.hpp(TimerHandle/
ScopedTimerHandle/TimerStatus/TimerOperationResult)。
submit_delayed_with_handle/submit_delayed_cancellable_with_handle/
submit_periodic_with_handle/submit_periodic_cancellable_with_handle
提供取消、重排与状态查询;内部定时器改为 registry + generation heap,
变更 1ms 内可见的 steady 时钟分片等待(5ms 延迟任务的平均到期误差从约 5.5ms
降至约 0.9ms;不用 condition_variable 定时等待,规避 gcc-11 libtsan 对
pthread_cond_clockwait 未拦截导致的 double-lock 误报),
stale entry 有界压缩;终态 record 只保留有界元数据。 - 定时器互操作指南(S1):新增
docs/external_event_loop_interop.md与可编译
示例examples/event_loop_interop.cpp(托管事件循环、strand 延续盲区纪律、
PhaseGate 批次收尾);中英文网站同步上线指南页。 - 监控扩展:
ExecutorSnapshotschema 2 → 3,新增cancellation
(CancellationStatus)与timers(TimerStatusSummary)独立字段与快照文本行;
Executor::get_cancellation_status()/get_timer_status_summary()查询入口。 - 教程与测试:新增教程
examples/tutorial/13_cancellation_and_timers.cpp、
tests/test_task_cancellation.cpp、tests/test_timer_handle.cpp、文档一致性测试
tests/test_api_doc_cancellation_fields.cpp,以及整库
EXECUTOR_STOP_TOKEN_FORCE_FALLBACK强制实例化的
tests/test_task_cancellation_fallback.cpp。 - comm 指引(G1 轻量项):中英文"如何选择通信组件"指南新增
"什么时候允许裸回调"一节,明确裸std::function回调的适用边界。 - 串行执行上下文(S2):新增
include/executor/serial_execution_context.hpp
(SerialExecutionContext,post/reserve/post_reserved/abandon/shutdown,
FIFO ticket 语义)。Executor::submit_on/submit_on_with_handle在其上提供
严格按提交顺序结算的std::future<T>/TimerSubmission<T>;facade wrapper 为
非阻塞共享状态实现(派发/结算分离),多 worker 下不再互相饥饿(两 worker ×
10,000 突发约 1s 内全部结算),外部事件循环互操作见
docs/external_event_loop_interop.md。 - 总量有界 admission(A1):
ExecutorConfig::max_in_flight_tasks(默认0=
不启用、零热路径开销)为 facade 默认异步提交(普通 / priority / tracked /
cancellable / batch /submit_on*)提供总在途上限;达到上限时提交不抛出,
future 立即以CapacityExhaustedException就绪,FailureKind::CapacityExhausted
事件与capacity_exhausted_count计数可观察;运行期set_max_in_flight_tasks()/
get_in_flight_submissions()/get_max_in_flight_tasks()可调可查。
性能
- 无锁组件兑现与 RT 优先级反转消除(性能审查 PA-5/7/8,2026-09 收敛计划
阶段 P2):ObjectPool改 tagged Treiber 索引 freelist((tag:32 | index:32)单字 head,ABA 由 tag 封闭;消费者release_bulk整链单 CAS
splice;双重释放检测改为 per-node state CAS,语义不变)——
LockFreeTaskExecutor提交路径与 RT 线程逐任务release不再共享互斥锁,
RT 路径优先级反转面消除;LockFreeQueue消费侧 MPMC 化(前沿连续
Published run 单 CAS 认领),LockFreeWorkerQueue的 pop/steal/size 去
consume_mx_(steal 与 pop 同为 FIFO 最老端,恰好一次交付),size()
改无锁近似值;LockFree worker 空闲从 1µs-sleep 永久轮询(约 10⁶
syscall/s/核)改为「PAUSE → yield → 10µs-sleep 缓冲带 → futex 驻停」,
驻停编码进 32 位wake_seq_(bit0=驻停位 + 唤醒计数,生产者 push 后
无条件fetch_add(2)、返回值带驻停位才notify_one,忙碌路径零
syscall),空闲 executor 进程 CPU 实测 0.0ms/500ms。实现期修复两个
深挖出的并发陷阱(条件唤醒标志被 StoreLoad 重排打穿致挂死;CAS 循环
带陈旧期望值重试致偶发线程饿死 20 秒+)。基准(同机同条件 3 次取中位):
mpsc 吞吐 1P +86%、8P +289%、16P +482%、32P +399%;RT 执行器提交延迟
-21%;RT 1ms 周期 jitter p50 78.7→16.8µs;已知取舍:2-4 生产者 mpsc
吞吐 -23%~-24%(Treiber 单链低生产者数下的缓存行往返,详见计划文档
P2 小节归因实验与后续条目)。新增test_object_pool_lockfree_stress
(多生产者锤击 + RT 延迟分布 + 空闲 CPU 守护 + 驻停唤醒守护)。设计
推导与基准全表见
docs/todolists/performance_audit_2026-09_plan.md阶段 P2 小节。 - 线程池提交热路径重构(性能审查 PA-1/2/3/4、PA-9/13/17,2026-09 收敛计划
阶段 P1):worker 空闲驻停从「全局mutex_+condition_重谓词(谓词内做
steal/dequeue,含堆分配与排序)」改为 32 位驻停代次计数 + C++20
std::atomic::wait(Linux futex 直达);提交路径单任务notify_one+
worker 接力唤醒(并行度指数恢复,惊群消除),批次notify_all;Task 全链路
(enqueue → dequeue → dispatch → 本地队列 → pop)改unique_ptr所有权/字段级
移动,消除逐跳 std::function/string/vector 复制;dispatch_batch消除每次
派发的 4-6 次堆分配(成员便签 + 计数排序分段);local_queues_去除
libstdc++atomic_load(shared_ptr*)库级自旋锁(改为读写锁保护下的裸指针
快照);steal victim 选择无分配化(LoadBalancer::highest_load_victim);
should_exit原子空集快速路径。停机正确性同步加固:worker 的 stop_ 退出加
「退出守门」(持 dispatcher 锁复核代次),排除任务处于搬运途中被永久滞留的
窗口。基准(14 核桌面,gcc 13 Release,3 次取中位):单生产者提交吞吐
125.5k → 565.4k tasks/s(4.5x),e2e 3.5x,多生产者(2-32 线程)2.2-4.7x
且扩展曲线平坦化,直连 ThreadPool 的单生产者吞吐 13.5x、唤醒 p99(4T+)
3-5x 改善。新增benchmark_thread_pool_hotpath(多生产者争用吞吐 +
wake-to-exec 延迟分布)。设计说明(32 位 futex 前置条件、代次采样时机、
接力唤醒与退出守门的推导)见
docs/todolists/performance_audit_2026-09_plan.md阶段 P1 小节。
修复与改进
- P-001/P-002(停机竞态):
LockFreeTaskExecutor与RealtimeThreadExecutor
以单原子准入门闩消除停机与提交交错的生命周期竞态(PR #180);worker 线程内
自停止语义与stop_and_join()返回值契约同步澄清。 - P-003(LockFree 池容量):对象池按取整后的环容量统一分配——请求容量 5
(环取整为 8)时可用槽位 7,池与push_tasks_batch上限一致,非 2 的幂配置
不再让failed_pushes/queue_full_rejections失真。 - P-004(进程内存锁租约):
util::ProcessMemoryLockLease引用计数管理
mlockall/munlockall——行为变化:最后一个持有租约的实时执行器停止时
才解除进程锁;与进程内其他mlockall使用方共存更安全。 - P-008(Windows 处理器组):
cpu_affinity支持超过 64 逻辑 CPU 的
处理器组编号(g*64+序号),跨组配置明确拒绝(PR #181)。 - TSAN 收尾(issue #185–#188):
LockFreeQueue::push_batch_exact的批量预留
会被消费者"停滞生产者恢复"启发式误取消(TSAN 构建下空环确定性失败)——预留改
倒序使前沿槽可取消窗口缩至 O(1),cancel_reservation增加 BatchWriting 逃逸,
停滞恢复契约保持不变;~TaskMonitor析构先取mutex_再成员析构,与最后一个
持锁读者建立 happens-before(消除 shutdown/析构路径 TSAN 报告与潜在 UAF);
test_lockfree_mpsc测试自身同步域修复;benchmark 测试RUN_SERIAL+
sanitizer 构建下延迟断言豁免;TSAN CI 子集补test_lockfree_mpsc/
test_batch_integration/test_executor_manager。 - P-006/P-007(可观察性):
ThreadPool::get_status()空闲线程数饱和语义
与 resizer 竞态修复;GPUvalidate_memory_range拒绝外部缓冲区,无锁队列
size()/empty()近似语义钉住回归测试。 - 测试与 CI:admission/serial 独立测试 NDEBUG 安全化;慢 CI runner 上
计数与 tick 轮询有界化;forced-fallback 目标从全源码清单构建。
变更
- shutdown 清理未到期 delayed 任务:future 异常由
std::runtime_error("Timer stopped...")+SubmitRejected事件改为
TaskCancelled(Shutdown),不再记录 failure 事件;可观察性转移到定时计数。 ExecutorSnapshot::schema_version2 → 3(纯新增字段);解析快照文本的下游
工具需按新 schema 更新(迁移说明见docs/MIGRATION.md)。
Android 适配一期
Android 适配一期:核心库可在 NDK 工具链下以 CPU-only 配置交叉编译为静态库/共享库,
并纳入官方模拟器与真实 ARM64 runner 的验证流程。Android 上的线程优先级、CPU 亲和性、
mlockall 与 timer slack 均保持 best-effort,不承诺硬实时;CUDA/OpenCL 不进入一期。
新增
- Android CPU-only 构建支持:新增
if(ANDROID)CMake 平台分支,bionic 下不再错误
链接librt,也不导出libatomic;Android 构建默认关闭 GPU/CUDA,用户仍可显式覆盖。 - 便携 StopToken/JThread 兼容层:新增
include/executor/stop_token.hpp。桌面平台
executor::StopToken是std::stop_token别名,保持既有 override 源码与 ABI 兼容;
Android libc++ 未启用 jthread 时使用自有StopSource/StopToken/detail::JThread。 - Android 线程与 affinity 默认值:bionic 下使用
sched_setaffinity/
sched_getaffinity;默认线程池上限为 4,自动 affinity 来自 cgroup 允许 cpuset;
短周期实时线程不再自动申请SCHED_FIFO。 - Android 构建与设备脚本:新增
scripts/build_android.sh、
scripts/run_android_tests.sh、scripts/capture_android_device_info.sh,以及
tests/android_smoke.cpp等无 GTest standalone 测试。 - Android CI:新增 NDK r26c / r28b 交叉编译 workflow;新增手动触发的
arm64-concurrencyworkflow,覆盖 4 核、单核 pinned、ASan/UBSan 和可配置 MPSC soak。 - Android 打包与平台文档:新增
docs/PACKAGE_ANDROID.md,覆盖 NDK CMake、AGP、
c++_shared打包、JNI shutdown 生命周期与 Prefab/AAR 模板;中英文网站首页、构建页
与平台部署核对页同步补充 Android CPU-only 能力边界。
修复与改进
- 修复
test_multithread_mpsc在慢速 ARM64 模拟环境下消费者过早退出导致误报的测试逻辑。 - Android 下实时调优路径统一为 best-effort:priority / affinity / mlock / timer slack
失败只写入状态字段,不改变任务接受结果。 - 为 Android 平台裁剪 NDK clang 不支持的 warning 选项,并守卫仅适用于 desktop Linux
的/proc测试。 - 修复 P-260816-001:
ExecutorManager::shutdown()不再在持有
default_async_mutex_时执行默认执行器的阻塞排空(stop(wait_for_tasks)/
wait_for_completion()含 worker join)。此前池内任务在排空期间再入
submit()/ 状态查询等持锁读路径会与 shutdown 互相等待形成自死锁;现在改为
锁内置闩并快照执行器、锁外排空,置闩后读路径立即走拒绝分支,与 ThreadPool
自身"先停止接收新任务,再等待已接受任务完成"的关停顺序对齐。并发 shutdown
调用者通过新增的条件变量等待排空完成,保持"第二个调用者等第一个排空结束后
才返回"的旧语义。新增回归测试tests/test_shutdown_drain_reentrancy.cpp
(旧实现在该测试下确定性死锁)。 - 修复 P-260816-002(H1):
Executor定时器线程启停竞态。旧实现先原子置位
timer_running_再创建线程并给timer_thread_赋值,并发shutdown会在成员尚未
赋值时读取它(数据竞争 UB)并跳过 join;随后赋值出的 joinable 线程成员在析构时触发
std::terminate,竞态窗口内提交的延迟任务 future 永久悬挂。现在:timer_thread_/
timer_state_/ 测试工厂由timer_thread_mutex_保护,赋值完成后才置位运行标志;
每代线程持有独立的停止标志,停止只对本代置位(join 期间并发重启不会复活旧线程,
join 必定返回);join 在锁外执行。submit_delayed在入队临界区内检查停止位,
消除"入队后无人处理"的悬挂 future;set_timer_thread_factory_for_test同步化。
新增回归测试tests/test_timer_thread_lifecycle_race.cpp(旧实现下延迟任务
future 永久悬挂 /std::terminate,测试确定性命中)。
验证
- 官方 Android 模拟器(API 30 x86_64,KVM):6/6 standalone 测试通过。
- qemu-user + NDK bionic 静态 ARM64:6/6 测试通过。
- GitHub ARM64 runner(Neoverse-N2,4 核):6/6、单核 pinned、ASan/UBSan、600 秒
MPSC soak 均通过;结果见docs/performance/android_a3_validation.md。 - big.LITTLE Android 真机验证已登记为发布前 gate,正式版本不得在未完成该项时宣称
已在 big.LITTLE 设备验证。 - P-260816-001 修复验证:树内 Debug 构建 105/105 ctest 通过(除 benchmark 标签外);
关停/生命周期相关测试(test_shutdown_drain_reentrancy、`test_c...
v0.4.0
[0.4.0] - 2026-08-13
0.4.0 聚焦通信与并发执行路径的确定性边界:核心通信组件采用构造期固定存储和原子同步,新增进程内 Topic 扇出、LET 阶段通信、实时分配诊断及延迟分位数观测;任务图句柄保留和线程池真实扩缩容也获得明确的容量与并发语义。既有主要公开调用方式保持兼容,但“同步无锁”仅描述组件内部原子与固定存储,完整实时性仍须由调用方在目标环境验证。
新增
- 进程内 Topic / Subscription:新增
comm::Topic<T>与 move-only RAIITopicSubscription<T>,将订阅后的事件扇出到每个订阅者的独立有界 FIFO;发布结果报告匹配、成功和拒绝订阅数,逐订阅者保留独立 drop policy、统计、回调和关闭唤醒语义。该原语明确不提供网络传输、重放、可靠确认或硬实时保证。 - LET 阶段通信契约:
PhaseGate、DoubleBuffer与LatestMailbox新增可选的 phase-bound LET 模式。绑定后,发布仅发生在当前相位,读取仅暴露上一完成相位的数据;相位切换会拒绝活跃读写,避免跨周期读取或写入。 - 实时内存分配诊断:新增
comm::RealtimeAllocationGuard、RealtimeAllocationViolationPolicy和线程局部统计,可记录受保护实时路径中的分配次数、字节数、组件与阶段;Linux 构建可通过EXECUTOR_ENABLE_REALTIME_ALLOCATION_GUARD启用,RealtimeThreadConfig::enable_allocation_guard控制周期回调的 opt-in 诊断。 - 通信延迟分位数:
CommStats增加固定大小延迟直方图及近似p50_latency、p99_latency,同时保留累计、平均和最大延迟统计。 - 有界任务图句柄保留:
ExecutorConfig::task_graph_retention_capacity和对应运行时设置 API 控制终态TaskHandle的保留上限。被淘汰的句柄会明确拒绝为过期;仍被活跃依赖链引用的节点不会提前淘汰。 - 线程池真实扩缩容:
ThreadPool::resize()与ThreadPoolResizer现创建或移除真实 worker,且仅接受初始化配置的线程数范围;缩容前迁移本地队列任务并 join 被移除 worker,返回时状态稳定。
修复与改进
- 通信同步核心无锁化:
MpscChannel/RealtimeChannel改为构造期预分配的有界 MPSC 节点池,
LatestMailbox/ 未绑定DoubleBuffer改为固定 reader-pin 快照槽,PhaseGate/Sequencer
改为原子状态核心;新增同步原子 lock-free 查询与构造期平台校验。该保证不覆盖 payload、callback、
时钟、缺页或 OS 调度,Topicfan-out 仍属于 mutex 与动态分配支持的非实时控制面。 - 线程池扩缩容并发安全:本地 worker 队列改以原子发布的
shared_ptr快照访问,调度、窃取与 resize 通过读写锁协调,避免队列替换期间的悬空访问和 UAF;shutdown 与 resize 的 join 路径也已串行化。 - 任务调度边界:移除
TaskDispatcher的旧引用构造路径;空本地队列快照不会从调度器取走任务或发生越界访问。 - 实时契约实现边界:LET 绑定要求固定双缓冲容量和不抛异常的复制语义;每个相位只允许一次发布,缺失上一相位数据或相位转换中读取会返回明确的通信错误。
- 兼容性:调整 C++20 实现以兼容 GCC 10(项目仍建议使用 GCC 11 或更高版本)。
文档与测试
- 更新中英文 README、API、通信设计文档、教程站点与 sitemap,补充 LET 状态/相位、通信选择、延迟观测和失败可观测性示例说明。
- 新增 Topic fan-out/独立背压/并发生命周期、通信实时内存、LET
PhaseGate、邮箱与双缓冲、任务图保留/过期语义的测试;扩展线程池扩缩容、调度 fallback 与并发 UAF 回归测试,并约束扩缩容压力用例的工作负载。 - 新增面向使用者的
executor-integration渐进式接入指南,以及面向维护者的能力索引与维护参考。