fix(scheduler): release replay-event payloads after the simulator pushes them (bug-1884, part 2)

sim_process_replay_event_message() now hands the decoded replay event to
the caller, which keeps it beside the translated core event and frees it
after xce_core_push_events() with driver.c's release_translated_payload()
rules: a pushed config is kept by the core, and a rusages report is kept
by the job it found. An untranslatable event is freed at once, and events
after the last session are freed at the end. The payloads were an
"accepted leak" per event; exit-time leak on the reproduction replay
75,495 -> 25,807 bytes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-09-29 08:55:34 +00:00
parent 880dc51007
commit c89e4e4520
Signed by untrusted user: rshen
GPG key ID: 80533536B0EB651C
4 changed files with 101 additions and 23 deletions

View file

@ -571,6 +571,7 @@ test_sim_process_replay_event_jobs_push_wires_real_task_count_into_resreq_primar
struct capn c;
capn_ptr root;
xce_core_event_t translated_ev;
replay_event_t translated_decoded;
int record_rc = 0;
int translated;
xce_sched_job_t* sjob;
@ -631,7 +632,9 @@ test_sim_process_replay_event_jobs_push_wires_real_task_count_into_resreq_primar
* not a mirror of it. record_rc is always 0 here: sim.record_file is
* NULL for this whole fixture (no --sim-output involved). ────────── */
translated = sim_process_replay_event_message(&sim, &c, root,
&translated_ev, &record_rc);
&translated_ev,
&translated_decoded,
&record_rc);
fclose(f);
TEST_ASSERT_EQUAL_INT(0, record_rc);
@ -693,6 +696,8 @@ test_sim_process_replay_event_jobs_push_wires_real_task_count_into_resreq_primar
"a hand-built mirror of it, must have carried the job's real "
"maxTasks through to the dispatched standalone primary");
free_ReplayEvent(&translated_decoded);
printf("test_sim_process_replay_event_jobs_push_wires_real_task_count_"
"into_resreq_primary: PASS\n");
}

View file

@ -757,15 +757,18 @@ static void test_events_earlier_than_start_snapshot_set_exact(void)
struct capn c;
capn_ptr root;
xce_core_event_t ev;
replay_event_t decoded;
int record_rc = 0;
TEST_ASSERT_EQUAL_INT(0, capn_init_fp(&c, start_sim.replay_file, 0));
TEST_ASSERT_TRUE(msg_root_has_shape(&c, &root, ReplayEvent_word_count,
ReplayEvent_pointer_count));
TEST_ASSERT_TRUE(sim_process_replay_event_message(&start_sim, &c, root,
&ev, &record_rc)
&ev, &decoded,
&record_rc)
>= 0);
TEST_ASSERT_EQUAL_INT(0, record_rc);
free_ReplayEvent(&decoded);
usleep(WAIT_US / 5);
TEST_ASSERT_EQUAL_UINT64_MESSAGE(ev_ts[i],
xce_core_now(&(start_sim.core)),

View file

@ -720,6 +720,7 @@ test_process_replay_event_advances_virtual_clock_to_exact_event_ts_in_file_order
struct capn c;
capn_ptr root;
xce_core_event_t ev;
replay_event_t decoded;
int record_rc = 0;
int translated;
@ -731,8 +732,8 @@ test_process_replay_event_advances_virtual_clock_to_exact_event_ts_in_file_order
* (sim_loop.c) -- always 0 here, sim.record_file is NULL for this
* whole fixture (no --sim-output involved in this task's own
* Observable). */
translated
= sim_process_replay_event_message(&sim, &c, root, &ev, &record_rc);
translated = sim_process_replay_event_message(&sim, &c, root, &ev,
&decoded, &record_rc);
TEST_ASSERT_EQUAL_INT(0, record_rc);
TEST_ASSERT_EQUAL_INT(1, translated);
@ -745,6 +746,7 @@ test_process_replay_event_advances_virtual_clock_to_exact_event_ts_in_file_order
* (see this file's own header comment for why a picker-hook spy
* cannot see per-event granularity). */
TEST_ASSERT_EQUAL_UINT64(ts_values[i], xce_core_now(&(sim.core)));
free_ReplayEvent(&decoded);
}
fclose(f);