/************************************************************************** * File name : PrioritySchedulerImpl.java * * This file is part a SCJ Level 0 and Level 1 implementation, * based on SCJ Draft, Version 0.94 25 June 2013. * * It 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 3 of the * License, or (at your option) any later version. * * This SCJ Level 0 and Level 1 implementation 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 this SCJ Level 0 and Level 1 implementation. * If not, see <http://www.gnu.org/licenses/>. * * Copyright 2012 * @authors Anders P. Ravn, Aalborg University, DK * Stephan E. Korsholm and Hans Søndergaard, * VIA University College, DK *************************************************************************/ package javax.safetycritical; import vm.Process; final class PrioritySchedulerImpl implements vm.Scheduler { PrioritySchedulerImpl() { } public Process getNextProcess() { vm.ClockInterruptHandler.instance.disable(); ScjProcess scjProcess = PriorityScheduler.instance().move(); if (scjProcess != null) { scjProcess.switchToPrivateMemArea(); vm.ClockInterruptHandler.instance.enable(); return scjProcess.process; } PriorityScheduler.instance().stop( PriorityScheduler.instance().current.process); vm.ClockInterruptHandler.instance.enable(); return null; } public void wait(Object target) { vm.ClockInterruptHandler.instance.disable(); Monitor monitor = Monitor.getMonitor(target); monitor.unlock(); // process WAITING PriorityScheduler.instance().current.state = ScjProcess.State.WAITING; PriorityScheduler.instance().pFrame.waitQueue.addProcess(monitor, PriorityScheduler.instance().current); //devices.Console.println(">>> To waitQueue: " + PriorityScheduler.instance().current.index); // move to next process in readyQueue PriorityScheduler.instance().moveToNext(); vm.ClockInterruptHandler.instance.enable(); vm.ClockInterruptHandler.instance.yield(); } public void notify(Object target) { vm.ClockInterruptHandler.instance.disable(); Monitor monitor = Monitor.getMonitor(target); ScjProcess process = PriorityScheduler.instance().pFrame.waitQueue.getNextProcess(monitor); if (process != null) { // process in REQUIRELOCK state process.state = ScjProcess.State.REQUIRELOCK; //devices.Console.println("ScjProcess.State.REQUIRELOCK"); PriorityScheduler.instance().pFrame.lockQueue.addProcess(monitor, process); //devices.Console.println(">>> To lockQueue: " + process.index); } vm.ClockInterruptHandler.instance.enable(); } public void notifyAll(Object target) { vm.ClockInterruptHandler.instance.disable(); Monitor monitor = Monitor.getMonitor(target); ScjProcess process = PriorityScheduler.instance().pFrame.waitQueue.getNextProcess(monitor); while (process != null) { // if (process != null) { // // this if is on grounds of waitForObject(...): // if (process.next_temp != null) { // PriorityScheduler.instance().pFrame.readyQueue.remove(process); // process.next.set(process.next_temp); // process.next_temp = null; // process.isNotified = true; // } // } // process in REQUIRELOCK state process.state = ScjProcess.State.REQUIRELOCK; PriorityScheduler.instance().pFrame.lockQueue.addProcess(monitor, process); // devices.Console.println(">>> To lockQueue: " + process.index); process = PriorityScheduler.instance().pFrame.waitQueue.getNextProcess(monitor); } vm.ClockInterruptHandler.instance.enable(); } public Monitor getDefaultMonitor() { return null; } // public static boolean waitForObject(Object target, HighResolutionTime time) { // vm.ClockInterruptHandler.instance.disable(); // // if (time instanceof RelativeTime && // (time.getMilliseconds() < 0L || // time.getMilliseconds() == 0L && time.getNanoseconds() < 0)) // throw new IllegalArgumentException("relative time is not vaild"); // // if ((time instanceof RelativeTime && // time.getMilliseconds() == 0 && time.getNanoseconds() == 0) || // time == null) { // vm.Monitor.wait(target); // return false; // } else { // // release the lock. // Monitor monitor = Monitor.getMonitor(target); // monitor.unlockWithOutEnable(); // // // get current process and reset the boolean value // ScjProcess current = PriorityScheduler.instance().current; // current.isNotified = false; // // save the next release time // current.next_temp = new AbsoluteTime(current.next); // // // get current time. // AbsoluteTime abs = Clock.getRealtimeClock().getTime(current.next); // // // set the next release time for current process // if (time instanceof RelativeTime) { // current.next = abs.add((RelativeTime) time, abs); // } else if (time instanceof AbsoluteTime) { // current.next = new AbsoluteTime((AbsoluteTime) time); // } else { // throw new UnsupportedOperationException(); // } // // // get the next process and set appropriate state. // ScjProcess nextProcess = PriorityScheduler.instance().pFrame.readyQueue.extractMax(); // nextProcess.state = ScjProcess.State.EXECUTING; // PriorityScheduler.instance().current = nextProcess; // // // insert the current process into the the release queue // // and wait queue. // PriorityScheduler.instance().pFrame.sleepingQueue.insert(current); // ?? // PriorityScheduler.instance().pFrame.waitQueue.addProcess(monitor, current); // // // transfer to the current process // vm.ClockInterruptHandler.instance.enable(); // vm.ClockInterruptHandler.instance.yield(); // // // if it is notified by time, then the process should get the lock // // again to execute and delete the copy in the waitSet. // vm.ClockInterruptHandler.instance.disable(); // if (!PriorityScheduler.instance().current.isNotified) { // PriorityScheduler.instance().current.next_temp = null; // PriorityScheduler.instance().pFrame.waitQueue.removeProcess(PriorityScheduler.instance().current); // monitor.lockWithOutEnable(); // } // vm.ClockInterruptHandler.instance.enable(); // // return PriorityScheduler.instance().current.isNotified; // } // } }