diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2022-11-23 14:20:35 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-23 07:20:35 +0100 |
commit | d3eb1383d12d6dc20774b082b4085990bbc518dc (patch) | |
tree | c9873878fea6583109e2ee72ecbdb9f5beb3a306 | |
parent | 5adfaa2a9247322f5dd3a0f911e0dea25a616b14 (diff) | |
download | Nim-d3eb1383d12d6dc20774b082b4085990bbc518dc.tar.gz |
alloc uses atomic operations only when necessary (#20899)
-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) |