///////////////////////////////////////////////////////////////////////////// // // Bossa, a framework for scheduler programming // Copyright (C) 2005 Ecole des Mines de Nantes and // Department of Computer Science, University of Copenhagen // // This file is part of Bossa. // // Bossa is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation; either version 2.1 of the License, or // any later version. // // Bossa is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with Bossa; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // Please send remarks, questions and bug reports to bossa@emn.fr // or to: // // Gilles Muller // Ecole des Mines de Nantes, // La Chantrerie - 4, rue Alfred Kastler. B.P. 20722 // 44307 NANTES Cedex 3, FRANCE // /////////////////////////////////////////////////////////////////////////////// /* * This VS scheduler does not support preemption * */ default virtual_scheduler Proportion = { const int MaxProp = 100; type TypeProp = [0 .. MaxProp]; scheduler = { int ticks; int proportion; } int period = 10; TypeProp totalProp = 0; bool trace_on = false; states = { RUNNING running : scheduler; READY ready : select queue; READY expired : private queue; BLOCKED blocked : queue; } handler (event e) { On system.clocktick { scheduler s = running; s => forwardImmediate (); s.ticks--; /* no more ticks so suspend the scheduler */ if (!(s in BLOCKED) && s.ticks == 0) { s.ticks = (s.proportion * period) / MaxProp; s => expired; } } On unblock.*, unblock.timer.*, block.*, yield.*, process.* { schedulerOf(e.target) => forwardImmediate(); } On preempt { running => forwardImmediate(); } On bossa.schedule { if (empty(ready)) { foreach (s in expired) { s => ready; } foreach (s in blocked) { s.ticks = (s.proportion * period) / MaxProp; } } select() => forwardImmediate(); // get the first scheduler in the queue } } interface = { void attach (scheduler s, TypeProp prop) { if (prop < 0) { // admission control error("prop cannot be negative"); } if (totalProp + prop > MaxProp) { error("maximum proportion exceeded"); } totalProp += prop; // scheduler is accepted s.ticks = (prop * period) / MaxProp; s.proportion = prop; } void detach (scheduler s) { totalProp = totalProp - s.proportion; } void set_period (int new_period) { period = new_period; if (!empty(running)) { running.ticks = (running.proportion * period) / MaxProp; } foreach (s in ready) { s.ticks = (s.proportion * period) / MaxProp; } foreach (s in expired) { s.ticks = (s.proportion * period) / MaxProp; } foreach (s in blocked) { s.ticks = (s.proportion * period) / MaxProp; } } } }