private static int ThreadInterrupt(VThread thread) { if (thread.state == ThreadState.THREAD_RUNNING) { WaitForThreadSuspend(thread); if (thread.isMain) { /* * Shutdown all running threads * and de-allocate al allocated * memory. If we do not call join() * to wait for all other threads * regardless of what they are doing, we * stop them. */ ScorpionVM.Shutdown(true); } else { try { thread.handle.Interrupt(); } catch (Exception) { return(-1); } } } return(-1); }
public static void UnlinkThread(int id) { Globals.ThreadMonitor.Lock(); if (Globals.Threads == null || GetThread(id) == null) { Globals.ThreadMonitor.UnLock(); return; } VThread[] lst; if (Globals.Threads.Length == 1) { Globals.Threads = null; Globals.ThreadMonitor.UnLock(); return; } else { lst = new VThread[Globals.Threads.Length - 1]; } int iter = 0; for (int i = 0; i < Globals.Threads.Length; i++) { if (Globals.Threads[i].Id != id) { lst[iter++] = Globals.Threads[i]; } } Globals.Threads = null; Globals.Threads = lst; Globals.ThreadMonitor.UnLock(); }
public static int Start(int id) { VThread thread = GetThread(id); if (thread == null) { return(1); } if (thread.ThreadActive()) { Globals.Logger.Commit("Thread", "Illegal thread state. Thread is already active!", Log.ERROR); return(1); } if (thread.handle != null) { thread.handle = new Thread( BytecodeInterpreter.InterpreterThreadStart); } try { thread.handle.Start(); return(0); } catch (Exception) { Globals.Logger.Commit("Thread", "Thread failed to start/restart.", Log.ERROR); return(1); } }
public static void ChangeState(VThread thread, ThreadState newState) { if (thread == null) { thread = self; } Globals.Logger.Commit("Thread", "threadid=" + thread.Id + ": (state " + thread.state + " -> " + newState, Log.INFO); thread.state = newState; }
private static int ThreadJoin(VThread thread) { if (thread.state == ThreadState.THREAD_RUNNING) { try { thread.handle.Join(); } catch (Exception) { return(-1); } } return(-1); }
public bool Lock(int spins = LOCK_INDEFINITE) { if (Globals.Threads == null || VThread.CurrentThread() == null) { return(false); } VThread self = VThread.CurrentThread(); if (threadId == self.Id || Globals.Threads.Length == 1) { return(true); } wait: try { WaitForLock(spins); if (!Lockable()) { if (spins == LOCK_INDEFINITE) { goto wait; } else { return(false); } } threadId = self.Id; state = MONITOR_BUSY; return(true); } catch (Exception) { if (spins == LOCK_INDEFINITE) { goto wait; } else { return(false); } } }
public static void LinkThread(VThread thread) { Globals.ThreadMonitor.Lock(); int listCount = Globals.Threads == null ? 1 : Globals.Threads.Length + 1; int iter = 0; VThread[] lst = new VThread[listCount]; for (int i = 0; i < Globals.Threads.Length; i++) { lst[iter++] = Globals.Threads[i]; } Globals.Threads = null; lst[iter] = thread; Globals.Threads = lst; Globals.ThreadMonitor.UnLock(); }
public static int Join(int id) { if (id == self.Id) { Globals.Logger.Commit("Thread", "threadid=" + self.Id + ": attempting to join its-self.", Log.DEBUG); return(1); } VThread thread = GetThread(id); if (thread == null) { Globals.Logger.Commit("Thread", "threadid=" + id + ": does not exist.", Log.DEBUG); return(1); } return(ThreadJoin(thread)); }
private static void WaitForThreadSuspend(VThread thread) { const int sMaxRetries = 10000000; const int sMaxSpinCount = 25; int spinCount = 0; int retryCount = 0; SuspendThread(thread); while (thread.state == ThreadState.THREAD_RUNNING && !thread.isSuspended) { if (retryCount++ == sMaxRetries) { if (++spinCount >= sMaxSpinCount) { Globals.Logger.Commit("Thread", "threadid=" + self.Id + ": stuck on thread threadid=" + thread.Id + " giving up.", Log.INFO); return; } } } }
public static void SuspendThread(VThread thread) { thread.SuspendPending = true; }
public static void UnsuspendThread(VThread thread) { thread.isSuspended = false; }