summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorringabout <43030857+ringabout@users.noreply.github.com>2022-11-23 14:20:35 +0800
committerGitHub <noreply@github.com>2022-11-23 07:20:35 +0100
commitd3eb1383d12d6dc20774b082b4085990bbc518dc (patch)
treec9873878fea6583109e2ee72ecbdb9f5beb3a306
parent5adfaa2a9247322f5dd3a0f911e0dea25a616b14 (diff)
downloadNim-d3eb1383d12d6dc20774b082b4085990bbc518dc.tar.gz
alloc uses atomic operations only when necessary (#20899)
-rw-r--r--lib/system/alloc.nim22
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)