PageRenderTime 36ms CodeModel.GetById 24ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

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