alloc uses atomic operations only when necessary (#20899)
This commit is contained in:
parent
5adfaa2a92
commit
d3eb1383d1
1 changed files with 17 additions and 5 deletions
|
|
@ -759,10 +759,14 @@ proc deallocBigChunk(a: var MemRegion, c: PBigChunk) =
|
||||||
when defined(gcDestructors):
|
when defined(gcDestructors):
|
||||||
template atomicPrepend(head, elem: untyped) =
|
template atomicPrepend(head, elem: untyped) =
|
||||||
# see also https://en.cppreference.com/w/cpp/atomic/atomic_compare_exchange
|
# 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
|
elem.next.storea head.loada
|
||||||
if atomicCompareExchangeN(addr head, addr elem.next, elem, weak = true, ATOMIC_RELEASE, ATOMIC_RELAXED):
|
head.storea elem
|
||||||
break
|
|
||||||
|
|
||||||
proc addToSharedFreeListBigChunks(a: var MemRegion; c: PBigChunk) {.inline.} =
|
proc addToSharedFreeListBigChunks(a: var MemRegion; c: PBigChunk) {.inline.} =
|
||||||
sysAssert c.next == nil, "c.next pointer must be nil"
|
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"
|
sysAssert c.size == size, "rawAlloc 6"
|
||||||
when defined(gcDestructors):
|
when defined(gcDestructors):
|
||||||
if c.freeList == nil:
|
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)
|
compensateCounters(a, c, size)
|
||||||
if c.freeList == nil:
|
if c.freeList == nil:
|
||||||
sysAssert(c.acc + smallChunkOverhead() + size <= SmallChunkSize,
|
sysAssert(c.acc + smallChunkOverhead() + size <= SmallChunkSize,
|
||||||
|
|
@ -869,7 +877,11 @@ proc rawAlloc(a: var MemRegion, requestedSize: int): pointer =
|
||||||
trackSize(c.size)
|
trackSize(c.size)
|
||||||
else:
|
else:
|
||||||
when defined(gcDestructors):
|
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:
|
if deferredFrees != nil:
|
||||||
freeDeferredObjects(a, deferredFrees)
|
freeDeferredObjects(a, deferredFrees)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue