summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorRokas Kupstys <rokups@zoho.com>2017-02-17 16:49:17 +0200
committerRokas Kupstys <rokups@zoho.com>2017-02-20 17:24:19 +0200
commitd69b701ddedf706cbfcea7f96bd69453237280c6 (patch)
treebfeb148f42df61929d67129028addc1b77be2ac3
parent96c571dd96b0742b069508a75716cf5ad9baa0ec (diff)
downloadNim-d69b701ddedf706cbfcea7f96bd69453237280c6.tar.gz
Coroutines realtime support
-rw-r--r--lib/system/gc.nim49
1 files changed, 36 insertions, 13 deletions
diff --git a/lib/system/gc.nim b/lib/system/gc.nim
index e989ec111..515aa9851 100644
--- a/lib/system/gc.nim
+++ b/lib/system/gc.nim
@@ -67,6 +67,8 @@ type
     prev: ptr GcStack
     next: ptr GcStack
     bottom: pointer
+    when withRealTime:
+      bottomSaved: pointer
     pos: pointer
     maxStackSize: int
 
@@ -929,19 +931,40 @@ when withRealTime:
       collectCTBody(gch)
     release(gch)
 
-  proc GC_step*(us: int, strongAdvice = false, stackSize = -1) {.noinline.} =
-    var stackTop {.volatile.}: pointer
-    let prevStackBottom = gch.stackBottom
-    if stackSize >= 0:
-      stackTop = addr(stackTop)
-      when stackIncreases:
-        gch.stackBottom = cast[pointer](
-          cast[ByteAddress](stackTop) - sizeof(pointer) * 6 - stackSize)
-      else:
-        gch.stackBottom = cast[pointer](
-          cast[ByteAddress](stackTop) + sizeof(pointer) * 6 + stackSize)
-    GC_step(gch, us, strongAdvice)
-    gch.stackBottom = prevStackBottom
+  when defined(nimCoroutines):
+    proc GC_step*(us: int, strongAdvice = false, stackSize = -1) {.noinline.} =
+      if stackSize >= 0:
+        var stackTop {.volatile.}: pointer
+        gch.activeStack.pos = addr(stackTop)
+
+        for stack in gch.stack.items():
+          stack.bottomSaved = stack.bottom
+          when stackIncreases:
+            stack.bottom = cast[pointer](
+              cast[ByteAddress](stack.pos) - sizeof(pointer) * 6 - stackSize)
+          else:
+            stack.bottom = cast[pointer](
+              cast[ByteAddress](stack.pos) + sizeof(pointer) * 6 + stackSize)
+
+      GC_step(gch, us, strongAdvice)
+
+      if stackSize >= 0:
+        for stack in gch.stack.items():
+          stack.bottom = stack.bottomSaved
+  else:
+    proc GC_step*(us: int, strongAdvice = false, stackSize = -1) {.noinline.} =
+      var stackTop {.volatile.}: pointer
+      let prevStackBottom = gch.stackBottom
+      if stackSize >= 0:
+        stackTop = addr(stackTop)
+        when stackIncreases:
+          gch.stackBottom = cast[pointer](
+            cast[ByteAddress](stackTop) - sizeof(pointer) * 6 - stackSize)
+        else:
+          gch.stackBottom = cast[pointer](
+            cast[ByteAddress](stackTop) + sizeof(pointer) * 6 + stackSize)
+      GC_step(gch, us, strongAdvice)
+      gch.stackBottom = prevStackBottom
 
 when not defined(useNimRtl):
   proc GC_disable() =