001: //
002: // Copyright (C) 2005 United States Government as represented by the
003: // Administrator of the National Aeronautics and Space Administration
004: // (NASA). All Rights Reserved.
005: //
006: // This software is distributed under the NASA Open Source Agreement
007: // (NOSA), version 1.3. The NOSA has been approved by the Open Source
008: // Initiative. See the file NOSA-1.3-JPF at the top of the distribution
009: // directory tree for the complete NOSA document.
010: //
011: // THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
012: // KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
013: // LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
014: // SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
015: // A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
016: // THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
017: // DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
018: //
019: package DEOS;
020:
021: import gov.nasa.jpf.jvm.Verify;
022:
023: /**
024: * DOCUMENT ME!
025: */
026: class Scheduler {
027: static Thread itsRunningThread;
028: static Thread itsIdleThread;
029: static PriorityListOfThreads itsRunnableList;
030:
031: //static int systemTickCount = 0xFFFFFFFF ;
032: static DEOSProcess theProcess;
033: static SynchObject synch;
034:
035: public static DEOSProcess currentProcess() {
036: return theProcess;
037: }
038:
039: public static Thread currentThread() {
040: return itsRunningThread;
041: }
042:
043: public static Thread idleThread() {
044: return itsIdleThread;
045: }
046:
047: public static void initialize() {
048: // JAVA DEOS
049: synch = new SynchObject();
050:
051: //System.out.println("Scheduler.initialize");
052: itsRunnableList = new PriorityListOfThreads();
053: initializeIdleProcess();
054:
055: int interruptState = CPU.enterCritical();
056: itsRunningThread = itsIdleThread;
057: itsRunningThread.startChargingCPUTime();
058: CPU.exitCritical(interruptState);
059: theProcess = new DEOSProcess();
060: DEOSKernel.localStartThread(theProcess.mainThread(),
061: Registry.uSecsInFastestPeriod, 0);
062: }
063:
064: public static int priorityForPeriodIndex(int thePeriodIndex) {
065: return Registry.numPeriods - thePeriodIndex;
066: }
067:
068: public static PriorityListOfThreads runnableList() {
069: return itsRunnableList;
070: }
071:
072: public static void scheduleAnyThread() {
073: //System.out.println("Scheduler.scheduleAnyThread: current = " +
074: // itsRunningThread);
075: if (!itsRunnableList.isEmpty()) {
076: if (itsRunningThread.currentPriority() < itsRunnableList
077: .head().parent().currentPriority()) {
078: //System.out.println("Preemption");
079: itsRunnableList
080: .addAtBeginning(itsRunningThread.preemptionNode);
081: Scheduler.scheduleOtherThread();
082: } else {
083: //System.out.println("Running has Higher Priority, i.e. no Preemption");
084: itsRunningThread.stopChargingCPUTime(0);
085: itsRunningThread.startChargingCPUTime();
086: }
087: } else {
088: System.out.println("How can this be!!!");
089: }
090: }
091:
092: public static void scheduleOtherThread() {
093: Thread newThread;
094: Thread fromThread = itsRunningThread;
095:
096: // Verify.beginAtomic();
097: //System.out.println("Scheduler.scheduleOtherThread");
098: threadListNode runnableThreadListNode = itsRunnableList.head();
099: Thread runnableThread = runnableThreadListNode.parent();
100: newThread = runnableThread;
101: runnableThreadListNode.removeFromList();
102:
103: // Verify.endAtomic();
104: fromThread.stopChargingCPUTime(0);
105:
106: //Verify.endAtomic();
107: newThread.startChargingCPUTime(); // cannot add this to atomic, since
108:
109: // it can block
110: // JAVA DEOS - All the threads wait on the synch object. To wake up
111: // the newThread we interrupt() it. Since it was waiting on the
112: // synch object and the fromThread has the lock on the synch object,
113: // the new thread won't run until we call wait(). This is intended
114: // to only allow on thread to be running at a time like in the real
115: // DEOS. - penix
116: itsRunningThread = newThread;
117:
118: //System.out.println(fromThread + " waking up " + newThread);
119: // check to make sure the current thread is not also the new
120: // thread or no one will get interrupted...
121: //if (fromThread != newThread) {
122: // newThread.javaThread().interrupt();
123: // try{synch.wait();}
124: // catch(InterruptedException ex) {
125: // //System.out.println("Waking up again");
126: // };
127: //}
128: }
129:
130: //private
131: static void handleSystemTickInterrupt() {
132: //System.out.println("Scheduler.handleSystemTickInterrupt");
133: StartOfPeriodEvent.eventForPeriodIndex(0).pulseEvent(0);
134: Scheduler.scheduleAnyThread();
135:
136: // System.out.println("Scheduler.handleSystemTickInterrupt RETURN");
137: }
138:
139: //private
140: static void handleTimerInterrupt() {
141: //System.out.println("Scheduler.handleTimerInterrupt");
142: itsRunningThread.cpuAllowanceExceeded();
143: }
144:
145: private static void idleThreadMain() {
146: while (true) {
147: }
148: }
149:
150: private static void initializeIdleProcess() {
151: //System.out.println("Scheduler.initializeIdleProcess");
152: itsIdleThread = new Thread("idle");
153:
154: // %%%%%5 added this code to make it work see sched.spin file
155: itsIdleThread.ConceptualObjectConstructor(0);
156: itsIdleThread.setCurrentPriority(0);
157: itsIdleThread.waitForNextTriggeringEvent();
158:
159: itsIdleThread.startOfPeriodWaitNode.removeFromList();
160:
161: //SPIN Registry::periodDurationInMicroSecs(itsIdleThread->periodIndex())
162: itsIdleThread
163: .setCPUBudget(Registry
164: .periodDurationInMicroSecs(itsIdleThread
165: .periodIndex()));
166: itsIdleThread.budget().replenish();
167: }
168: }
|