/src/kilim/Scheduler.java
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