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