Mercurial > projects > dwt-addons
diff dwtx/core/internal/jobs/DeadlockDetector.d @ 167:862b05e0334a
Add a wrapper for Thread
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Tue, 09 Sep 2008 15:59:16 +0200 |
parents | 9d0585bcb7aa |
children |
line wrap: on
line diff
--- a/dwtx/core/internal/jobs/DeadlockDetector.d Mon Sep 08 01:01:30 2008 +0200 +++ b/dwtx/core/internal/jobs/DeadlockDetector.d Tue Sep 09 15:59:16 2008 +0200 @@ -12,7 +12,7 @@ *******************************************************************************/ module dwtx.core.internal.jobs.DeadlockDetector; -import tango.core.Thread; +import dwtx.dwtxhelper.JThread; import tango.io.Stdout; import tango.text.convert.Format; @@ -101,9 +101,9 @@ * are actually deadlocked with the current thread. * Add the threads that form deadlock to the deadlockedThreads list. */ - private bool addCycleThreads(ArrayList deadlockedThreads, Thread next) { + private bool addCycleThreads(ArrayList deadlockedThreads, JThread next) { //get the thread that block the given thread from running - Thread[] blocking = blockingThreads(next); + JThread[] blocking = blockingThreads(next); //if the thread is not blocked by other threads, then it is not part of a deadlock if (blocking.length is 0) return false; @@ -128,7 +128,7 @@ /** * Get the thread(s) that own the lock this thread is waiting for. */ - private Thread[] blockingThreads(Thread current) { + private JThread[] blockingThreads(JThread current) { //find the lock this thread is waiting for ISchedulingRule lock = cast(ISchedulingRule) getWaitingLock(current); return getThreadsOwningLock(lock); @@ -167,7 +167,7 @@ * Returns true IFF the matrix contains a row for the given thread. * (meaning the given thread either owns locks or is waiting for locks) */ - bool contains(Thread t) { + bool contains(JThread t) { return lockThreads.contains(t); } @@ -200,7 +200,7 @@ /** * Returns all the locks owned by the given thread */ - private Object[] getOwnedLocks(Thread current) { + private Object[] getOwnedLocks(JThread current) { ArrayList ownedLocks = new ArrayList(1); int index = indexOf(current, false); @@ -216,7 +216,7 @@ /** * Returns an array of threads that form the deadlock (usually 2). */ - private Thread[] getThreadsInDeadlock(Thread cause) { + private JThread[] getThreadsInDeadlock(JThread cause) { ArrayList deadlockedThreads = new ArrayList(2); /** * if the thread that caused deadlock doesn't own any locks, then it is not part @@ -225,15 +225,15 @@ if (ownsLocks(cause)) deadlockedThreads.add(cause); addCycleThreads(deadlockedThreads, cause); - return arraycast!(Thread)( deadlockedThreads.toArray()); + return arraycast!(JThread)( deadlockedThreads.toArray()); } /** * Returns the thread(s) that own the given lock. */ - private Thread[] getThreadsOwningLock(ISchedulingRule rule) { + private JThread[] getThreadsOwningLock(ISchedulingRule rule) { if (rule is null) - return new Thread[0]; + return new JThread[0]; int lockIndex = indexOf(rule, false); ArrayList blocking = new ArrayList(1); for (int i = 0; i < graph.length; i++) { @@ -244,13 +244,13 @@ Stdout.formatln(Format("Lock {} is involved in deadlock but is not owned by any thread.", rule )); //$NON-NLS-1$ //$NON-NLS-2$ if ((blocking.size() > 1) && (cast(ILock)rule ) && (JobManager.DEBUG_LOCKS)) Stdout.formatln(Format("Lock {} is owned by more than 1 thread, but it is not a rule.", rule )); //$NON-NLS-1$ //$NON-NLS-2$ - return arraycast!(Thread)( blocking.toArray()); + return arraycast!(JThread)( blocking.toArray()); } /** * Returns the lock the given thread is waiting for. */ - private Object getWaitingLock(Thread current) { + private Object getWaitingLock(JThread current) { int index = indexOf(current, false); //find the lock that this thread is waiting for for (int j = 0; j < graph[index].length; j++) { @@ -279,7 +279,7 @@ * Returns the index of the given thread in the thread array. If the thread * is not present in the array, it is added to the end. */ - private int indexOf(Thread owner, bool add) { + private int indexOf(JThread owner, bool add) { int index = lockThreads.indexOf(owner); if ((index < 0) && add) { lockThreads.add(owner); @@ -299,7 +299,7 @@ /** * The given lock was acquired by the given thread. */ - void lockAcquired(Thread owner, ISchedulingRule lock) { + void lockAcquired(JThread owner, ISchedulingRule lock) { int lockIndex = indexOf(lock, true); int threadIndex = indexOf(owner, true); if (resize) @@ -333,18 +333,18 @@ /** * The given lock was released by the given thread. Update the graph. */ - void lockReleased(Thread owner, ISchedulingRule lock) { + void lockReleased(JThread owner, ISchedulingRule lock) { int lockIndex = indexOf(lock, false); int threadIndex = indexOf(owner, false); //make sure the lock and thread exist in the graph if (threadIndex < 0) { if (JobManager.DEBUG_LOCKS) - Stdout.formatln("[lockReleased] Lock {} was already released by thread {}", lock, owner.name()); //$NON-NLS-1$ //$NON-NLS-2$ + Stdout.formatln("[lockReleased] Lock {} was already released by thread {}", lock, owner.getName()); //$NON-NLS-1$ //$NON-NLS-2$ return; } if (lockIndex < 0) { if (JobManager.DEBUG_LOCKS) - Stdout.formatln("[lockReleased] Thread {} already released lock {}", owner.name(), lock); //$NON-NLS-1$ //$NON-NLS-2$ + Stdout.formatln("[lockReleased] Thread {} already released lock {}", owner.getName(), lock); //$NON-NLS-1$ //$NON-NLS-2$ return; } //if this lock was suspended, set it to NO_STATE @@ -358,7 +358,7 @@ if ((lock.isConflicting(cast(ISchedulingRule) locks.get(j))) || (!(cast(ILock)lock ) && !(cast(ILock)locks.get(j)) && (graph[threadIndex][j] > NO_STATE))) { if (graph[threadIndex][j] is NO_STATE) { if (JobManager.DEBUG_LOCKS) - Stdout.formatln("[lockReleased] More releases than acquires for thread {} and lock {}", owner.name(), lock); //$NON-NLS-1$ //$NON-NLS-2$ + Stdout.formatln("[lockReleased] More releases than acquires for thread {} and lock {}", owner.getName(), lock); //$NON-NLS-1$ //$NON-NLS-2$ } else { graph[threadIndex][j]--; } @@ -373,18 +373,18 @@ * The given scheduling rule is no longer used because the job that invoked it is done. * Release this rule regardless of how many times it was acquired. */ - void lockReleasedCompletely(Thread owner, ISchedulingRule rule) { + void lockReleasedCompletely(JThread owner, ISchedulingRule rule) { int ruleIndex = indexOf(rule, false); int threadIndex = indexOf(owner, false); //need to make sure that the given thread and rule were not already removed from the graph if (threadIndex < 0) { if (JobManager.DEBUG_LOCKS) - Stdout.formatln("[lockReleasedCompletely] Lock {} was already released by thread {}", rule, owner.name()); //$NON-NLS-1$ //$NON-NLS-2$ + Stdout.formatln("[lockReleasedCompletely] Lock {} was already released by thread {}", rule, owner.getName()); //$NON-NLS-1$ //$NON-NLS-2$ return; } if (ruleIndex < 0) { if (JobManager.DEBUG_LOCKS) - Stdout.formatln("[lockReleasedCompletely] Thread {} already released lock {}", owner.name(), rule); //$NON-NLS-1$ //$NON-NLS-2$ + Stdout.formatln("[lockReleasedCompletely] Thread {} already released lock {}", owner.getName(), rule); //$NON-NLS-1$ //$NON-NLS-2$ return; } /** @@ -403,7 +403,7 @@ * The given thread could not get the given lock and is waiting for it. * Update the graph. */ - Deadlock lockWaitStart(Thread client, ISchedulingRule lock) { + Deadlock lockWaitStart(JThread client, ISchedulingRule lock) { setToWait(client, lock, false); int lockIndex = indexOf(lock, false); int[] temp = new int[lockThreads.size()]; @@ -411,15 +411,15 @@ if (!checkWaitCycles(temp, lockIndex)) return null; //there is a deadlock in the graph - Thread[] threads = getThreadsInDeadlock(client); - Thread candidate = resolutionCandidate(threads); + JThread[] threads = getThreadsInDeadlock(client); + JThread candidate = resolutionCandidate(threads); ISchedulingRule[] locksToSuspend = realLocksForThread(candidate); Deadlock deadlock = new Deadlock(threads, locksToSuspend, candidate); //find a thread whose locks can be suspended to resolve the deadlock if (JobManager.DEBUG_LOCKS) reportDeadlock(deadlock); if (JobManager.DEBUG_DEADLOCK) - throw new IllegalStateException(Format("Deadlock detected. Caused by thread {}.", client.name())); //$NON-NLS-1$ + throw new IllegalStateException(Format("Deadlock detected. Caused by thread {}.", client.getName())); //$NON-NLS-1$ // Update the graph to indicate that the locks will now be suspended. // To indicate that the lock will be suspended, we set the thread to wait for the lock. // When the lock is forced to be released, the entry will be cleared. @@ -432,13 +432,13 @@ * The given thread has stopped waiting for the given lock. * Update the graph. */ - void lockWaitStop(Thread owner, ISchedulingRule lock) { + void lockWaitStop(JThread owner, ISchedulingRule lock) { int lockIndex = indexOf(lock, false); int threadIndex = indexOf(owner, false); //make sure the thread and lock exist in the graph if (threadIndex < 0) { if (JobManager.DEBUG_LOCKS) - Stdout.formatln("Thread {} was already removed.", owner.name() ); //$NON-NLS-1$ //$NON-NLS-2$ + Stdout.formatln("Thread {} was already removed.", owner.getName() ); //$NON-NLS-1$ //$NON-NLS-2$ return; } if (lockIndex < 0) { @@ -447,7 +447,7 @@ return; } if (graph[threadIndex][lockIndex] !is WAITING_FOR_LOCK) - Assert.isTrue(false, Format("Thread {} was not waiting for lock {} so it could not time out.", owner.name(), (cast(Object)lock).toString())); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + Assert.isTrue(false, Format("Thread {} was not waiting for lock {} so it could not time out.", owner.getName(), (cast(Object)lock).toString())); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ graph[threadIndex][lockIndex] = NO_STATE; reduceGraph(threadIndex, lock); } @@ -455,7 +455,7 @@ /** * Returns true IFF the given thread owns a single lock */ - private bool ownsLocks(Thread cause) { + private bool ownsLocks(JThread cause) { int threadIndex = indexOf(cause, false); for (int j = 0; j < graph[threadIndex].length; j++) { if (graph[threadIndex][j] > NO_STATE) @@ -468,7 +468,7 @@ * Returns true IFF the given thread owns a single real lock. * A real lock is a lock that can be suspended. */ - private bool ownsRealLocks(Thread owner) { + private bool ownsRealLocks(JThread owner) { int threadIndex = indexOf(owner, false); for (int j = 0; j < graph[threadIndex].length; j++) { if (graph[threadIndex][j] > NO_STATE) { @@ -484,7 +484,7 @@ * Return true IFF this thread owns rule locks (i.e. implicit locks which * cannot be suspended) */ - private bool ownsRuleLocks(Thread owner) { + private bool ownsRuleLocks(JThread owner) { int threadIndex = indexOf(owner, false); for (int j = 0; j < graph[threadIndex].length; j++) { if (graph[threadIndex][j] > NO_STATE) { @@ -500,7 +500,7 @@ * Returns an array of real locks that are owned by the given thread. * Real locks are locks that implement the ILock interface and can be suspended. */ - private ISchedulingRule[] realLocksForThread(Thread owner) { + private ISchedulingRule[] realLocksForThread(JThread owner) { int threadIndex = indexOf(owner, false); ArrayList ownedLocks = new ArrayList(1); for (int j = 0; j < graph[threadIndex].length; j++) { @@ -607,14 +607,14 @@ * Adds a 'deadlock detected' message to the log with a stack trace. */ private void reportDeadlock(Deadlock deadlock) { - String msg = "Deadlock detected. All locks owned by thread " ~ deadlock.getCandidate().name() ~ " will be suspended."; //$NON-NLS-1$ //$NON-NLS-2$ + String msg = "Deadlock detected. All locks owned by thread " ~ deadlock.getCandidate().getName() ~ " will be suspended."; //$NON-NLS-1$ //$NON-NLS-2$ MultiStatus main = new MultiStatus(JobManager.PI_JOBS, JobManager.PLUGIN_ERROR, msg, new IllegalStateException()); - Thread[] threads = deadlock.getThreads(); + JThread[] threads = deadlock.getThreads(); for (int i = 0; i < threads.length; i++) { Object[] ownedLocks = getOwnedLocks(threads[i]); Object waitLock = getWaitingLock(threads[i]); StringBuffer buf = new StringBuffer("Thread "); //$NON-NLS-1$ - buf.append(threads[i].name()); + buf.append(threads[i].getName()); buf.append(" has locks: "); //$NON-NLS-1$ for (int j = 0; j < ownedLocks.length; j++) { buf.append(Format("{}",ownedLocks[j])); @@ -654,7 +654,7 @@ * Get the thread whose locks can be suspended. (i.e. all locks it owns are * actual locks and not rules). Return the first thread in the array by default. */ - private Thread resolutionCandidate(Thread[] candidates) { + private JThread resolutionCandidate(JThread[] candidates) { //first look for a candidate that has no scheduling rules for (int i = 0; i < candidates.length; i++) { if (!ownsRuleLocks(candidates[i])) @@ -672,7 +672,7 @@ /** * The given thread is waiting for the given lock. Update the graph. */ - private void setToWait(Thread owner, ISchedulingRule lock, bool suspend) { + private void setToWait(JThread owner, ISchedulingRule lock, bool suspend) { bool needTransfer = false; /** * if we are adding an entry where a thread is waiting on a scheduling rule, @@ -706,7 +706,7 @@ sb.append("\n"); for (int i = 0; i < graph.length; i++) { sb.append(" "); - sb.append( (cast(Thread) lockThreads.get(i)).name() ); + sb.append( (cast(JThread) lockThreads.get(i)).getName() ); sb.append(" : "); for (int j = 0; j < graph[i].length; j++) { sb.append(" ");