Here is the PoC.
import libcachesim as lcs
import threading
import time
S3_URI = "s3://cache-datasets/cache_dataset_oracleGeneral/2007_msr/msr_hm_0.oracleGeneral.zst"
def run_heavy_simulation(name):
# Create a large synthetic trace
reader = lcs.TraceReader(trace=S3_URI)
cache = lcs.LRU(cache_size=1024*1024)
print(f"Thread {name} starting simulation...")
start = time.time()
# Call C++ core logic
lcs.Util.process_trace(cache, reader)
end = time.time()
print(f"Thread {name} completed in {end - start:.2f}s")
# --- Experiment start ---
start_total = time.time()
t1 = threading.Thread(target=run_heavy_simulation, args=("A",))
t2 = threading.Thread(target=run_heavy_simulation, args=("B",))
t1.start()
t2.start()
t1.join()
t2.join()
end_total = time.time()
print(f"\nTotal elapsed time: {end_total - start_total:.2f}s")
# Verification:
# If total time ≈ single-thread time -> GIL released successfully (Success)
# If total time ≈ single-thread time * 2 -> GIL still held (Fail)
The output is
[INFO] 05-17-2026 00:16:42 cli_reader_utils.c:213 (tid=123568604841664): detecting trace type: ORACLE_GENERAL_TRACE
Thread A starting simulation...
Thread A completed in 0.45s
[INFO] 05-17-2026 00:16:42 cli_reader_utils.c:213 (tid=123568596448960): detecting trace type: ORACLE_GENERAL_TRACE
Thread B starting simulation...
Thread B completed in 0.42s
Total elapsed time: 0.91s
Here is the PoC.
The output is