Merge branch 'coro-remove-prefix' of https://github.com/reactormonk/nim into reactormonk-coro-remove-prefix
This commit is contained in:
commit
fa99a60222
1 changed files with 15 additions and 19 deletions
|
|
@ -15,8 +15,7 @@ import macros
|
||||||
import arch
|
import arch
|
||||||
import lists
|
import lists
|
||||||
|
|
||||||
const coroDefaultStackSize = 512 * 1024
|
const defaultStackSize = 512 * 1024
|
||||||
|
|
||||||
|
|
||||||
type Coroutine = ref object
|
type Coroutine = ref object
|
||||||
# prev: ptr Coroutine
|
# prev: ptr Coroutine
|
||||||
|
|
@ -38,8 +37,7 @@ proc GC_addStack(starts: pointer) {.cdecl, importc.}
|
||||||
proc GC_removeStack(starts: pointer) {.cdecl, importc.}
|
proc GC_removeStack(starts: pointer) {.cdecl, importc.}
|
||||||
proc GC_setCurrentStack(starts, pos: pointer) {.cdecl, importc.}
|
proc GC_setCurrentStack(starts, pos: pointer) {.cdecl, importc.}
|
||||||
|
|
||||||
|
proc start*(c: proc(), stacksize: int=defaultStackSize) =
|
||||||
proc coroStart*(c: proc(), stacksize: int=coroDefaultStackSize) =
|
|
||||||
## Adds coroutine to event loop. It does not run immediately.
|
## Adds coroutine to event loop. It does not run immediately.
|
||||||
var coro = Coroutine()
|
var coro = Coroutine()
|
||||||
coro.fn = c
|
coro.fn = c
|
||||||
|
|
@ -49,20 +47,20 @@ proc coroStart*(c: proc(), stacksize: int=coroDefaultStackSize) =
|
||||||
coroutines.append(coro)
|
coroutines.append(coro)
|
||||||
|
|
||||||
{.push stackTrace: off.}
|
{.push stackTrace: off.}
|
||||||
proc coroYield*(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 oldFrame = getFrame()
|
var oldFrame = getFrame()
|
||||||
var sp {.volatile.}: pointer
|
var sp {.volatile.}: pointer
|
||||||
GC_setCurrentStack(current.stack, cast[pointer](addr sp))
|
GC_setCurrentStack(current.stack, cast[pointer](addr sp))
|
||||||
current.sleepTime = sleep_time
|
current.sleepTime = sleepTime
|
||||||
current.lastRun = epochTime()
|
current.lastRun = epochTime()
|
||||||
if setjmp(current.ctx) == 0:
|
if setjmp(current.ctx) == 0:
|
||||||
longjmp(mainCtx, 1)
|
longjmp(mainCtx, 1)
|
||||||
setFrame(oldFrame)
|
setFrame(oldFrame)
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
proc coroRun*() =
|
proc run*() =
|
||||||
## Starts main event loop which exits when all coroutines exit. Calling this proc
|
## Starts main event loop which exits when all coroutines exit. Calling this proc
|
||||||
## starts execution of first coroutine.
|
## starts execution of first coroutine.
|
||||||
var node = coroutines.head
|
var node = coroutines.head
|
||||||
|
|
@ -108,18 +106,16 @@ proc coroRun*() =
|
||||||
else:
|
else:
|
||||||
node = node.next
|
node = node.next
|
||||||
|
|
||||||
|
proc alive*(c: proc()): bool =
|
||||||
proc coroAlive*(c: proc()): bool =
|
|
||||||
## Returns ``true`` if coroutine has not returned, ``false`` otherwise.
|
## Returns ``true`` if coroutine has not returned, ``false`` otherwise.
|
||||||
for coro in items(coroutines):
|
for coro in items(coroutines):
|
||||||
if coro.fn == c:
|
if coro.fn == c:
|
||||||
return true
|
return true
|
||||||
|
|
||||||
proc coroWait*(c: proc(), interval=0.01) =
|
proc wait*(c: proc(), interval=0.01) =
|
||||||
## Returns only after coroutine ``c`` has returned. ``interval`` is time in seconds how often.
|
## Returns only after coroutine ``c`` has returned. ``interval`` is time in seconds how often.
|
||||||
while coroAlive(c):
|
while alive(c):
|
||||||
coroYield interval
|
suspend interval
|
||||||
|
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
var stackCheckValue = 1100220033
|
var stackCheckValue = 1100220033
|
||||||
|
|
@ -128,18 +124,18 @@ when isMainModule:
|
||||||
proc c1() =
|
proc c1() =
|
||||||
for i in 0 .. 3:
|
for i in 0 .. 3:
|
||||||
echo "c1"
|
echo "c1"
|
||||||
coroYield 0.05
|
suspend 0.05
|
||||||
echo "c1 exits"
|
echo "c1 exits"
|
||||||
|
|
||||||
|
|
||||||
proc c2() =
|
proc c2() =
|
||||||
for i in 0 .. 3:
|
for i in 0 .. 3:
|
||||||
echo "c2"
|
echo "c2"
|
||||||
coroYield 0.025
|
suspend 0.025
|
||||||
coroWait(c1)
|
wait(c1)
|
||||||
echo "c2 exits"
|
echo "c2 exits"
|
||||||
|
|
||||||
coroStart(c1)
|
start(c1)
|
||||||
coroStart(c2)
|
start(c2)
|
||||||
coroRun()
|
run()
|
||||||
echo "done ", stackCheckValue
|
echo "done ", stackCheckValue
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue