mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-03 22:18:40 +00:00
Fix big chunk leak in allocator (#26017)
Fix proposed by GPT 5.6 Sol.
close #26016
Potentially close #22510
No concrete proof for the second one, though the described behavior
matches and the step count explains why it's so difficult to find a
repro.
(cherry picked from commit 3bb46d3217)
This commit is contained in:
40
tests/threads/tsharedfreelistbigchunks.nim
Normal file
40
tests/threads/tsharedfreelistbigchunks.nim
Normal file
@@ -0,0 +1,40 @@
|
||||
discard """
|
||||
matrix: "--mm:arc; --mm:orc"
|
||||
"""
|
||||
|
||||
import std/[atomics, typedthreads]
|
||||
|
||||
const numChunks = 23 # More than the allocator's bounded drain can process.
|
||||
|
||||
var
|
||||
pointers: array[numChunks, pointer]
|
||||
allocated: Atomic[bool]
|
||||
continueAllocating: Atomic[bool]
|
||||
|
||||
proc allocPointers() {.thread.} =
|
||||
for i in 0..<pointers.len:
|
||||
pointers[i] = allocShared(8192)
|
||||
allocated.store(true, moRelease)
|
||||
|
||||
while not continueAllocating.load(moAcquire):
|
||||
discard
|
||||
|
||||
# The first allocation drains MaxSteps + 1 chunks. The second allocation
|
||||
# must still be able to find and drain the remainder.
|
||||
for _ in 0..1:
|
||||
let p = allocShared(8192)
|
||||
deallocShared(p)
|
||||
|
||||
doAssert getOccupiedMem() == 0
|
||||
|
||||
var thread: Thread[void]
|
||||
createThread(thread, allocPointers)
|
||||
|
||||
while not allocated.load(moAcquire):
|
||||
discard
|
||||
|
||||
for p in pointers:
|
||||
deallocShared(p)
|
||||
continueAllocating.store(true, moRelease)
|
||||
|
||||
joinThread(thread)
|
||||
Reference in New Issue
Block a user