mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-08 14:03:23 +00:00
alloc uses atomic operations only when necessary (#20899)
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user