feat(scheduler-allocation): implement parjob's combinatorial plan generation

Add the real xce_alloc_plan_iter_t for parjob: for host-count k=1..maxTasks
(ascending, most-preferred-first), generate one balanced partition of
maxTasks into k buckets (floor/ceil split, remainder to the first rem
buckets), which is descending by construction. Pure function of maxTasks
alone -- never dereferences sched -- with a real pthread_testcancel()
cancellation point and stable post-exhaustion NULL (Req 2.1-2.6, 4.1).

my_alloc()/parjob_prepare_allocation() remain untouched stubs; wiring the
iterator into real allocation is task 4.2.

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 20:04:44 +00:00
parent 9d64ba0d69
commit 6ca717fb86
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
4 changed files with 583 additions and 1 deletions

View file

@ -1559,6 +1559,27 @@ sched_seqjob_rewrap_equivalence_test = executable(
dependencies: [scheduler_test_deps],
install: false)
# Task 4.1 (scheduler-allocation spec, Req 2 AC 1-6, Req 4 AC 1):
# parjob_allocator.c's REAL combinatorial xce_alloc_plan_iter_t
# implementation -- ascending host-count plan order, one balanced
# ceil/floor partition per host-count, descending bucket order within
# each plan, a stable exhaustion signal, and a real pthread_testcancel()
# cancellation point. White-box #include of
# ../src/plugins/parjob_allocator.c itself (the file under test) --
# simpler than sched_seqjob_allocator_test's own white-box stack since
# parjob_allocator.c's still-stubbed my_alloc()/parjob_prepare_allocation()
# bodies (untouched by this task -- task 4.2's job) make no calls into
# core.c/resource.c/schedobj.c/host_iter.c at all, so none of those need
# to be pulled in here. Only my_alloc()/prepare_allocation() themselves
# are never called by this file's tests -- they exercise
# parjob_plan_iter_init()/_next()/_fini() directly.
sched_parjob_combinatorial_test = executable(
'sched_parjob_combinatorial_test',
['test_parjob_combinatorial.c'],
include_directories:[incdir],
dependencies: [scheduler_test_deps],
install: false)
# Register as meson tests so `meson test --suite scheduler` runs them all.
# detect_leaks=0 matches the suite convention (fixtures are not torn down).
test('scheduler test', scheduler_test, suite: 'scheduler',
@ -1756,3 +1777,6 @@ test('scheduler seqjob allocator test',
test('scheduler seqjob rewrap equivalence test',
sched_seqjob_rewrap_equivalence_test, suite: 'scheduler',
env: ['ASAN_OPTIONS=detect_leaks=0'])
test('scheduler parjob combinatorial test',
sched_parjob_combinatorial_test, suite: 'scheduler',
env: ['ASAN_OPTIONS=detect_leaks=0'])