Skip to content

fix: release a thread's hazard slot instead of freeing it #3720

fix: release a thread's hazard slot instead of freeing it

fix: release a thread's hazard slot instead of freeing it #3720

Workflow file for this run

name: ci
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
# the default job timeout is six hours. twice in one day a run wedged
# with zero output inside the memcheck step's apt-get preamble (a
# mirror stall), and each time it sat until someone noticed — the run
# for #811 burned four hours. a wedged run should fail in minutes.
timeout-minutes: 90
steps:
- uses: actions/checkout@v4
- name: build
run: cargo build --release
- name: check rust crash guards
run: make check-no-panics
- name: rust unit tests
run: cargo test --release --workspace --locked
- name: cycle gc world-stop tests
run: make test-cycle-gc
- name: test
run: |
./target/release/pith run tests/cases/test_suite.pith
./target/release/pith run tests/cases/test_process_command.pith
./target/release/pith run tests/cases/test_http_request_bytes.pith
- name: run examples (native smoke)
run: |
./target/release/pith run examples/hello.pith >/dev/null
./target/release/pith run examples/collection_methods.pith >/dev/null
./target/release/pith run examples/string_collection_methods.pith >/dev/null
./target/release/pith run examples/stdlib_algo.pith >/dev/null
- name: green-thread runtime tests
run: make green-tests
- name: regression corpus under green
run: make verify-green-corpus-only
# the runner is linux, so every other step above already runs green by
# default. this is the only step that exercises the PITH_GREEN=0 opt-out
# across the corpus.
- name: regression corpus under os threads
run: make verify-osthread-corpus-only
# the memcheck step below runs with valgrind's leak check off, because
# the runtime's freelists and pools are still reachable at exit and
# would bury a real signal. this covers leaks instead, by measuring
# growth across two round counts.
- name: leak growth
run: make leak-check-only
- name: build self-hosted compiler
run: make self-host
- name: run examples (self-hosted)
run: make run-examples-self
- name: native parity examples
run: make parity-examples-only
- name: sitegen golden check
run: make sitegen-check
- name: lsp golden check
run: make lsp-check-only
- name: logscan golden check
run: make logscan-check
- name: apic golden check
run: make apic-check
- name: parq golden check
run: make parq-check
- name: protogen golden check
run: make protogen-check
- name: docsite golden check
run: make docsite-check
- name: gzip interop check
run: make gzip-interop-check
- name: zstd interop check
run: make zstd-interop-check
- name: pure-pith zstd decoder interop
run: make zstd-pure-check
- name: pure-pith zstd encoder interop
run: make zstd-encode-check
- name: tls live interop (openssl)
run: make tls-live-interop
- name: tls interop (go crypto/tls)
run: make tls-go-interop
- name: tls interop (rustls)
run: make tls-rustls-interop
- name: fuzz check
run: make fuzz-check
- name: pithgen check
run: make pithgen-check
- name: memcheck
# generous triple of the step's normal time (apt ~1min + the
# curated suite ~8min): the observed wedges were apt-mirror stalls
# that produced no output at all, so a hard cap converts hours of
# silence into a fast, visible failure.
timeout-minutes: 30
run: |
# not `|| true`: `make memcheck` skips itself when valgrind is
# missing, so a swallowed install failure would turn this step into a
# guard that passes without running.
#
# install valgrind with a hard wall-clock bound and a retry. the
# Acquire::*::Timeout options only bound an HTTP read, but the stalls
# seen in practice hung before that layer (dns, the dpkg lock, sudo
# itself) and sat until the step timeout with zero output. wrapping
# each apt call in `timeout` fails fast wherever it wedges, and a
# second attempt after a short sleep clears a transiently bad mirror.
install_valgrind() {
timeout 240 sudo apt-get -o Acquire::Retries=3 -o Acquire::http::Timeout=30 -o Acquire::https::Timeout=30 update -qq \
&& timeout 240 sudo apt-get -o Acquire::Retries=3 -o Acquire::http::Timeout=30 -o Acquire::https::Timeout=30 install -y -qq valgrind
}
install_valgrind || { echo "apt install stalled or failed; retrying once after 15s"; sleep 15; install_valgrind; }
make memcheck
- name: verify a fresh clone can bootstrap from the seed
run: make smoke-bootstrap-seed
- name: verify the tracked seed matches the emitter source
run: make check-bootstrap-seed
- name: verify bootstrap fixed point
run: make bootstrap-verify
- name: lint
run: |
# std/ is in here because its public api IS the documentation —
# docsite generates from it, so a naming slip there ships to
# readers rather than staying an internal wart.
#
# lint now fails on a WARNING, not only on a hard error. a file
# that declares itself generated in its leading comment block is
# skipped, since generated code mirrors the naming of whatever
# produced it and is not ours to rename.
#
# tools/docsite/sample is golden-test INPUT rather than source:
# docsite renders that tree and the output is diffed, so the
# fixture deliberately contains an undocumented public function
# to pin how an undocumented item renders. documenting it would
# delete the case it exists to cover. a marker comment is no
# good either — the file's leading `##` block IS the module doc
# the golden captures.
for f in $(find examples self-host std tools -name '*.pith' \
-not -path 'tools/docsite/sample/*' | sort); do
./self-host/pith_main lint "$f"
if [ $? -ne 0 ]; then
echo "FAIL lint $f"
exit 1
fi
done
- name: check examples (self-hosted)
run: |
for f in $(find examples -name '*.pith' | sort); do
result=$(./self-host/pith_main check "$f" 2>&1)
if [ "$result" != "ok" ]; then
echo "FAIL $f (self-hosted check)"
echo "$result"
exit 1
fi
echo "ok $f"
done
- name: check pith formatting
run: |
# std/ nests to std/net/http2, deeper than a `std/**/*.pith` glob
# reaches without globstar, so the file list comes from find.
for f in $(find self-host std tools bench -name '*.pith' | sort); do
./self-host/pith_main fmt --check "$f"
if [ $? -ne 0 ]; then
echo "FAIL $f not formatted"
exit 1
fi
done
- name: check doc coverage
run: |
# std/ nests to std/net/http2, deeper than a `std/**/*.pith` glob
# reaches without globstar, so the file list comes from find.
#
# self-host/ joined this gate once its pub items were documented.
# note the gate and lint's E304 cover DIFFERENT things and neither
# subsumes the other: this walks top-level items including structs,
# E304 also walks impl methods. a file can pass here and still warn.
for f in $(find self-host std -name '*.pith' | sort); do
./self-host/pith_main doc --check "$f"
if [ $? -ne 0 ]; then
echo "FAIL $f missing doc comments"
exit 1
fi
done