Merge branch 'coro-remove-prefix' of https://github.com/reactormonk/nim into reactormonk-coro-remove-prefix

This commit is contained in:
Dominik Picheta 2015-08-30 13:08:30 +01:00
commit fa99a60222

View file

@ -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