Historical internal name "uncommonlisp" retired in favor of the
public name "lumbda" ahead of lumbda.com going live. Scope of
this commit:
Source files renamed:
uncommonlisp.py -> lumbda.py
asm/uncommonlisp.s -> asm/lumbda.s
c/uncommonlisp.h -> c/lumbda.h
whitepaper/uncommonlisp-whitepaper -> whitepaper/lumbda-whitepaper (.rst + .pdf)
Binaries renamed (tracked ones; c/ was always gitignored):
asm/uncommonlisp, asm/uncommonlisp-gc, asm/uncommonlisp.o,
asm/uncommonlisp-gc.o -> asm/lumbda(-gc)(.o)
c/.gitignore -> ignores lumbda
Internal string updates (sed pass ordered longest-first):
asm/uncommonlisp -> asm/lumbda
c/uncommonlisp -> c/lumbda
uncommonlisp.py -> lumbda.py
UNCOMMONLISP_BIN -> LUMBDA_BIN (asm/test.sh env var)
"uncommonlisp> " -> "lumbda> " (asm REPL prompt baked into binary)
UNCOMMONLISP -> LUMBDA (macros, comments)
uncommonlisp -> lumbda (prose)
Binary portal magic updated:
"ULPORTAL" -> "LUMBDAB1" # "Lumbda Binary v1"
Old portal files are not backward-compatible — this is a deliberate
break since it's the rename moment. S-expression portals already
carry their own ";; lumbda-portal v1" header and remain cleanly
versioned.
WHITEPAPER.pdf / WHITEPAPER.rst symlinks repointed to the renamed
files. Makefile's whitepaper target targets lumbda-whitepaper.pdf.
Not changed (intentional, separate phases):
- Filesystem directory /home/fox/git/uncommonlisp itself
(fox renames locally and the gitlab repo URL in a follow-up)
- tests.py hardcoded cwd=/home/fox/git/uncommonlisp
(matches the current on-disk location; will flip when the
directory rename ships)
- Git history (immutable; old commits still say uncommonlisp,
which is correct — that's what they were)
Verified:
137 asm no-GC + 137 asm GC + 571 Python + 83 C + 189 shared
functional tests all pass under the new names.
bench-gc-http (2000 req): all 4 cells behave as expected
(cells 1/2 flat, 3 leaks, 4 bounded at 1 chunk).
Python REPL, C REPL, asm REPL all start cleanly.
104 lines
4.3 KiB
Bash
Executable file
104 lines
4.3 KiB
Bash
Executable file
#!/bin/bash
|
|
# bench-gc-http.sh — validate the asm naive GC under sustained HTTP
|
|
# load. Starts each server, hits it with N requests, samples peak
|
|
# RSS. Expected: server with GC holds memory flat under the
|
|
# no-arena workload; server without GC leaks monotonically.
|
|
#
|
|
# Four configs compared:
|
|
# 1. asm no-GC + http-server.lsp (bounded via heap-snapshot)
|
|
# 2. asm GC + http-server.lsp (bounded via snapshot + GC backstop)
|
|
# 3. asm no-GC + http-server-noarena.lsp (leaks — baseline failure)
|
|
# 4. asm GC + http-server-noarena.lsp (bounded via GC alone)
|
|
|
|
set -u
|
|
cd "$(dirname "$0")/.."
|
|
|
|
REQUESTS=${REQUESTS:-5000}
|
|
CONCURRENCY=${CONCURRENCY:-8}
|
|
|
|
# Kill stragglers on exit. The noarena + no-GC case can balloon
|
|
# to gigabytes if the test somehow overshoots REQUESTS; ulimit -v
|
|
# on each spawn caps blast radius.
|
|
declare -a SPAWNED=()
|
|
cleanup() {
|
|
local pid
|
|
for pid in "${SPAWNED[@]}"; do kill -9 "$pid" 2>/dev/null; done
|
|
sleep 0.2
|
|
pkill -9 -u "$USER" -f 'examples/http-server' 2>/dev/null || true
|
|
}
|
|
trap cleanup EXIT INT TERM
|
|
|
|
make -s -C asm all
|
|
|
|
printf "\n═══════════════════════════════════════════════════════\n"
|
|
printf "asm GC vs no-GC under sustained HTTP load\n"
|
|
printf " %s requests, concurrency %s, 1 KB body per request\n" "$REQUESTS" "$CONCURRENCY"
|
|
printf "═══════════════════════════════════════════════════════\n"
|
|
|
|
run_case() {
|
|
local label="$1" bin="$2" srv="$3" vcap="$4"
|
|
# Fresh port per case so we don't collide with a lingering socket.
|
|
local pid peak=0 rss time_s=0 t0 t1
|
|
printf "\n── %s ──\n" "$label"
|
|
( ulimit -v "$vcap" && exec "$bin" < "$srv" >/dev/null 2>&1 ) &
|
|
pid=$!
|
|
SPAWNED+=("$pid")
|
|
# Wait for port.
|
|
for _ in $(seq 1 30); do
|
|
if curl -s -o /dev/null -w "%{http_code}" "http://localhost:8080/" 2>/dev/null | grep -q 200; then
|
|
break
|
|
fi
|
|
sleep 0.1
|
|
done
|
|
if ! kill -0 "$pid" 2>/dev/null; then
|
|
echo " SERVER FAILED TO START (ulimit -v $vcap may be too tight)"
|
|
return 1
|
|
fi
|
|
# Baseline RSS
|
|
local rss0
|
|
rss0=$(awk '/^VmRSS:/ {print $2}' /proc/$pid/status 2>/dev/null || echo 0)
|
|
printf " baseline_rss_kb=%s\n" "$rss0"
|
|
# Drive traffic; sample RSS every 200ms.
|
|
t0=$(date +%s.%N)
|
|
( seq 1 "$REQUESTS" | xargs -P "$CONCURRENCY" -I_ \
|
|
curl -s -o /dev/null "http://localhost:8080/bench" ) &
|
|
local curl_pid=$!
|
|
while kill -0 "$curl_pid" 2>/dev/null; do
|
|
if kill -0 "$pid" 2>/dev/null; then
|
|
rss=$(awk '/^VmRSS:/ {print $2}' /proc/$pid/status 2>/dev/null || echo 0)
|
|
[ "$rss" -gt "$peak" ] && peak=$rss
|
|
else
|
|
echo " SERVER DIED MID-RUN (likely OOM at ulimit -v $vcap)"
|
|
kill "$curl_pid" 2>/dev/null
|
|
break
|
|
fi
|
|
sleep 0.2
|
|
done
|
|
wait "$curl_pid" 2>/dev/null || true
|
|
t1=$(date +%s.%N)
|
|
# Final RSS right before we kill the server.
|
|
local final_rss=0
|
|
if kill -0 "$pid" 2>/dev/null; then
|
|
final_rss=$(awk '/^VmRSS:/ {print $2}' /proc/$pid/status 2>/dev/null || echo 0)
|
|
fi
|
|
kill -9 "$pid" 2>/dev/null
|
|
wait "$pid" 2>/dev/null || true
|
|
time_s=$(python3 -c "print(f'{float(\"$t1\")-float(\"$t0\"):.2f}')")
|
|
local rps
|
|
rps=$(python3 -c "print(f'{$REQUESTS / ($time_s if $time_s>0 else 1):.0f}')")
|
|
printf " time_s=%s req/s=%s peak_rss_kb=%s final_rss_kb=%s growth_kb=%s\n" \
|
|
"$time_s" "$rps" "$peak" "$final_rss" "$((final_rss - rss0))"
|
|
}
|
|
|
|
# vcap = ulimit -v in KB. 131072 = 128 MB — enough for one GC chunk
|
|
# and the process; tight enough that a leaker will OOM before the
|
|
# kernel eats all RAM. Widen if the no-GC noarena case needs to run
|
|
# to completion rather than OOM'd.
|
|
VCAP=${VCAP:-524288}
|
|
|
|
run_case "asm no-GC + snapshot loop" "./asm/lumbda" "examples/http-server.lsp" "$VCAP" || true
|
|
run_case "asm GC + snapshot loop" "./asm/lumbda-gc" "examples/http-server.lsp" "$VCAP" || true
|
|
run_case "asm no-GC + no snapshot" "./asm/lumbda" "examples/http-server-noarena.lsp" "$VCAP" || true
|
|
run_case "asm GC + no snapshot" "./asm/lumbda-gc" "examples/http-server-noarena.lsp" "$VCAP" || true
|
|
|
|
printf "\n"
|