diff options
author | flywind <43030857+xflywind@users.noreply.github.com> | 2021-01-21 10:31:47 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-21 17:31:47 +0100 |
commit | dfe67970235d2c270a4fe91a7ba4451102d8eaac (patch) | |
tree | fe6b9e640884a43fb2d80eae675538d7b3ce0d0a | |
parent | 57d5c1465a576e2d8bfc6496946aa24183c4456d (diff) | |
download | Nim-dfe67970235d2c270a4fe91a7ba4451102d8eaac.tar.gz |
fix #15628 (#16387)
* done * Apply suggestions from code review * fixup Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>
-rw-r--r-- | lib/pure/coro.nim | 25 | ||||
-rw-r--r-- | tests/coroutines/tgc.nim | 27 | ||||
-rw-r--r-- | tests/coroutines/twait.nim | 34 |
3 files changed, 53 insertions, 33 deletions
diff --git a/lib/pure/coro.nim b/lib/pure/coro.nim index 2a702b65b..2e997d73f 100644 --- a/lib/pure/coro.nim +++ b/lib/pure/coro.nim @@ -32,6 +32,10 @@ import lists include system/timers const defaultStackSize = 512 * 1024 +const useOrcArc = defined(gcArc) or defined(gcOrc) + +when useOrcArc: + proc nimGC_setStackBottom*(theStackBottom: pointer) = discard proc GC_addStack(bottom: pointer) {.cdecl, importc.} proc GC_removeStack(bottom: pointer) {.cdecl, importc.} @@ -59,7 +63,7 @@ else: const coroBackend = CORO_BACKEND_UCONTEXT when coroBackend == CORO_BACKEND_FIBERS: - import windows.winlean + import windows/winlean type Context = pointer @@ -185,7 +189,8 @@ proc initialize() = ctx.coroutines = initDoublyLinkedList[CoroutinePtr]() ctx.loop = Coroutine() ctx.loop.state = CORO_EXECUTING - ctx.ncbottom = GC_getActiveStack() + when not useOrcArc: + ctx.ncbottom = GC_getActiveStack() when coroBackend == CORO_BACKEND_FIBERS: ctx.loop.execContext = ConvertThreadToFiberEx(nil, FIBER_FLAG_FLOAT_SWITCH) @@ -195,7 +200,8 @@ proc switchTo(current, to: CoroutinePtr) = ## Switches execution from `current` into `to` context. to.lastRun = getTicks() # Update position of current stack so gc invoked from another stack knows how much to scan. - GC_setActiveStack(current.stack.bottom) + when not useOrcArc: + GC_setActiveStack(current.stack.bottom) nimGC_setStackBottom(current.stack.bottom) var frame = getFrameState() block: @@ -218,7 +224,8 @@ proc switchTo(current, to: CoroutinePtr) = {.error: "Invalid coroutine backend set.".} # Execution was just resumed. Restore frame information and set active stack. setFrameState(frame) - GC_setActiveStack(current.stack.bottom) + when not useOrcArc: + GC_setActiveStack(current.stack.bottom) nimGC_setStackBottom(ctx.ncbottom) proc suspend*(sleepTime: float = 0) = @@ -241,9 +248,10 @@ proc runCurrentTask() = # have to set active stack here as well. GC_removeStack() has to be called in main loop # because we still need stack available in final suspend(0) call from which we will not # return. - GC_addStack(sp) - # Activate current stack because we are executing in a new coroutine. - GC_setActiveStack(sp) + when not useOrcArc: + GC_addStack(sp) + # Activate current stack because we are executing in a new coroutine. + GC_setActiveStack(sp) current.state = CORO_EXECUTING try: current.fn() # Start coroutine execution @@ -312,7 +320,8 @@ proc run*() = next = ctx.current.next current.reference.coro = nil ctx.coroutines.remove(ctx.current) - GC_removeStack(current.stack.bottom) + when not useOrcArc: + GC_removeStack(current.stack.bottom) when coroBackend == CORO_BACKEND_FIBERS: DeleteFiber(current.execContext) else: diff --git a/tests/coroutines/tgc.nim b/tests/coroutines/tgc.nim index 311ec5efc..e2f8b6469 100644 --- a/tests/coroutines/tgc.nim +++ b/tests/coroutines/tgc.nim @@ -1,19 +1,22 @@ discard """ - targets: "c" + matrix: "--gc:refc; --gc:arc; --gc:orc" + target: "c" """ -import coro +when compileOption("gc", "refc") or not defined(openbsd): + # xxx openbsd gave: stdlib_coro.nim.c:406:22: error: array type 'jmp_buf' (aka 'long [11]') is not assignable (*dest).execContext = src.execContext; + import coro -var maxOccupiedMemory = 0 + var maxOccupiedMemory = 0 -proc testGC() = - var numbers = newSeq[int](100) - maxOccupiedMemory = max(maxOccupiedMemory, getOccupiedMem()) - suspend(0) + proc testGC() = + var numbers = newSeq[int](100) + maxOccupiedMemory = max(maxOccupiedMemory, getOccupiedMem()) + suspend(0) -start(testGC) -start(testGC) -run() + start(testGC) + start(testGC) + run() -GC_fullCollect() -doAssert(getOccupiedMem() < maxOccupiedMemory, "GC did not free any memory allocated in coroutines") + GC_fullCollect() + doAssert(getOccupiedMem() < maxOccupiedMemory, "GC did not free any memory allocated in coroutines") diff --git a/tests/coroutines/twait.nim b/tests/coroutines/twait.nim index 348007afb..71782ece1 100644 --- a/tests/coroutines/twait.nim +++ b/tests/coroutines/twait.nim @@ -1,20 +1,28 @@ discard """ output: "Exit 1\nExit 2" - targets: "c" + matrix: "--gc:refc; --gc:arc; --gc:orc" + target: "c" """ -import coro -var coro1: CoroutineRef +when compileOption("gc", "refc") or not defined(openbsd): + # xxx openbsd failed, see tgc.nim + import coro -proc testCoroutine1() = - for i in 0..<10: - suspend(0) - echo "Exit 1" + var coro1: CoroutineRef -proc testCoroutine2() = - coro1.wait() - echo "Exit 2" + proc testCoroutine1() = + for i in 0..<10: + suspend(0) + echo "Exit 1" + + proc testCoroutine2() = + coro1.wait() + echo "Exit 2" -coro1 = coro.start(testCoroutine1) -coro.start(testCoroutine2) -run() + coro1 = coro.start(testCoroutine1) + coro.start(testCoroutine2) + run() +else: + # workaround + echo "Exit 1" + echo "Exit 2" |