/src/kilim/WorkerThread.java

http://github.com/kilim/kilim · Java · 102 lines · 76 code · 14 blank · 12 comment · 13 complexity · fbe3daeff10c6dc57e33b82eda631284 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.AtomicInteger;
  8. public class WorkerThread extends Thread {
  9. volatile Task runningTask;
  10. /**
  11. * A list of tasks that prefer to run only on this thread. This is used by kilim.ReentrantLock and Task to ensure
  12. * that lock.release() is done on the same thread as lock.acquire()
  13. */
  14. RingQueue<Task> tasks = new RingQueue<Task>(10);
  15. Scheduler scheduler;
  16. static AtomicInteger gid = new AtomicInteger();
  17. public int numResumes = 0;
  18. WorkerThread(Scheduler ascheduler) {
  19. super("KilimWorker-" + gid.incrementAndGet());
  20. scheduler = ascheduler;
  21. }
  22. public void run() {
  23. try {
  24. while (true) {
  25. Task t = getNextTask(this); // blocks until task available
  26. runningTask = t;
  27. t._runExecute(this);
  28. runningTask = null;
  29. }
  30. } catch (ShutdownException se) {
  31. // nothing to do.
  32. } catch (OutOfMemoryError ex) {
  33. System.err.println("Out of memory");
  34. System.exit(1);
  35. } catch (Throwable ex) {
  36. ex.printStackTrace();
  37. System.err.println(runningTask);
  38. }
  39. runningTask = null;
  40. }
  41. protected Task getNextTask(WorkerThread workerThread) throws ShutdownException {
  42. Task t = null;
  43. while (true) {
  44. if (scheduler.isShutdown())
  45. throw new ShutdownException();
  46. t = getNextTask();
  47. if (t != null)
  48. break;
  49. // try loading from scheduler
  50. scheduler.loadNextTask(this);
  51. synchronized (this) { // ///////////////////////////////////////
  52. // Wait if still no task to execute.
  53. t = tasks.get();
  54. if (t != null)
  55. break;
  56. scheduler.addWaitingThread(this);
  57. try {
  58. wait();
  59. } catch (InterruptedException ignore) {
  60. } // shutdown indicator checked above
  61. } // //////////////////////////////////////////////////////////
  62. }
  63. assert t != null : "Returning null task";
  64. return t;
  65. }
  66. public Task getCurrentTask() {
  67. return runningTask;
  68. }
  69. public synchronized void addRunnableTask(Task t) {
  70. assert t.preferredResumeThread == null || t.preferredResumeThread == this : "Task given to wrong thread";
  71. tasks.put(t);
  72. notify();
  73. }
  74. public synchronized boolean hasTasks() {
  75. return tasks.size() > 0;
  76. }
  77. public synchronized Task getNextTask() {
  78. return tasks.get();
  79. }
  80. public synchronized void waitForMsgOrSignal() {
  81. try {
  82. if (tasks.size() == 0) {
  83. wait();
  84. }
  85. } catch (InterruptedException ignore) {
  86. }
  87. }
  88. }