001    // DebugScheduler.java, created by wbeebee
002    // Copyright (C) 2002 Wes Beebee <wbeebee@mit.edu>
003    // Licensed under the terms of the GNU GPL; see COPYING for details.
004    package javax.realtime;
005    
006    import java.util.List;
007    import java.util.ArrayList;
008    import java.util.NoSuchElementException;
009    import java.util.Iterator;
010    
011    /** <code>DebugScheduler</code> is a scheduler designed to test the rest of the system.
012     *  It produces a prodigious amount of debugging output as well as asserting many invariants.
013     */
014    public class DebugScheduler extends Scheduler {
015        static DebugScheduler instance = null;
016        RefList threadList = new RefList();
017        RefList disabledThreads = new RefList();
018        Iterator iterator = threadList.roundIterator();
019    
020        protected DebugScheduler() {
021            super();
022            setQuanta(1); // Start switching after a specified number of milliseconds
023        }
024    
025        /** Return an instance of a DebugScheduler */
026        public static DebugScheduler instance() {
027            if (instance == null) {
028                ImmortalMemory.instance().enter(new Runnable() {
029                    public void run() {
030                        instance = new DebugScheduler();
031                    }
032                });
033            }
034    
035            return instance;
036        }
037        
038        /** It is always feasible to add another thread to a DebugScheduler. */
039        protected void addToFeasibility(Schedulable schedulable) {}
040    
041        public void fireSchedulable(Schedulable schedulable) {
042            schedulable.run();
043        }
044    
045        /** Used to determine the policy of the <code>Scheduler</code>. */
046        public String getPolicyName() {
047            return "Debug scheduler";
048        }
049    
050        /** It is always feasible to add another thread to a DebugScheduler. */
051        public boolean isFeasible() {
052            return true;
053        }
054    
055        /** It is always feasible to add another thread to a DebugScheduler. */
056        protected boolean isFeasible(Schedulable s, ReleaseParameters rp) {
057            return true;
058        }
059    
060        /** It is always feasible to add another thread to a DebugScheduler. */
061        protected void removeFromFeasibility(Schedulable schedulable) {}
062    
063        /** It is always feasible to add another thread to a DebugScheduler. */
064        public boolean setIfFeasible(Schedulable schedulable,
065                                     ReleaseParameters release,
066                                     MemoryParameters memory) {
067            return true;
068        }
069    
070        /** It is always feasible to add another thread to a DebugScheduler. */
071        public boolean setIfFeasible(Schedulable schedulable,
072                                     ReleaseParameters release,
073                                     MemoryParameters memory,
074                                     ProcessingGroupParameters group) {
075            return true;
076        }
077    
078        protected long chooseThread(long currentTime) {
079            setQuanta(1); // Switch again after a specified number of milliseconds.
080            try {
081                return ((Long)iterator.next()).longValue();
082            } catch (NoSuchElementException e) {
083                NoHeapRealtimeThread.print("No threads left to run!");
084                System.exit(-1);
085                return 0;
086            }
087        }
088    
089        protected void addThread(RealtimeThread thread) {
090            NoHeapRealtimeThread.print("\naddThread1("+thread.getUID()+")");
091            if (thread.getUID()<0) {
092                NoHeapRealtimeThread.print("assert: addThread 2");
093                print();
094                System.exit(-1);
095            }
096            if (disabledThreads.contains(thread.getUID())) {
097                NoHeapRealtimeThread.print("assert: addThread ");
098                print();
099                System.exit(-1);
100            }
101            threadList.add(thread.getUID());
102        }
103    
104        protected void removeThread(RealtimeThread thread) {
105            NoHeapRealtimeThread.print("\nremoveThread1("+thread.getUID()+")");
106            if (thread.getUID()<0) {
107                NoHeapRealtimeThread.print("assert: removeThread 2");
108                print();
109                System.exit(-1);
110            }
111            if (!threadList.contains(thread.getUID())) {
112                NoHeapRealtimeThread.print("assert: removeThread ");
113                print();
114                System.exit(-1);
115            }
116            threadList.remove(thread.getUID());
117        }
118    
119        protected void addThread(long threadID) {
120            NoHeapRealtimeThread.print("\naddThread2("+threadID+")");
121            if (threadID>0) {
122                NoHeapRealtimeThread.print("assert: addThread 1");
123                print();
124                System.exit(-1);
125            }
126            threadList.add(threadID);
127        }
128    
129        protected void removeThread(long threadID) {
130            NoHeapRealtimeThread.print("\nremoveThread2("+threadID+")");
131            if (threadID>0) {
132                NoHeapRealtimeThread.print("assert: removeThread 1");
133                print();
134                System.exit(-1);
135            }
136            threadList.remove(threadID);
137        }
138    
139        protected void disableThread(long threadID) {
140            NoHeapRealtimeThread.print("\ndisableThread("+threadID+")");
141            if (!threadList.contains(threadID)) {
142                NoHeapRealtimeThread.print("assert: disableThread ");
143                print();
144                System.exit(-1);
145            }
146            threadList.remove(threadID);
147            disabledThreads.add(threadID);
148        }
149    
150        protected void enableThread(long threadID) {
151            NoHeapRealtimeThread.print("\nenableThread("+threadID+")");
152            if (!disabledThreads.contains(threadID)) {
153                NoHeapRealtimeThread.print("assert: enableThread ");
154                print();
155                System.exit(-1);
156            }
157            threadList.add(threadID);
158            disabledThreads.remove(threadID);
159        }
160    
161        protected void waitForNextPeriod(RealtimeThread rt) {
162        }
163    
164        public String toString() {
165            return "["+threadList+","+disabledThreads+"]";
166        }
167    }