feat(scheduler-allocation): wire unsatisfiable-resreq cache into dispatch

Wrap sched_make_primary_alloc_() -- the single choke point all three
primary-resreq shapes (standalone, compound-nested, alter-nested via
compound delegation) already funnel through -- with a cache lookup
before allocation and a cache insert on exhaustion. On a hit, pend the
job immediately via the same make_pendreason()/add_job_preason() path
every exhaustion case already uses, without invoking either allocator
(Req 7.3, 7.4, 7.5).

A nested primary has no real per-primary schedobj, so
sched_primary_cache_obj_() synthesizes one on the stack per dispatch for
cache-key purposes; verified memory-safe since alloc_cache.c's
build_key_() copies the fingerprint/identity by value synchronously
before the stack frame unwinds.

Log bug-1768 (compound/alter-nested primaries never get real slot/rusage
availability checks -- seqjob/parjob's prepare_allocation hooks no-op
whenever ctx->schedobj->tag != XCE_RESREQ_PRIMARY) and bug-1769
(sched_make_alter_allocation() type-confuses xce_compound_schedobj_t*
as xce_sched_obj_t*, a ~112-byte heap over-read, currently untested).
Both are pre-existing and out of this feature's scope; discovered and
confirmed while building this task's dispatch tests.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XYdtrEWWZfKRRGED7raEYg
This commit is contained in:
Rongsong Shen 2026-09-04 23:27:56 +00:00
parent 9d23060b76
commit 5c022d0b4f
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
6 changed files with 1015 additions and 5 deletions

View file

@ -1439,6 +1439,58 @@ sched_snapshot_load_allocator_regression_test = executable(
'-Wl,--wrap=xcecli_join'],
install: false)
# scheduler-allocation spec, task 5.1 (Req 7.3, 7.4, 7.5): wiring the
# unsatisfiable-resreq cache around sched_make_primary_alloc_() (`static`
# to scheduler.c). Same real-scheduler_srcs link technique as
# sched_snapshot_load_allocator_regression_test above (see this test
# file's own header comment for the full rationale). In addition to the
# usual xcecli_start/xcecli_join doubles, this file also wraps
# sched_meet_host_selection (resource.c, exported) to count real calls --
# the decisive "did the real allocator run" signal a cache HIT and a
# genuine exhausted attempt cannot otherwise be told apart by (both pend,
# and Req 7.5 requires them to report the SAME reason category).
scheduler_cache_dispatch_test_srcs = ['test_scheduler_cache_dispatch.c']
foreach f : scheduler_srcs
if f != 'src/main.c'
scheduler_cache_dispatch_test_srcs += ['../' + f]
endif
endforeach
sched_cache_dispatch_test = executable(
'sched_cache_dispatch_test',
scheduler_cache_dispatch_test_srcs,
include_directories:[incdir],
dependencies: [scheduler_deps, unity_dep],
link_args: ['-Wl,--wrap=xcecli_start',
'-Wl,--wrap=xcecli_join',
'-Wl,--wrap=sched_meet_host_selection'],
install: false)
# Companion to sched_cache_dispatch_test above: the primary-nested-inside-
# a-COMPOUND half of the same task 5.1 proof, kept in its own binary/
# process -- calling sched_init() twice in one process is not safe here
# (plugins/fcfs.c's legacy job_elect_fn path carries process-global state;
# a real run with both tests in one binary crashed with a genuine SEGV in
# fcfs_del_job() the first time this was tried -- see this test file's own
# header comment).
scheduler_cache_dispatch_compound_test_srcs = [
'test_scheduler_cache_dispatch_compound.c']
foreach f : scheduler_srcs
if f != 'src/main.c'
scheduler_cache_dispatch_compound_test_srcs += ['../' + f]
endif
endforeach
sched_cache_dispatch_compound_test = executable(
'sched_cache_dispatch_compound_test',
scheduler_cache_dispatch_compound_test_srcs,
include_directories:[incdir],
dependencies: [scheduler_deps, unity_dep],
link_args: ['-Wl,--wrap=xcecli_start',
'-Wl,--wrap=xcecli_join',
'-Wl,--wrap=sched_meet_host_selection'],
install: false)
# White-box regression test for bug-1685 (double-free/heap-corruption
# SIGABRT in limit_update_config() on a duplicate limit-name config
# update). It #includes ../src/plugins/limit.c directly (same white-box
@ -1780,3 +1832,9 @@ test('scheduler seqjob rewrap equivalence test',
test('scheduler parjob combinatorial test',
sched_parjob_combinatorial_test, suite: 'scheduler',
env: ['ASAN_OPTIONS=detect_leaks=0'])
test('scheduler cache dispatch test',
sched_cache_dispatch_test, suite: 'scheduler',
env: ['ASAN_OPTIONS=detect_leaks=0'])
test('scheduler cache dispatch compound test',
sched_cache_dispatch_compound_test, suite: 'scheduler',
env: ['ASAN_OPTIONS=detect_leaks=0'])