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:
+35
-2
@@ -86,6 +86,37 @@ static inline ailang_rc_header_t *header_of(void *payload) {
|
||||
static uint64_t g_rc_alloc_count = 0;
|
||||
static uint64_t g_rc_free_count = 0;
|
||||
|
||||
/* M2: per-thread embedding context. A scalar kernel allocates nothing,
|
||||
* so this carries only the de-globalised RC accounting. Set by the
|
||||
* generated C `@<sym>` forwarder into __ail_tls_ctx for the synchronous
|
||||
* duration of one call (never held across a suspension point). The
|
||||
* g_rc_* statics + atexit below are RETAINED as the null-ctx
|
||||
* (single-threaded executable) fallback. */
|
||||
typedef struct ailang_ctx {
|
||||
uint64_t alloc_count;
|
||||
uint64_t free_count;
|
||||
} ailang_ctx_t;
|
||||
|
||||
__thread ailang_ctx_t *__ail_tls_ctx = NULL;
|
||||
|
||||
ailang_ctx_t *ailang_ctx_new(void) {
|
||||
return (ailang_ctx_t *)calloc(1, sizeof(ailang_ctx_t));
|
||||
}
|
||||
|
||||
void ailang_ctx_free(ailang_ctx_t *ctx) {
|
||||
if (ctx != NULL) {
|
||||
const char *flag = getenv("AILANG_RC_STATS");
|
||||
if (flag != NULL && flag[0] != '\0') {
|
||||
fprintf(stderr,
|
||||
"ailang_rc_stats: allocs=%llu frees=%llu live=%lld\n",
|
||||
(unsigned long long)ctx->alloc_count,
|
||||
(unsigned long long)ctx->free_count,
|
||||
(long long)(ctx->alloc_count - ctx->free_count));
|
||||
}
|
||||
}
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static void ailang_rc_stats_atexit(void) {
|
||||
fprintf(stderr,
|
||||
"ailang_rc_stats: allocs=%llu frees=%llu live=%lld\n",
|
||||
@@ -122,7 +153,8 @@ void *ailang_rc_alloc(size_t size) {
|
||||
*hdr = 1;
|
||||
void *payload = (uint8_t *)block + HEADER_SIZE;
|
||||
memset(payload, 0, size);
|
||||
g_rc_alloc_count++;
|
||||
ailang_ctx_t *_ctx = __ail_tls_ctx;
|
||||
if (_ctx != NULL) _ctx->alloc_count++; else g_rc_alloc_count++;
|
||||
return payload;
|
||||
}
|
||||
|
||||
@@ -172,7 +204,8 @@ void ailang_rc_dec(void *payload) {
|
||||
*hdr -= 1;
|
||||
if (*hdr == 0) {
|
||||
free(hdr);
|
||||
g_rc_free_count++;
|
||||
ailang_ctx_t *_ctx = __ail_tls_ctx;
|
||||
if (_ctx != NULL) _ctx->free_count++; else g_rc_free_count++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user