Skip to content

Commit b0dcb22

Browse files
committed
fixup! ci: replace workflow set with mimalloc benchmark
Assisted-by: Claude Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent e735769 commit b0dcb22

1 file changed

Lines changed: 46 additions & 25 deletions

File tree

ci/bench-mimalloc.py

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
import time
1818

1919

20-
def robust_rmtree(path, attempts=20, delay=0.5):
20+
def robust_rmtree(path, attempts=60, delay=1.0):
2121
"""`shutil.rmtree` with retries.
2222
2323
Windows may briefly retain a file lock on objects (e.g. an mmap'd
2424
commit-graph) even after the process that opened them has exited,
25-
causing `rmtree` to raise `PermissionError`. Retry a few times.
25+
causing `rmtree` to raise `PermissionError`. Retry generously.
2626
"""
2727
for i in range(attempts):
2828
try:
@@ -37,11 +37,9 @@ def robust_rmtree(path, attempts=20, delay=0.5):
3737
def time_one_repack(binary, template, work):
3838
"""Run `<binary> -C <work> repack -adfq` once and return elapsed seconds.
3939
40-
The work directory is overwritten with a fresh copy of `template`
41-
before the timed command runs.
40+
The work directory must not already exist; it is created from
41+
`template` byte-for-byte before the timed command runs.
4242
"""
43-
if os.path.exists(work):
44-
robust_rmtree(work)
4543
shutil.copytree(template, work)
4644
cmd = [binary, "-C", work, "-c", "pack.threads=4", "repack", "-adfq"]
4745
t0 = time.monotonic_ns()
@@ -77,25 +75,48 @@ def main():
7775
rng = random.Random(args.seed)
7876
os.makedirs(os.path.dirname(args.results) or ".", exist_ok=True)
7977

80-
with open(args.results, "w", newline="") as f:
81-
writer = csv.DictWriter(
82-
f, fieldnames=["iteration", "position", "variant", "seconds"])
83-
writer.writeheader()
84-
for it in range(1, args.iterations + 1):
85-
order = list(binaries.keys())
86-
rng.shuffle(order)
87-
print(f"=== iteration {it}: order = {order} ===", flush=True)
88-
for pos, variant in enumerate(order, start=1):
89-
seconds = time_one_repack(binaries[variant], args.template, args.work)
90-
writer.writerow({
91-
"iteration": it,
92-
"position": pos,
93-
"variant": variant,
94-
"seconds": f"{seconds:.6f}",
95-
})
96-
f.flush()
97-
print(f" pos={pos} variant={variant} seconds={seconds:.3f}",
98-
flush=True)
78+
# The work directory used by --work is a *base name*; each timed run
79+
# uses a unique sibling like ${work}.1.1, ${work}.1.2, ... so we never
80+
# need to rmtree a directory whose files might still be mmap-locked
81+
# by the just-exited git process (a Windows-specific issue with the
82+
# commit-graph file).
83+
work_base = args.work
84+
if os.path.exists(work_base):
85+
robust_rmtree(work_base)
86+
work_dirs = []
87+
88+
try:
89+
with open(args.results, "w", newline="") as f:
90+
writer = csv.DictWriter(
91+
f, fieldnames=["iteration", "position", "variant", "seconds"])
92+
writer.writeheader()
93+
for it in range(1, args.iterations + 1):
94+
order = list(binaries.keys())
95+
rng.shuffle(order)
96+
print(f"=== iteration {it}: order = {order} ===", flush=True)
97+
for pos, variant in enumerate(order, start=1):
98+
work = f"{work_base}.{it}.{pos}"
99+
work_dirs.append(work)
100+
seconds = time_one_repack(binaries[variant],
101+
args.template, work)
102+
writer.writerow({
103+
"iteration": it,
104+
"position": pos,
105+
"variant": variant,
106+
"seconds": f"{seconds:.6f}",
107+
})
108+
f.flush()
109+
print(f" pos={pos} variant={variant} "
110+
f"seconds={seconds:.3f}", flush=True)
111+
finally:
112+
# Cleanup is best-effort; if Windows still holds locks we accept
113+
# that the workspace will be reaped by the runner.
114+
for work in work_dirs:
115+
try:
116+
robust_rmtree(work)
117+
except OSError as e:
118+
print(f"warning: could not remove {work}: {e}",
119+
file=sys.stderr)
99120

100121
# Summary
101122
with open(args.results) as f:

0 commit comments

Comments
 (0)