PageRenderTime 44ms CodeModel.GetById 12ms app.highlight 25ms RepoModel.GetById 1ms app.codeStats 1ms

/src/kilim/Scheduler.java

http://github.com/kilim/kilim
Java | 168 lines | 90 code | 29 blank | 49 comment | 11 complexity | d8db5277a4241fb727eaf64b2288b61e MD5 | raw file
  1/* Copyright (c) 2006, Sriram Srinivasan
  2 *
  3 * You may distribute this software under the terms of the license 
  4 * specified in the file "License"
  5 */
  6package kilim;
  7
  8import java.util.concurrent.atomic.AtomicBoolean;
  9
 10import kilim.nio.NioSelectorScheduler.RegistrationTask;
 11import kilim.timerservice.Timer;
 12
 13/**
 14 * This is a basic FIFO Executor. It maintains a list of runnable tasks and hands them out to WorkerThreads. Note
 15 * that we don't maintain a list of all tasks, but we will at some point when we introduce monitoring/watchdog
 16 * services. Paused tasks are not GC'd because their PauseReasons ought to be registered with some other live
 17 * object.
 18 *
 19 */
 20public abstract class Scheduler {
 21    public static volatile Scheduler defaultScheduler = null;
 22    public static volatile Scheduler pinnableScheduler = null;
 23    public static int defaultNumberThreads;
 24    private static final ThreadLocal<Task> taskMgr_ = new ThreadLocal<Task>();
 25    public static Logger defaultLogger = new BasicLogger();
 26
 27    protected AtomicBoolean shutdown = new AtomicBoolean(false);
 28    
 29    private Logger logger = defaultLogger;
 30
 31    static {
 32        String s = System.getProperty("kilim.Scheduler.numThreads");
 33        if (s!=null)
 34            try {
 35                defaultNumberThreads = Integer.parseInt(s);
 36            } catch (Exception e) {
 37            }
 38        if (defaultNumberThreads==0)
 39            defaultNumberThreads = Runtime.getRuntime().availableProcessors();
 40    }
 41
 42    protected static Task getCurrentTask() {
 43        return taskMgr_.get();
 44    }
 45
 46    protected static void setCurrentTask(Task t) {
 47        taskMgr_.set(t);
 48    }
 49
 50    /**
 51     * return a new default Scheduler with default queue length
 52     * @param numThreads the number of threads to use, or use the default if less than one
 53     * @return the new Scheduler
 54     */
 55    public static Scheduler make(int numThreads) { return new AffineScheduler(numThreads,0); }
 56    
 57    /**
 58     * are the queues empty allows false positives, but not false negatives ie, if this method returns false, then
 59     * at some moment during the call at least one queue was non-empty if it returns true then for each queue there
 60     * was a moment during the call when it was empty
 61     */
 62    public abstract boolean isEmptyish();
 63
 64    public abstract int numThreads();
 65    
 66    public boolean isPinnable() { return true; }
 67        
 68    /**
 69     * Schedule a task to run.
 70     * It is the task's job to ensure that it is not scheduled when it is runnable.
 71     * the default index for assignment to an executor
 72     */
 73    public void schedule(Task t) {
 74        if (t instanceof RegistrationTask)
 75            ((RegistrationTask) t).wake();
 76        else
 77            schedule(-1,t);
 78    }
 79
 80    /**
 81     * schedule a task to run
 82     * @param index the index of the executor to use, or less than zero to use the default (round robin) assignment
 83     * @param t the task
 84     */
 85    public abstract void schedule(int index,Task t);
 86
 87    public abstract void scheduleTimer(Timer t);
 88
 89    /**
 90     * block the thread till a moment at which all scheduled tasks have completed and then shutdown the scheduler
 91     * does not prevent scheduling new tasks (from other threads) until the shutdown is complete so such a task
 92     * could be partially executed
 93     */
 94    public abstract void idledown();
 95
 96    public void shutdown() {
 97        shutdown.set(true);
 98        if (defaultScheduler==this)
 99            defaultScheduler = null;
100    }
101
102    public boolean isShutdown() {
103        return shutdown.get();
104    }
105
106    /** a static accessor to allow log to be protected */
107    static protected void logRelay(Scheduler sched,Object src,Object obj) { sched.log(src,obj); }
108    
109    public static interface Logger {
110        public void log(Object source,Object problem);
111    }
112    static class BasicLogger implements Logger {
113        public void log(Object source,Object obj) {
114            if (obj instanceof Throwable)
115                ((Throwable) obj).printStackTrace();
116            else
117                System.out.println(obj);
118        }
119    }
120    
121    /**
122     * write to the log
123     * @param src the source of the log object
124     * @param obj the object to log
125     */
126    protected void log(Object src,Object obj) {
127        if (logger != null)
128            logger.log(src,obj);
129    }
130    
131    /**
132     * set a logger
133     * @param logger the logger
134     */
135    public void setLogger(Logger logger) { this.logger = logger; }
136
137    /** get and possibly instantiate a default scheduler */
138    public synchronized static Scheduler getDefaultScheduler() {
139        if (defaultScheduler==null)
140            defaultScheduler = Scheduler.make(defaultNumberThreads);
141        return defaultScheduler;
142    }
143    /** get and possibly instantiate a scheduler that is pinnable */
144    public synchronized static Scheduler getDefaultPinnable() {
145        if (pinnableScheduler==null) {
146            if (defaultScheduler==null || defaultScheduler.isPinnable())
147                pinnableScheduler = getDefaultScheduler();
148            else
149                pinnableScheduler = make(defaultNumberThreads);
150        }
151        return pinnableScheduler;
152    }
153
154    protected Scheduler getPinnable() {
155        return isPinnable() ? this : getDefaultPinnable();
156    }
157    
158    public synchronized static void setDefaultScheduler(Scheduler s) {
159        defaultScheduler = s;
160    }
161    public synchronized static void setDefaultPinnable(Scheduler s) {
162        pinnableScheduler = s;
163    }
164
165}
166
167
168