001    // RoundRobinScheduler.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>RoundRobinScheduler</code> is an example of the dumbest possible
012     *  scheduler that actually switches between threads.
013     *  It's great for getting an idea of what's required in a scheduler.
014     */
015    public class RoundRobinScheduler extends Scheduler {
016        static RoundRobinScheduler instance = null;
017        RefList threadList = new RefList();
018        RefList disabledThreads = new RefList();
019        Iterator iterator = threadList.roundIterator();
020    
021        protected RoundRobinScheduler() {
022            super();
023            setQuanta(10000); // Start switching after a specified number of milliseconds
024        }
025    
026        /** Return an instance of a RoundRobinScheduler */
027        public static RoundRobinScheduler instance() {
028            if (instance == null) {
029                ImmortalMemory.instance().enter(new Runnable() {
030                    public void run() {
031                        instance = new RoundRobinScheduler();
032                    }
033                });
034            }
035    
036            return instance;
037        }
038        
039        /** It is always feasible to add another thread to a RoundRobinScheduler. */
040        protected void addToFeasibility(Schedulable schedulable) {}
041    
042        public void fireSchedulable(Schedulable schedulable) {
043            schedulable.run();
044        }
045    
046        /** Used to determine the policy of the <code>Scheduler</code>. */
047        public String getPolicyName() {
048            return "Round robin";
049        }
050    
051        /** It is always feasible to add another thread to a RoundRobinScheduler. */
052        public boolean isFeasible() {
053            return true;
054        }
055    
056        /** It is always feasible to add another thread to a RoundRobinScheduler. */
057        protected boolean isFeasible(Schedulable s, ReleaseParameters rp) {
058            return true;
059        }
060    
061        /** It is always feasible to add another thread to a RoundRobinScheduler. */
062        protected void removeFromFeasibility(Schedulable schedulable) {}
063    
064        /** It is always feasible to add another thread to a RoundRobinScheduler. */
065        public boolean setIfFeasible(Schedulable schedulable,
066                                     ReleaseParameters release,
067                                     MemoryParameters memory) {
068            return true;
069        }
070    
071        /** It is always feasible to add another thread to a RoundRobinScheduler. */
072        public boolean setIfFeasible(Schedulable schedulable,
073                                     ReleaseParameters release,
074                                     MemoryParameters memory,
075                                     ProcessingGroupParameters group) {
076            return true;
077        }
078    
079        protected long chooseThread(long currentTime) {
080            setQuanta(10000); // Switch again after a specified number of milliseconds.
081            try {
082                return ((Long)iterator.next()).longValue();
083            } catch (NoSuchElementException e) {
084                return 0;
085            }
086        }
087    
088        protected void addThread(RealtimeThread thread) {
089            threadList.add(thread.getUID());
090        }
091    
092        protected void removeThread(RealtimeThread thread) {
093            threadList.remove(thread.getUID());
094        }
095    
096        protected void addThread(long threadID) {
097            threadList.add(threadID);
098        }
099    
100        protected void removeThread(long threadID) {
101            threadList.remove(threadID);
102        }
103    
104        protected void disableThread(long threadID) {
105            threadList.remove(threadID);
106            disabledThreads.add(threadID);
107        }
108    
109        protected void enableThread(long threadID) {
110            threadList.add(threadID);
111            disabledThreads.remove(threadID);
112        }
113    
114        /** RoundRobinScheduler is too dumb to deal w/periods. */
115        protected void waitForNextPeriod(RealtimeThread rt) {
116        }
117    
118        public String toString() {
119            return "["+threadList+","+disabledThreads+"]";
120        }
121    }