Revise low level fiber semantics to play nicer with schedulers.
Now that I'm starting to write a real async scheduler on top of Wren's basic fiber API, I have a better feel for what it needs. It turns out run() is not it. - Remove run() methods. - Add transfer() which leaves the caller of the invoked fiber alone. - Add suspend() to return control to the host application. - Add Timer.schedule() to start a new independently scheduled fiber. - Change Timer.sleep() so that it only transfers control to explicitly scheduled fibers, not any one.
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import "timer" for Timer
|
||||
|
||||
var a = Fiber.new {
|
||||
IO.print("a before")
|
||||
Timer.sleep(10)
|
||||
IO.print("a after")
|
||||
}
|
||||
|
||||
var b = Fiber.new {
|
||||
IO.print("b before")
|
||||
a.call()
|
||||
IO.print("b after")
|
||||
}
|
||||
|
||||
// All fibers are suspended since they were directly called and not scheduled.
|
||||
IO.print("before") // expect: before
|
||||
b.call() // expect: b before
|
||||
// expect: a before
|
||||
// expect: a after
|
||||
// expect: b after
|
||||
IO.print("done") // expect: done
|
||||
@@ -1,14 +1,14 @@
|
||||
import "timer" for Timer
|
||||
|
||||
Fiber.new {
|
||||
Timer.schedule {
|
||||
Timer.sleep(2)
|
||||
IO.print("a")
|
||||
}.call()
|
||||
}
|
||||
|
||||
Fiber.new {
|
||||
Timer.schedule {
|
||||
Timer.sleep(1)
|
||||
IO.print("b")
|
||||
}.call()
|
||||
}
|
||||
|
||||
IO.print("main")
|
||||
Timer.sleep(3)
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import "timer" for Timer
|
||||
|
||||
// These are both rounded to 1, so "a" should complete first.
|
||||
Fiber.new {
|
||||
Timer.schedule {
|
||||
Timer.sleep(1.5)
|
||||
IO.print("a")
|
||||
}.call()
|
||||
}
|
||||
|
||||
Fiber.new {
|
||||
Timer.schedule {
|
||||
Timer.sleep(1.3)
|
||||
IO.print("b")
|
||||
}.call()
|
||||
}
|
||||
|
||||
IO.print("main")
|
||||
Timer.sleep(3)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
import "timer" for Timer
|
||||
|
||||
IO.print(Timer.sleep(0)) // expect: null
|
||||
+16
-16
@@ -1,27 +1,27 @@
|
||||
import "timer" for Timer
|
||||
|
||||
Fiber.new {
|
||||
Timer.schedule {
|
||||
IO.print("a before")
|
||||
Timer.sleep(0)
|
||||
IO.print("a")
|
||||
}.call()
|
||||
IO.print("a after")
|
||||
}
|
||||
|
||||
Fiber.new {
|
||||
Timer.schedule {
|
||||
IO.print("b before")
|
||||
Timer.sleep(0)
|
||||
IO.print("b")
|
||||
}.call()
|
||||
|
||||
Fiber.new {
|
||||
Timer.sleep(0)
|
||||
IO.print("c")
|
||||
}.call()
|
||||
IO.print("b after")
|
||||
}
|
||||
|
||||
IO.print("main")
|
||||
Timer.sleep(0) // This is enough to let the other fiber run.
|
||||
Timer.sleep(0) // This is enough to let the other fibers run to their sleep.
|
||||
IO.print("main after")
|
||||
Timer.sleep(0) // And now their sleeps complete.
|
||||
IO.print("done")
|
||||
|
||||
// expect: main
|
||||
// Run in the order they were enqueued.
|
||||
// expect: a
|
||||
// expect: b
|
||||
// expect: c
|
||||
// expect: a before
|
||||
// expect: b before
|
||||
// expect: main after
|
||||
// expect: a after
|
||||
// expect: b after
|
||||
// expect: done
|
||||
|
||||
Reference in New Issue
Block a user