Co-authored-by: drswinghead <drswinghead@gmail.com> Co-authored-by: Clyybber <darkmine956@gmail.com>
This commit is contained in:
parent
d19316bbb9
commit
341cd844b2
2 changed files with 14 additions and 0 deletions
|
|
@ -36,6 +36,7 @@ const defaultStackSize = 512 * 1024
|
||||||
proc GC_addStack(bottom: pointer) {.cdecl, importc.}
|
proc GC_addStack(bottom: pointer) {.cdecl, importc.}
|
||||||
proc GC_removeStack(bottom: pointer) {.cdecl, importc.}
|
proc GC_removeStack(bottom: pointer) {.cdecl, importc.}
|
||||||
proc GC_setActiveStack(bottom: pointer) {.cdecl, importc.}
|
proc GC_setActiveStack(bottom: pointer) {.cdecl, importc.}
|
||||||
|
proc GC_getActiveStack() : pointer {.cdecl, importc.}
|
||||||
|
|
||||||
const
|
const
|
||||||
CORO_BACKEND_UCONTEXT = 0
|
CORO_BACKEND_UCONTEXT = 0
|
||||||
|
|
@ -166,6 +167,7 @@ type
|
||||||
coroutines: DoublyLinkedList[CoroutinePtr]
|
coroutines: DoublyLinkedList[CoroutinePtr]
|
||||||
current: DoublyLinkedNode[CoroutinePtr]
|
current: DoublyLinkedNode[CoroutinePtr]
|
||||||
loop: Coroutine
|
loop: Coroutine
|
||||||
|
ncbottom: pointer # non coroutine stack botttom
|
||||||
|
|
||||||
var ctx {.threadvar.}: CoroutineLoopContext
|
var ctx {.threadvar.}: CoroutineLoopContext
|
||||||
|
|
||||||
|
|
@ -183,6 +185,7 @@ proc initialize() =
|
||||||
ctx.coroutines = initDoublyLinkedList[CoroutinePtr]()
|
ctx.coroutines = initDoublyLinkedList[CoroutinePtr]()
|
||||||
ctx.loop = Coroutine()
|
ctx.loop = Coroutine()
|
||||||
ctx.loop.state = CORO_EXECUTING
|
ctx.loop.state = CORO_EXECUTING
|
||||||
|
ctx.ncbottom = GC_getActiveStack()
|
||||||
when coroBackend == CORO_BACKEND_FIBERS:
|
when coroBackend == CORO_BACKEND_FIBERS:
|
||||||
ctx.loop.execContext = ConvertThreadToFiberEx(nil, FIBER_FLAG_FLOAT_SWITCH)
|
ctx.loop.execContext = ConvertThreadToFiberEx(nil, FIBER_FLAG_FLOAT_SWITCH)
|
||||||
|
|
||||||
|
|
@ -193,6 +196,7 @@ proc switchTo(current, to: CoroutinePtr) =
|
||||||
to.lastRun = getTicks()
|
to.lastRun = getTicks()
|
||||||
# Update position of current stack so gc invoked from another stack knows how much to scan.
|
# Update position of current stack so gc invoked from another stack knows how much to scan.
|
||||||
GC_setActiveStack(current.stack.bottom)
|
GC_setActiveStack(current.stack.bottom)
|
||||||
|
nimGC_setStackBottom(current.stack.bottom)
|
||||||
var frame = getFrameState()
|
var frame = getFrameState()
|
||||||
block:
|
block:
|
||||||
# Execution will switch to another fiber now. We do not need to update current stack
|
# Execution will switch to another fiber now. We do not need to update current stack
|
||||||
|
|
@ -215,12 +219,14 @@ proc switchTo(current, to: CoroutinePtr) =
|
||||||
# Execution was just resumed. Restore frame information and set active stack.
|
# Execution was just resumed. Restore frame information and set active stack.
|
||||||
setFrameState(frame)
|
setFrameState(frame)
|
||||||
GC_setActiveStack(current.stack.bottom)
|
GC_setActiveStack(current.stack.bottom)
|
||||||
|
nimGC_setStackBottom(ctx.ncbottom)
|
||||||
|
|
||||||
proc suspend*(sleepTime: float = 0) =
|
proc suspend*(sleepTime: float = 0) =
|
||||||
## Stops coroutine execution and resumes no sooner than after ``sleeptime`` seconds.
|
## Stops coroutine execution and resumes no sooner than after ``sleeptime`` seconds.
|
||||||
## Until then other coroutines are executed.
|
## Until then other coroutines are executed.
|
||||||
var current = getCurrent()
|
var current = getCurrent()
|
||||||
current.sleepTime = sleepTime
|
current.sleepTime = sleepTime
|
||||||
|
nimGC_setStackBottom(ctx.ncbottom)
|
||||||
switchTo(current, addr(ctx.loop))
|
switchTo(current, addr(ctx.loop))
|
||||||
|
|
||||||
proc runCurrentTask() =
|
proc runCurrentTask() =
|
||||||
|
|
@ -230,6 +236,7 @@ proc runCurrentTask() =
|
||||||
block:
|
block:
|
||||||
var current = getCurrent()
|
var current = getCurrent()
|
||||||
current.stack.bottom = sp
|
current.stack.bottom = sp
|
||||||
|
nimGC_setStackBottom(current.stack.bottom)
|
||||||
# Execution of new fiber just started. Since it was entered not through `switchTo` we
|
# Execution of new fiber just started. Since it was entered not through `switchTo` we
|
||||||
# have to set active stack here as well. GC_removeStack() has to be called in main loop
|
# 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
|
# because we still need stack available in final suspend(0) call from which we will not
|
||||||
|
|
@ -244,6 +251,7 @@ proc runCurrentTask() =
|
||||||
echo "Unhandled exception in coroutine."
|
echo "Unhandled exception in coroutine."
|
||||||
writeStackTrace()
|
writeStackTrace()
|
||||||
current.state = CORO_FINISHED
|
current.state = CORO_FINISHED
|
||||||
|
nimGC_setStackBottom(ctx.ncbottom)
|
||||||
suspend(0) # Exit coroutine without returning from coroExecWithStack()
|
suspend(0) # Exit coroutine without returning from coroExecWithStack()
|
||||||
doAssert false
|
doAssert false
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -273,6 +273,9 @@ when nimCoroutines:
|
||||||
gch.activeStack = gch.stack.find(bottom)
|
gch.activeStack = gch.stack.find(bottom)
|
||||||
gch.activeStack.setPosition(addr(sp))
|
gch.activeStack.setPosition(addr(sp))
|
||||||
|
|
||||||
|
proc GC_getActiveStack() : pointer {.cdecl, exportc.} =
|
||||||
|
return gch.activeStack.bottom
|
||||||
|
|
||||||
when not defined(useNimRtl):
|
when not defined(useNimRtl):
|
||||||
proc nimGC_setStackBottom(theStackBottom: pointer) =
|
proc nimGC_setStackBottom(theStackBottom: pointer) =
|
||||||
# Initializes main stack of the thread.
|
# Initializes main stack of the thread.
|
||||||
|
|
@ -300,6 +303,9 @@ when not defined(useNimRtl):
|
||||||
else:
|
else:
|
||||||
gch.stack.bottom = cast[pointer](max(a, b))
|
gch.stack.bottom = cast[pointer](max(a, b))
|
||||||
|
|
||||||
|
when nimCoroutines:
|
||||||
|
if theStackBottom != nil: gch.stack.bottom = theStackBottom
|
||||||
|
|
||||||
gch.stack.setPosition(theStackBottom)
|
gch.stack.setPosition(theStackBottom)
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue