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 Thread {
027: /*
028: static void stopAndDeleteThreadKernelExceptionHandler() {
029: Thread theThread = Scheduler.currentThread();
030: DEOSProcess ownerProcess = Scheduler.currentProcess();
031:
032: int interruptState = CPU.enterCritical();
033: theThread.stopThread();
034: theThread.itsCreationStatus = threadStatusNotCreated;
035: ownerProcess.deallocateCPUBudgetForThread( theThread );
036: theThread = null;
037: Scheduler.scheduleOtherThread();
038: CPU.exitCritical( interruptState );
039: }
040: */
041: static final int threadStatusNotCreated = 0;
042: static final int threadStatusDormant = 1;
043: static final int threadStatusActive = 2;
044: static final int threadStatusKernelExceptionPending = 3;
045: threadListNode timeoutNode;
046: threadListNode startOfPeriodWaitNode;
047: threadListNode preemptionNode;
048: Budget itsBudget;
049: Budget itsCurrentBudget;
050: int itsLastExecution;
051: int itsLastCompletion;
052: StartOfPeriodEvent itsPeriodicEvent;
053: int itsPeriodIndex;
054: int itsCurrentPriority;
055: int itsCreationStatus;
056: String itsName;
057: DEOSThread body;
058:
059: public Thread(String name) {
060: //System.out.println("Thread Constructor");
061: itsName = name;
062:
063: timeoutNode = new threadListNode(this );
064: startOfPeriodWaitNode = new threadListNode(this );
065: ;
066: preemptionNode = new threadListNode(this );
067:
068: // %%%%%% added this see athread.spin
069: itsBudget = new Budget();
070: itsCreationStatus = threadStatusNotCreated;
071:
072: Assertion.addThread(this );
073:
074: if (name.equals("main")) {
075: body = new DEOSMainThread(this );
076: } else if (name.equals("idle")) {
077: body = new DEOSIdleThread(this );
078: } else {
079: body = new DEOSThread(this );
080: }
081: }
082:
083: public DEOSThread getBody() {
084: return body;
085: }
086:
087: public void setCPUBudget(int b) {
088: //System.out.println("Thread.setCPUBudget " + b);
089: itsBudget.setTotalBudgetInUsec(b);
090: }
091:
092: public void setCurrentPriority(int p) {
093: //System.out.println("Thread.setCurrentPriority " + p);
094: itsCurrentPriority = p;
095: }
096:
097: public boolean isIdle() {
098: return itsName.equals("idle");
099: }
100:
101: public boolean isMain() {
102: return itsName.equals("main");
103: }
104:
105: public boolean ConceptualObjectConstructor(int period) {
106: itsPeriodIndex = period;
107: itsCurrentPriority = Scheduler
108: .priorityForPeriodIndex(itsPeriodIndex);
109: itsPeriodicEvent = StartOfPeriodEvent
110: .eventForPeriodIndex(itsPeriodIndex);
111: itsCurrentBudget = itsBudget;
112: itsCreationStatus = threadStatusDormant;
113:
114: return true;
115: }
116:
117: public void ConceptualObjectDestructor() {
118: itsCreationStatus = threadStatusNotCreated;
119: }
120:
121: public Budget budget() {
122: return itsBudget;
123: }
124:
125: public void completeForPeriod() {
126: //Verify.beginAtomic();
127: waitForNextTriggeringEvent();
128: itsLastCompletion = itsPeriodicEvent.currentPeriod();
129:
130: //Verify.endAtomic();
131: }
132:
133: public void cpuAllowanceExceeded() {
134: if (this == Scheduler.idleThread()) {
135: //System.out.println("CPUAllowance Exceeded, but it is idle thread");
136: startChargingCPUTime();
137:
138: //System.out.println("after");
139: } else {
140: waitForNextPeriod();
141: }
142: }
143:
144: public int cpuBudget() {
145: return itsBudget.totalBudgetInUsec();
146: }
147:
148: public int currentPriority() {
149: return itsCurrentPriority;
150: }
151:
152: public void initiateStopAndDelete() {
153: // Verify.beginAtomic();
154: Thread current = Scheduler.currentThread();
155:
156: if (current != this ) {
157: System.out.println("Current running thread (" + current
158: + ") != thread trying to delete itself!" + this );
159:
160: return;
161: }
162:
163: current.stopThread();
164: current.itsCreationStatus = threadStatusNotCreated;
165: DEOSProcess.deallocateCPUBudgetForThread(current);
166:
167: // Verify.endAtomic();
168: Scheduler.scheduleOtherThread();
169: }
170:
171: public int periodIndex() {
172: return itsPeriodIndex;
173: }
174:
175: public void startChargingCPUTime() {
176: //Verify.beginAtomic();
177: //System.out.println("Thread.startChargingCPUTime");
178: int cp = itsPeriodicEvent.currentPeriod();
179: int budget;
180:
181: // added by ckong - July 3, 2001
182: if (isIdle()) {
183: budget = itsCurrentBudget.totalBudgetInUsec();
184: } else {
185: if (cp == itsLastExecution) {
186: //sop.currentId == this.itsLastExecution
187: budget = itsCurrentBudget.remainingBudgetInUsec();
188: } else {
189: budget = itsCurrentBudget.totalBudgetInUsec();
190: itsLastExecution = cp;
191:
192: int remainingTime = itsCurrentBudget
193: .remainingBudgetInUsec();
194: }
195: }
196:
197: itsCurrentBudget.setRemainingBudgetInUsec(budget);
198:
199: // Verify.endAtomic();
200: Assertion.check();
201:
202: itsCurrentBudget.startTimer();
203: }
204:
205: public void startThread(int theCPUBudget) {
206: //System.out.println("Thread.StartThread");
207: itsCurrentPriority = Scheduler
208: .priorityForPeriodIndex(itsPeriodIndex);
209: itsBudget.setTotalBudgetInUsec(theCPUBudget);
210: startThreadInternal();
211: itsLastCompletion = itsPeriodicEvent.currentPeriod() - 1;
212: waitForNextTriggeringEvent(); // assumes critical!
213: itsLastExecution = itsPeriodicEvent.currentPeriod();
214: itsLastCompletion = itsPeriodicEvent.currentPeriod();
215: }
216:
217: public void startThreadInternal() {
218: itsCreationStatus = threadStatusActive;
219: itsBudget.setRemainingBudgetInUsec(itsBudget
220: .totalBudgetInUsec());
221: itsCurrentBudget = itsBudget;
222: }
223:
224: public void stopChargingCPUTime(int bonus) {
225: //Verify.beginAtomic();
226: //System.out.println("Thread.stopChargingCPUTime");
227: // Modified by ckong - June 25, 2001
228: //int remainingTime = bonus + DEOS.theTimer.timeRemaining();
229: int remainingTime = bonus
230: + DEOS.theTimer.getRemainingTime(DEOS.systemClock
231: .getCurrentTime());
232: itsCurrentBudget.setRemainingBudgetInUsec(remainingTime);
233:
234: //body.stopThread();
235: //Verify.endAtomic();
236: }
237:
238: public void stopThread() {
239: // Verify.beginAtomic();
240: itsLastCompletion = itsPeriodicEvent.currentPeriod();
241: itsCreationStatus = threadStatusDormant;
242: Assertion.removeThread(this );
243:
244: // Verify.endAtomic();
245: }
246:
247: public String toString() {
248: return itsName;
249: }
250:
251: public void waitForNextPeriod() {
252: // Verify.beginAtomic();
253: int interruptState = CPU.enterCritical();
254: completeForPeriod();
255:
256: // Verify.endAtomic();
257: Scheduler.scheduleOtherThread();
258: CPU.exitCritical(interruptState);
259: }
260:
261: public void waitForNextTriggeringEvent() {
262: //System.out.println("Thread.waitForNextTriggeringEvent");
263: itsPeriodicEvent.makeThreadWait(this);
264: }
265: }
|