//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: /** @author Michael E. Cotterell * @version 1.0 * @date Wed Aug 21 20:08:06 EDT 2013 * @see LICENSE (MIT style license file). */ package scalation.coroutine import scala.collection.mutable.PriorityQueue import scala.util.continuations._ //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: /** This `Scheduler` trait provides an interface for coroutine schedulers. */ trait Scheduler extends Coroutine { /** The currently executing coroutine (execute one at a time). */ protected var _current: Coroutine = null /** The clock that keep track of the current scheduling time. */ protected var _clock = 0.0 //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: /** The current value of the Scheduler's clock. */ final def clock () = _clock //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: /** Schedule (first time) or reschedule (subsequent times) a coroutine to * execute. * @param coroutine the coroutine to be scheduled */ def reschedule (coroutine: Coroutine): Unit } // Scheduler //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: /** This `PriorityScheduler` class provides a coroutine scheduler implementation * that is backed by an instance of the `PriorityQueue [Coroutine]` class. */ case class PriorityScheduler () extends Scheduler { /** The future event list. */ protected val agenda = PriorityQueue.empty [Coroutine] //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: /** Implements for Scheduler mixin. */ def reschedule (coroutine: Coroutine) = { agenda += coroutine } //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: /** The scheduler itself is a coroutine and may be thought of as the * director. The director iteratively manages the clock and the agenda of * coroutines until the agenda becomes empty. */ override def run (): Unit @suspendable = { while (!agenda.isEmpty) { _current = agenda.dequeue () _clock = _current.actTime println("[%.6f] %s RESUMES %s".format (_clock, "Scheduler", _current)) yieldToCoroutine (_current) } // while } // run } // PriorityScheduler