/** * Stops all threads created by <I>all</I> <TT>CSPParallel</TT> and {@link ProcessManager} objects. No new threads can be * created until the <TT>resetDestroy</TT> method gets called. */ public static void destroy() { lock (allParThreads) { if (!destroyCalled) { Console.WriteLine("*** jcsp.lang.CSPParallel: stopping " + allParThreads.Count + " threads"); //allParThreads.Size() + " threads"); for (var i = allParThreads.GetEnumerator(); i.MoveNext();) { /*final*/ ParThread t = i.Current.Value; try { t.Interrupt(); } catch (SecurityException e) { Console.WriteLine("*** jcsp.lang.CSPParallel: couldn't stop thread " + t + " - security exception"); } } destroyCalled = true; } } }
/** * Removes the thread object from the <code>allParThreads</code> collection. */ public static void removeFromAllParThreads(/*final*/ ParThread oldThread) { lock (allParThreads) { allParThreads.TryRemove(_byte, out oldThread); } }
/** * Adds the thread object to the <code>allParThreads</code> collection. This should be called by any infrastructure threads when they start. * * @param newThread the thread to be added to the collection. */ public static void addToAllParThreads(/*final*/ ParThread newThread) //throws InterruptedException { try { lock (allParThreads) { if (destroyCalled) { throw new ThreadInterruptedException("CSPParallel.destroy() has been called"); } //allParThreads.add(newThread); allParThreads.TryAdd(_byte, newThread); } } catch (ThreadInterruptedException ex) { Console.WriteLine("Thread interrupted " + ex); } }
/** * Run the parallel composition of the processes registered with this * <TT>CSPParallel</TT> object. It terminates when, and only when, all its component * processes terminate. * </P> * <P><I>Implementation note: In its first </I>run<I>, only * (numProcesses - 1) Threads are created to run the processes -- * the last process is executed in the invoking Thread. * Sunsequent </I>run<I>s reuse these Threads (so the overhead * of thread creation happens only once).</I></P> */ public void run() { if (nProcesses > 0) { IamCSProcess myProcess; //int currentPriority = 0; ThreadPriority currentPriority = 0; int maxPriority = 0; if (priority) { Thread thread = Thread.CurrentThread; currentPriority = thread.Priority; maxPriority = Math.Min( (byte)currentPriority + nProcesses - 1, Math.Min((byte)ThreadPriority.Highest, //thread.getThreadGroup().getMaxPriority()) (byte)thread.Priority) ); } lock (sync) { //Debug.WriteLine("Resettin g barrier in CSPParallel" , "KAROL"); barrier.reset(nProcesses); myProcess = processes[nProcesses - 1]; if (processesChanged) { if (nThreads < nProcesses - 1) { if (parThreads.Length < nProcesses - 1) { /*final*/ ParThread[] tmp = parThreads; parThreads = new ParThread[processes.Length]; Array.Copy(tmp, 0, parThreads, 0, nThreads); } for (int i = 0; i < nThreads; i++) { //Debug.WriteLine("Resetting processes and barrier in CSPParallel", "KAROL"); parThreads[i].reset(processes[i], barrier); if (priority) { //parThreads[i].SetPriority(Math.max( // currentPriority, maxPriority - i)); parThreads[i].SetPriority(Math.Max((byte)currentPriority, maxPriority - i)); } parThreads[i].release(); } for (int i = nThreads; i < nProcesses - 1; i++) { //Debug.WriteLine("Creating thread and barrier in CSPParallel", "KAROL"); parThreads[i] = new ParThread(processes[i], barrier); if (priority) { parThreads[i].SetPriority(Math.Max( (byte)currentPriority, maxPriority - i)); } parThreads[i].Start(); } nThreads = nProcesses - 1; } else { for (int i = 0; i < nProcesses - 1; i++) { //Debug.WriteLine("Resetting processes and barrier in CSPParallel", "KAROL"); parThreads[i].reset(processes[i], barrier); if (priority) { parThreads[i].SetPriority(Math.Max( (byte)currentPriority, maxPriority - i)); } parThreads[i].release(); } } processesChanged = false; } else { for (int i = 0; i < nProcesses - 1; i++) { if (priority) { parThreads[i].SetPriority(Math.Max((byte)currentPriority, maxPriority - i)); } parThreads[i].release(); } } } try { myProcess.run(); } catch (ProcessInterruptedException e) { // If this was raised then we must propagate the interrupt signal to other processes lock (sync) { for (int i = 0; i < nThreads; i++) { try { parThreads[i].Interrupt(); } catch (Exception t) { Console.WriteLine( "*** jcsp.lang.Parallel: couldn't stop thread " + t + " - security exception"); } } } } catch (Exception e) { uncaughtException("jcsp.lang.Parallel", e); } //Debug.WriteLine("Synchronizing barrier in CSPParallel","KAROL"); barrier.sync(); } }
/** * @param <TT>process</TT> the {@link IamCSProcess} to be executed by this ProcessManager */ public ProcessManager(IamCSProcess process) { this.process = process; thread = new ParThread(this.process, new CSPBarrier()); }