. "$BST_LIB" # jemalloc 5.3.0+git (630434bb, meta-oe recipes-devtools) -- a general-purpose # scalable concurrent malloc, ported here as a STATIC library plus its own # upstream unit suite, which OpenEmbedded packages as a ptest. # # WHAT THIS FILE ASSERTS, AND WHAT IT DELIBERATELY DOES NOT RUN. # The port's acceptance gate is upstream's own suite: 99 unit programs under # /usr/lib/jemalloc/ptest/tests/unit, each a self-contained binary that links the # whole allocator and prints its own "--- pass: N/M, skip: X/M, fail: Y/M ---". # The whole suite CANNOT be run by default here: it wedges the guest permanently # at the `fork` test (brintos/hardwarejs#17 -- a forked child traps with SIGILL, # leaks a coroutine park slot, and after enough occurrences exec itself stops # working and vmlinux can no longer be instantiated). That is not a hang this # file can bound with a timeout, because the damage outlives the process: a run # that reaches it takes the MACHINE down, not just the suite. So the wedge is # asserted directly as a red, and the full run is one environment variable away: # # BST_JEMALLOC_PTEST=1 BST_SUITE_TIMEOUT=9000 brintos-selftest 78-jemalloc.test # # WHAT RUNS INSTEAD IS STILL UPSTREAM'S SUITE, not a probe we wrote: four of its # own unit programs, chosen because each is CONF-INDEPENDENT (no sibling .sh, so # brintos/hardwarejs#16 below cannot perturb them) and because between them they # cover the allocator proper (a0), the bit/size arithmetic every size-class # decision rides on (bit_util), the hash used for arena selection (hash), and the # red-black tree the extent maps are built from (rb). Four spawns is a deliberate # budget: exec here is a fresh wasm module instantiation of a ~7.4 MB binary, not # a fork, so each one costs seconds. # # THE ORACLE IS A NATIVE x86_64 CONTROL of the identical SRCREV, built with the # identical configure flags (--enable-xmalloc --disable-shared --disable-cxx # --with-lg-quantum=4) and driven through the identical run-ptest. It reported # pass 77 / skip 22 / fail 0 across the 99 programs, and 756 PASS / 165 SKIP / # 0 FAIL at assertion granularity. Every expectation below was read off that run. # Its value is that it makes a target red CLASSIFIABLE rather than arguable: the # 22 skips follow from the configure flags, which are the same on both sides, so # a difference is this arm's and nothing else's. ptestdir=/usr/lib/jemalloc/ptest unitdir=$ptestdir/tests/unit # ----------------------------------------------------------------- payload --- # check_rc with `test` is an ash builtin and forks nothing, unlike check/check_out # whose command substitution does. On a spawn-budgeted arm that difference is the # whole reason the presence half of this file is free. check_rc jemalloc/lib-static 0 test -f /usr/lib/libjemalloc.a check_rc jemalloc/lib-pic 0 test -f /usr/lib/libjemalloc_pic.a check_rc jemalloc/header 0 test -f /usr/include/jemalloc/jemalloc.h check_rc jemalloc/pkgconfig 0 test -f /usr/lib/pkgconfig/jemalloc.pc check_rc jemalloc/bin-config 0 test -x /usr/bin/jemalloc-config check_rc jemalloc/bin-sh 0 test -x /usr/bin/jemalloc.sh check_rc jemalloc/bin-jeprof 0 test -f /usr/bin/jeprof check_rc jemalloc/ptest-runptest 0 test -x "$ptestdir/run-ptest" check_rc jemalloc/ptest-unitdir 0 test -d "$unitdir" # No libjemalloc.so on a distro that configures --disable-shared image-wide; a # .so appearing here would mean the static-only rule silently stopped holding. if [ -e /usr/lib/libjemalloc.so ] || [ -e /usr/lib/libjemalloc.so.2 ]; then bst_notok jemalloc/static-only "a shared libjemalloc shipped on a --disable-shared distro" else bst_ok jemalloc/static-only fi # The suite must be COMPLETE, not merely present: 99 unit programs is what this # SRCREV builds, and a short count means do_install_ptest silently dropped some. # `-ge` rather than `-eq` because a previous run leaves a tests.log beside them. nunit=$(ls "$unitdir" 2>/dev/null | grep -vE '\.(sh|log)$' | wc -l) if [ "$nunit" -ge 99 ]; then bst_ok jemalloc/ptest-unit-count else bst_notok jemalloc/ptest-unit-count "expected >= 99 unit programs, found $nunit" fi # ------------------------------------------------- upstream's own unit suite --- # Each prints its own tally; "fail: 0/" in that line AND exit 0 is the pass. # These four are the port's positive evidence: upstream's code, upstream's # assertions, run on this arm. if [ -d "$unitdir" ]; then for t in a0 bit_util hash rb; do if [ -x "$unitdir/$t" ]; then check_out "jemalloc/unit-$t" "fail: 0/" "$unitdir/$t" else bst_notok "jemalloc/unit-$t" "upstream unit program $t not installed" fi done else for t in a0 bit_util hash rb; do bst_notok "jemalloc/unit-$t" "no ptest unit directory on the image" done fi # ------------------------------------------------------- the attributed reds --- # BRINTOS-WORKAROUND: hardwarejs#17 remove -- when the fork defect closes, delete # this branch and the BST_JEMALLOC_PTEST gate: the full suite becomes the default # and this case turns into its verdict. if [ -n "${BST_JEMALLOC_PTEST:-}" ]; then # The real thing, on the operator's explicit request. ptest-runner is the # harness the ticket closes on; -t is set high because it does not bound # anything on this arm anyway (brintos/linux#48, relative timers do not fire), # so a tight value would be an assertion about nothing. if [ -x /usr/bin/ptest-runner ]; then out=$(/usr/bin/ptest-runner -t 20000 jemalloc 2>&1) nfail=$(printf '%s\n' "$out" | grep -c '^FAIL: ' || true) if [ "$nfail" -eq 0 ]; then bst_ok jemalloc/ptest-suite else bst_notok jemalloc/ptest-suite "$nfail FAIL lines under ptest-runner" fi else bst_notok jemalloc/ptest-suite "BST_JEMALLOC_PTEST set but no ptest-runner on the image" fi else bst_notok jemalloc/ptest-suite \ "upstream suite not run by default: it wedges the guest at the fork test (46 of 99 programs never run, and exec stops working machine-wide) -- brintos/hardwarejs#17; set BST_JEMALLOC_PTEST=1 to run it" fi # BRINTOS-WORKAROUND: hardwarejs#16 remove -- MALLOC_CONF is read by every # jemalloc consumer; when getenv() works at init this becomes an ordinary case. # Present-but-broken, so `not ok` and not a skip. Asserted WITHOUT a spawn: the # defect is already reduced and filed, and re-measuring it costs a 7 MB exec. bst_notok jemalloc/conf-from-env \ "MALLOC_CONF is ignored: getenv() returns NULL to jemalloc's init although env(1) shows it set, so tcache_max/bin_shards/narenas cannot be tuned (the same conf via /etc/malloc.conf works) -- brintos/hardwarejs#16" # The two upstream unit programs whose subject IS a MALLOC_CONF setting. They are # not independently broken -- they are hardwarejs#16 seen twice -- so they name it # rather than standing as separate defects. bst_skip jemalloc/unit-arena_decay \ "needs tcache_max:1024 from MALLOC_CONF; unapplied, allocations stay in tcache and the decay ticker never ticks -- brintos/hardwarejs#16" bst_skip jemalloc/unit-binshard \ "needs bin_shards:... from MALLOC_CONF; unapplied, nshards stays at the default 1 -- brintos/hardwarejs#16" # ------------------------------------------------------ structurally absent --- # Not reductions of scope by choice: upstream's integration and stress link rules # name lib/libjemalloc.$(IMPORTLIB) -- the DSO -- unconditionally, with no # `ifeq ($(enable_shared), 1)` guard, so they cannot be built on a static-only # distro at all. The hwjs link is a whole-program bitcode merge and wasmld refuses # a -shared side-module link outright, so this is not a knob we declined to turn. bst_skip jemalloc/suite-integration \ "not built: upstream's integration link rule requires the shared library, which a --disable-shared, whole-program-bitcode arm cannot produce" bst_skip jemalloc/suite-stress \ "not built: same DSO prerequisite as the integration suite" # BRINTOS-WORKAROUND: hwjs-cc#10 revisit -- flip to a real case when C++ lands. bst_skip jemalloc/cxx-operator-new \ "src/jemalloc_cpp.cpp dropped (--disable-cxx): CXX for a target recipe is the C driver with no C++ include path, and the file needs -- brintos/hwjs-cc#10"