refactor(scheduler-sim-decision-trace): split trace sources under the 800-line cap

Task 2.4: outcome capture moves to sched_trace_outcome.c and the
position/host/summary/rollback half of the model to sched_trace_scan.c;
shared helpers go behind sched_trace_internal.h (sti_ prefix). Code is
moved unchanged; every target that compiles the trace sources gets all
four, and the core isolation scan covers the new files.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-10-08 10:16:46 +00:00
parent eacb1fa599
commit 144a01982e
Signed by untrusted user: rshen
GPG key ID: 80533536B0EB651C
40 changed files with 1355 additions and 1094 deletions

View file

@ -64,11 +64,13 @@
* sidesteps that entirely by checking *usage*, not *visibility*).
*
* Decision trace sources (scheduler-sim-decision-trace spec, task 1.3,
* design.md "Invariant Cross-Check" dimension 2): sched_trace.c (record
* model) and sched_trace_capture.c (capture helpers) run on the allocator
* design.md "Invariant Cross-Check" dimension 2): sched_trace.c and
* sched_trace_scan.c (record model), sched_trace_capture.c and
* sched_trace_outcome.c (capture helpers) and their shared
* sched_trace_internal.h (split in task 2.4) run on the allocator
* thread inside the core's allocation chain, so they join layer 1's
* forbidden-headers and forbidden-symbols scans, plus a check that applies
* to these two files only: no stdio, no file I/O and no logging (a trace
* to these trace files only: no stdio, no file I/O and no logging (a trace
* record is pure data; only the simulator REPL renders or writes it). They
* are NOT part of layer 2: sched_core_isolation_lib covers the four core
* state-machine files, and the capture file references scheduler symbols
@ -117,6 +119,18 @@
#error \
"XCE_SCHED_TRACE_CAPTURE_C_PATH must be defined by meson.build to sched_trace_capture.c's absolute path"
#endif
#ifndef XCE_SCHED_TRACE_SCAN_C_PATH
#error \
"XCE_SCHED_TRACE_SCAN_C_PATH must be defined by meson.build to sched_trace_scan.c's absolute path"
#endif
#ifndef XCE_SCHED_TRACE_OUTCOME_C_PATH
#error \
"XCE_SCHED_TRACE_OUTCOME_C_PATH must be defined by meson.build to sched_trace_outcome.c's absolute path"
#endif
#ifndef XCE_SCHED_TRACE_INTERNAL_H_PATH
#error \
"XCE_SCHED_TRACE_INTERNAL_H_PATH must be defined by meson.build to sched_trace_internal.h's absolute path"
#endif
#ifndef XCE_CORE_LIB_PATH
#error \
"XCE_CORE_LIB_PATH must be defined by meson.build to the absolute path of core.c's isolated static_library() archive"
@ -217,6 +231,9 @@ static void test_core_source_paths_are_readable(void)
char* cc = read_whole_file(XCE_CORE_CLOCK_C_PATH);
char* st = read_whole_file(XCE_SCHED_TRACE_C_PATH);
char* sc = read_whole_file(XCE_SCHED_TRACE_CAPTURE_C_PATH);
char* ss = read_whole_file(XCE_SCHED_TRACE_SCAN_C_PATH);
char* so = read_whole_file(XCE_SCHED_TRACE_OUTCOME_C_PATH);
char* si = read_whole_file(XCE_SCHED_TRACE_INTERNAL_H_PATH);
TEST_ASSERT_NOT_NULL_MESSAGE(h, XCE_CORE_H_PATH);
TEST_ASSERT_NOT_NULL_MESSAGE(c, XCE_CORE_C_PATH);
@ -225,6 +242,9 @@ static void test_core_source_paths_are_readable(void)
TEST_ASSERT_NOT_NULL_MESSAGE(cc, XCE_CORE_CLOCK_C_PATH);
TEST_ASSERT_NOT_NULL_MESSAGE(st, XCE_SCHED_TRACE_C_PATH);
TEST_ASSERT_NOT_NULL_MESSAGE(sc, XCE_SCHED_TRACE_CAPTURE_C_PATH);
TEST_ASSERT_NOT_NULL_MESSAGE(ss, XCE_SCHED_TRACE_SCAN_C_PATH);
TEST_ASSERT_NOT_NULL_MESSAGE(so, XCE_SCHED_TRACE_OUTCOME_C_PATH);
TEST_ASSERT_NOT_NULL_MESSAGE(si, XCE_SCHED_TRACE_INTERNAL_H_PATH);
free(h);
free(c);
@ -233,6 +253,9 @@ static void test_core_source_paths_are_readable(void)
free(cc);
free(st);
free(sc);
free(ss);
free(so);
free(si);
}
/* Scans one file's text for every FORBIDDEN_INCLUDES entry, tagging each
@ -261,6 +284,9 @@ static void test_core_never_includes_forbidden_headers(void)
char* cc = read_whole_file(XCE_CORE_CLOCK_C_PATH);
char* st = read_whole_file(XCE_SCHED_TRACE_C_PATH);
char* sc = read_whole_file(XCE_SCHED_TRACE_CAPTURE_C_PATH);
char* ss = read_whole_file(XCE_SCHED_TRACE_SCAN_C_PATH);
char* so = read_whole_file(XCE_SCHED_TRACE_OUTCOME_C_PATH);
char* si = read_whole_file(XCE_SCHED_TRACE_INTERNAL_H_PATH);
TEST_ASSERT_NOT_NULL(h);
TEST_ASSERT_NOT_NULL(c);
@ -269,6 +295,9 @@ static void test_core_never_includes_forbidden_headers(void)
TEST_ASSERT_NOT_NULL(cc);
TEST_ASSERT_NOT_NULL(st);
TEST_ASSERT_NOT_NULL(sc);
TEST_ASSERT_NOT_NULL(ss);
TEST_ASSERT_NOT_NULL(so);
TEST_ASSERT_NOT_NULL(si);
assert_no_forbidden_includes(h, "core.h");
assert_no_forbidden_includes(c, "core.c");
@ -277,6 +306,9 @@ static void test_core_never_includes_forbidden_headers(void)
assert_no_forbidden_includes(cc, "core_clock.c");
assert_no_forbidden_includes(st, "sched_trace.c");
assert_no_forbidden_includes(sc, "sched_trace_capture.c");
assert_no_forbidden_includes(ss, "sched_trace_scan.c");
assert_no_forbidden_includes(so, "sched_trace_outcome.c");
assert_no_forbidden_includes(si, "sched_trace_internal.h");
free(h);
free(c);
@ -285,6 +317,9 @@ static void test_core_never_includes_forbidden_headers(void)
free(cc);
free(st);
free(sc);
free(ss);
free(so);
free(si);
}
/* Shared by test_core_never_calls_forbidden_symbols() -- see
@ -313,6 +348,9 @@ static void test_core_never_calls_forbidden_symbols(void)
char* cc = read_whole_file(XCE_CORE_CLOCK_C_PATH);
char* st = read_whole_file(XCE_SCHED_TRACE_C_PATH);
char* sc = read_whole_file(XCE_SCHED_TRACE_CAPTURE_C_PATH);
char* ss = read_whole_file(XCE_SCHED_TRACE_SCAN_C_PATH);
char* so = read_whole_file(XCE_SCHED_TRACE_OUTCOME_C_PATH);
char* si = read_whole_file(XCE_SCHED_TRACE_INTERNAL_H_PATH);
TEST_ASSERT_NOT_NULL(h);
TEST_ASSERT_NOT_NULL(c);
@ -321,6 +359,9 @@ static void test_core_never_calls_forbidden_symbols(void)
TEST_ASSERT_NOT_NULL(cc);
TEST_ASSERT_NOT_NULL(st);
TEST_ASSERT_NOT_NULL(sc);
TEST_ASSERT_NOT_NULL(ss);
TEST_ASSERT_NOT_NULL(so);
TEST_ASSERT_NOT_NULL(si);
assert_no_forbidden_symbols(h, "core.h");
assert_no_forbidden_symbols(c, "core.c");
@ -329,6 +370,9 @@ static void test_core_never_calls_forbidden_symbols(void)
assert_no_forbidden_symbols(cc, "core_clock.c");
assert_no_forbidden_symbols(st, "sched_trace.c");
assert_no_forbidden_symbols(sc, "sched_trace_capture.c");
assert_no_forbidden_symbols(ss, "sched_trace_scan.c");
assert_no_forbidden_symbols(so, "sched_trace_outcome.c");
assert_no_forbidden_symbols(si, "sched_trace_internal.h");
free(h);
free(c);
@ -337,6 +381,9 @@ static void test_core_never_calls_forbidden_symbols(void)
free(cc);
free(st);
free(sc);
free(ss);
free(so);
free(si);
}
/* core_clock.c is deliberately NOT scanned here -- it is the one
@ -386,8 +433,9 @@ static void test_core_never_calls_wallclock_functions(void)
/*
* No stdio, no file I/O, no logging in the decision trace sources
* (scheduler-sim-decision-trace design.md, TraceModel / TraceCapture: "No
* I/O and no tlog"). Applies to sched_trace.c and sched_trace_capture.c
* only.
* I/O and no tlog"). Applies to the trace sources only: sched_trace.c,
* sched_trace_scan.c, sched_trace_capture.c, sched_trace_outcome.c and
* sched_trace_internal.h.
*
* Comments, string literals and character literals are blanked before the
* scan, so prose such as "never calls fopen" in a comment is not a hit.
@ -650,15 +698,27 @@ static void test_trace_sources_do_no_stdio_or_file_io(void)
{
char* st = read_whole_file(XCE_SCHED_TRACE_C_PATH);
char* sc = read_whole_file(XCE_SCHED_TRACE_CAPTURE_C_PATH);
char* ss = read_whole_file(XCE_SCHED_TRACE_SCAN_C_PATH);
char* so = read_whole_file(XCE_SCHED_TRACE_OUTCOME_C_PATH);
char* si = read_whole_file(XCE_SCHED_TRACE_INTERNAL_H_PATH);
TEST_ASSERT_NOT_NULL(st);
TEST_ASSERT_NOT_NULL(sc);
TEST_ASSERT_NOT_NULL(ss);
TEST_ASSERT_NOT_NULL(so);
TEST_ASSERT_NOT_NULL(si);
assert_trace_source_has_no_io(st, "sched_trace.c");
assert_trace_source_has_no_io(sc, "sched_trace_capture.c");
assert_trace_source_has_no_io(ss, "sched_trace_scan.c");
assert_trace_source_has_no_io(so, "sched_trace_outcome.c");
assert_trace_source_has_no_io(si, "sched_trace_internal.h");
free(st);
free(sc);
free(ss);
free(so);
free(si);
}
/*