tscheduler.nim 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. discard """
  2. output: '''a1 5
  3. a2 10
  4. a1 3
  5. a1 1
  6. a2 8
  7. a2 6
  8. a2 4
  9. a2 2'''
  10. disabled: "true"
  11. """
  12. import os, strutils, times, algorithm
  13. type TaskFn = iterator (): float
  14. type Task = object
  15. coro: TaskFn
  16. next_run: float
  17. type Scheduler = object
  18. tasks: seq[Task]
  19. proc newScheduler(): Scheduler =
  20. var s = Scheduler()
  21. s.tasks = @[]
  22. return s
  23. proc start(this: var Scheduler, task: TaskFn) =
  24. var t = Task()
  25. t.coro = task
  26. t.next_run = 0.0
  27. this.tasks.add(t)
  28. proc run(this: var Scheduler) =
  29. while this.tasks.len > 0:
  30. var dead: seq[int] = @[]
  31. for i in this.tasks.low..this.tasks.high:
  32. var task = this.tasks[i]
  33. if finished(task.coro):
  34. dead.add(i)
  35. continue
  36. if task.next_run <= epochTime():
  37. task.next_run = task.coro() + epochTime()
  38. this.tasks[i] = task
  39. for i in dead:
  40. this.tasks.delete(i)
  41. if this.tasks.len > 0:
  42. sort(this.tasks, proc (t1: Task, t2: Task): int = cmp(t1.next_run, t2.next_run))
  43. sleep(int((this.tasks[0].next_run - epochTime()) * 1000))
  44. iterator a1(): float {.closure.} =
  45. var k = 5
  46. while k > 0:
  47. echo "a1 $1" % [$k]
  48. dec k, 2
  49. yield 0.5
  50. iterator a2(): float {.closure.} =
  51. var k = 10
  52. while k > 0:
  53. echo "a2 $1" % [$k]
  54. dec k, 2
  55. yield 1.5
  56. var sched = newScheduler()
  57. sched.start(a1)
  58. sched.start(a2)
  59. sched.run()