iter embedding-abi-m2.1 (PARTIAL 4/9 + Boss spec-defect repair): ctx ABI + de-globalisation
Tasks 1-4 land fully review-green and are the cohesive shippable
subset (the per-thread embedding ABI, fully wired + proven):
- T1: FIXED-FIRST alloc-guard baseline pin (RED captured -> GREEN at T4).
- T2: runtime/rc.c gains ailang_ctx_t {alloc_count,free_count} +
ailang_ctx_new/_free + __thread __ail_tls_ctx; the two increment
sites become 'if (_ctx) _ctx->... else g_rc_...'. g_rc_* statics +
ailang_rc_stats_atexit + the constructor RETAINED VERBATIM as the
null-ctx (single-threaded executable) fallback. rc_accounting_tsan.c
+ driver: per-ctx 8x200000 tsan-clean (de-globalisation positive proof).
- T3: codegen Target::StaticLib forwarder gains a leading 'ptr %ctx'
+ one '@__ail_tls_ctx = external thread_local global ptr' decl +
TLS save/store/restore around the BYTE-UNCHANGED internal call;
_adapter/_clos + internal arg vector untouched (M1 decision held);
doc-comment provisionality narrowed to the value/record layout.
- T4: build_staticlib rejects --alloc != rc (RC-only swarm artefact).
Boss adjudication of the orchestrator's Task-5 BLOCKED (spec-defect,
correctly surfaced not hacked): swarm.c's -DSHARED_CTX negative
control is structurally impossible — examples/embed_backtest_step.ail
is a non-allocating scalar kernel that never writes a ctx field, and
__ail_tls_ctx is __thread, so a shared-ctx scalar swarm has no
shared-memory write to race on (the spec's OWN item-1 honesty point).
The de-globalisation teeth belong to the item-1 rc_accounting harness
(shared ctx genuinely races on ctx->alloc_count; orchestrator
independently confirmed tsan exit 66). Spec amended in lockstep
(Goal coherent-stop, must-fail-axis item 2, Testing item 3,
Acceptance) so item 3's negative control is item-1's by the
de-globalisation-proof / capability-demo split; plan Task 5
restructured (swarm.c per-ctx capability demo only; negative-control
standing test relocated into the item-1 harness driver) + Task 3's
plan-transcription error (@ail_backtest_step ->
@ail_embed_backtest_step_step) corrected. This is a Boss
consistency-repair of an internally-contradictory clause whose intent
is already correctly realised in the same spec — not a redesign; no
brainstorm bounce. Task-5 working files discarded (corrected plan
reproduces them; a structurally-RED test must not enter main).
INDEX.md + final journal land at iter completion (re-dispatch [5,9]).
This commit is contained in:
@@ -171,7 +171,11 @@ pub enum Target {
|
||||
/// `--emit=staticlib`: suppress the `@main` trampoline AND the
|
||||
/// `MissingEntryMain` shape-check (a kernel module is a library);
|
||||
/// emit one external C entrypoint per `(export …)` fn forwarding
|
||||
/// to `@ail_<module>_<fn>`. Provisional signature until M3.
|
||||
/// to the internal `@ail_<module>_<def>`. M2: the entrypoint takes
|
||||
/// a mandatory leading `ptr %ctx` (per-thread embedding context)
|
||||
/// published via `@__ail_tls_ctx` around the unchanged internal
|
||||
/// call. The ctx-threaded C signature is the M2 shape; only the
|
||||
/// value/record layout remains provisional until M3.
|
||||
StaticLib,
|
||||
}
|
||||
|
||||
@@ -606,6 +610,11 @@ fn lower_workspace_inner(ws: &Workspace, alloc: AllocStrategy, target: Target) -
|
||||
// the internal callee takes the scalars positionally
|
||||
// (confirmed against `emit_fn`'s signature emission,
|
||||
// `lib.rs:1087`).
|
||||
// M2: the per-thread embedding ctx slot. Defined by
|
||||
// runtime/rc.c (__thread ailang_ctx_t *__ail_tls_ctx);
|
||||
// the forwarder publishes its explicit ctx param here for
|
||||
// the synchronous duration of the internal call.
|
||||
out.push_str("\n@__ail_tls_ctx = external thread_local global ptr\n");
|
||||
for (mname, m) in &ws.modules {
|
||||
for d in &m.defs {
|
||||
if let Def::Fn(f) = d {
|
||||
@@ -617,17 +626,21 @@ fn lower_workspace_inner(ws: &Workspace, alloc: AllocStrategy, target: Target) -
|
||||
(check-side gate should have rejected it)"))),
|
||||
};
|
||||
let cret = llvm_scalar(&ret_ty);
|
||||
let params: Vec<String> = param_tys.iter().enumerate()
|
||||
.map(|(i, t)| format!("{} %a{i}", llvm_scalar(t)))
|
||||
.collect();
|
||||
let args: Vec<String> = param_tys.iter().enumerate()
|
||||
.map(|(i, t)| format!("{} %a{i}", llvm_scalar(t)))
|
||||
.collect();
|
||||
let mut sig_params = vec!["ptr %ctx".to_string()];
|
||||
sig_params.extend(
|
||||
param_tys.iter().enumerate()
|
||||
.map(|(i, t)| format!("{} %a{i}", llvm_scalar(t))));
|
||||
out.push_str(&format!(
|
||||
"\ndefine {cret} @{sym}({}) {{\n \
|
||||
%saved = load ptr, ptr @__ail_tls_ctx\n \
|
||||
store ptr %ctx, ptr @__ail_tls_ctx\n \
|
||||
%r = call {cret} @ail_{mname}_{}({})\n \
|
||||
store ptr %saved, ptr @__ail_tls_ctx\n \
|
||||
ret {cret} %r\n}}\n",
|
||||
params.join(", "),
|
||||
sig_params.join(", "),
|
||||
f.name,
|
||||
args.join(", "),
|
||||
));
|
||||
|
||||
Reference in New Issue
Block a user