diff options
-rw-r--r-- | lib/system/alloc.nim | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index 69bab5a85..04cbb9e3e 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -759,10 +759,14 @@ proc deallocBigChunk(a: var MemRegion, c: PBigChunk) = when defined(gcDestructors): template atomicPrepend(head, elem: untyped) = # see also https://en.cppreference.com/w/cpp/atomic/atomic_compare_exchange - while true: + when hasThreadSupport: + while true: + elem.next.storea head.loada + if atomicCompareExchangeN(addr head, addr elem.next, elem, weak = true, ATOMIC_RELEASE, ATOMIC_RELAXED): + break + else: elem.next.storea head.loada - if atomicCompareExchangeN(addr head, addr elem.next, elem, weak = true, ATOMIC_RELEASE, ATOMIC_RELAXED): - break + head.storea elem proc addToSharedFreeListBigChunks(a: var MemRegion; c: PBigChunk) {.inline.} = sysAssert c.next == nil, "c.next pointer must be nil" @@ -842,7 +846,11 @@ proc rawAlloc(a: var MemRegion, requestedSize: int): pointer = sysAssert c.size == size, "rawAlloc 6" when defined(gcDestructors): if c.freeList == nil: - c.freeList = atomicExchangeN(addr c.sharedFreeList, nil, ATOMIC_RELAXED) + when hasThreadSupport: + c.freeList = atomicExchangeN(addr c.sharedFreeList, nil, ATOMIC_RELAXED) + else: + c.freeList = c.sharedFreeList + c.sharedFreeList = nil compensateCounters(a, c, size) if c.freeList == nil: sysAssert(c.acc + smallChunkOverhead() + size <= SmallChunkSize, @@ -869,7 +877,11 @@ proc rawAlloc(a: var MemRegion, requestedSize: int): pointer = trackSize(c.size) else: when defined(gcDestructors): - let deferredFrees = atomicExchangeN(addr a.sharedFreeListBigChunks, nil, ATOMIC_RELAXED) + when hasThreadSupport: + let deferredFrees = atomicExchangeN(addr a.sharedFreeListBigChunks, nil, ATOMIC_RELAXED) + else: + let deferredFrees = a.sharedFreeListBigChunks + a.sharedFreeListBigChunks = nil if deferredFrees != nil: freeDeferredObjects(a, deferredFrees) |