2023-11-19 01:53:56 +03:00
|
|
|
package Repository.TestingSystem.Common.ThreadsPlanner;
|
2023-09-26 22:57:18 +03:00
|
|
|
import Common.Global;
|
|
|
|
|
import Common.Utils.InterruptThread;
|
|
|
|
|
|
|
|
|
|
import java.util.LinkedHashMap;
|
|
|
|
|
import java.util.Vector;
|
|
|
|
|
public abstract class ThreadsPlanner {
|
|
|
|
|
//-->
|
2023-09-30 18:19:31 +03:00
|
|
|
protected Thread interruptThread = new InterruptThread(5000, () -> {
|
|
|
|
|
try {
|
|
|
|
|
Interrupt();
|
|
|
|
|
} catch (Exception exception) {
|
|
|
|
|
Global.Log.PrintException(exception);
|
|
|
|
|
}
|
2023-09-26 22:57:18 +03:00
|
|
|
System.exit(0);
|
|
|
|
|
return null;
|
|
|
|
|
});
|
|
|
|
|
protected int maxKernels;
|
|
|
|
|
protected int kernels;
|
|
|
|
|
//---
|
|
|
|
|
protected int threadMaxId = 0;
|
|
|
|
|
protected int wait_ms;
|
|
|
|
|
protected LinkedHashMap<Integer, Thread> threads = new LinkedHashMap<>();
|
|
|
|
|
protected Vector<Integer> activeThreads = new Vector<>();
|
|
|
|
|
protected Vector<Integer> waitingThreads = new Vector<>();
|
|
|
|
|
//--
|
2023-10-14 02:30:31 +03:00
|
|
|
public ThreadsPlanner(int wait_ms_in) {
|
2023-09-26 22:57:18 +03:00
|
|
|
wait_ms = wait_ms_in;
|
2023-10-14 02:30:31 +03:00
|
|
|
}
|
2023-11-14 16:19:31 +03:00
|
|
|
public void setMaxKernels(int maxKernels_in) {
|
2023-09-26 22:57:18 +03:00
|
|
|
maxKernels = maxKernels_in;
|
|
|
|
|
kernels = maxKernels;
|
|
|
|
|
}
|
2023-11-14 16:19:31 +03:00
|
|
|
public String printThread(Integer id) {
|
|
|
|
|
return "thread id = "+id;
|
|
|
|
|
}
|
|
|
|
|
public String getThreadsSummary() {
|
|
|
|
|
Vector<String> lines = new Vector<>();
|
|
|
|
|
lines.add("Planner summary:");
|
|
|
|
|
lines.add("Waiting: " + waitingThreads.size());
|
|
|
|
|
lines.add("Running: " + activeThreads.size());
|
|
|
|
|
for (Integer id : activeThreads) {
|
|
|
|
|
lines.add(printThread(id));
|
|
|
|
|
}
|
|
|
|
|
lines.add("");
|
|
|
|
|
return String.join("\n", lines);
|
|
|
|
|
}
|
2023-09-26 22:57:18 +03:00
|
|
|
//--
|
|
|
|
|
public void Start() {
|
|
|
|
|
Global.Log.Print("Planner started");
|
|
|
|
|
try {
|
|
|
|
|
//--
|
|
|
|
|
while (!waitingThreads.isEmpty() || !activeThreads.isEmpty()) {
|
2023-11-14 16:19:31 +03:00
|
|
|
Global.Log.Print(getThreadsSummary());
|
2023-09-26 22:57:18 +03:00
|
|
|
checkActiveThreads();
|
|
|
|
|
tryStartThreads();
|
|
|
|
|
Thread.sleep(wait_ms);
|
|
|
|
|
}
|
|
|
|
|
//--
|
|
|
|
|
} catch (Exception exception) {
|
|
|
|
|
Global.Log.PrintException(exception);
|
2023-11-14 16:19:31 +03:00
|
|
|
} finally {
|
2023-09-30 22:30:41 +03:00
|
|
|
Global.Log.Print("Planner finished");
|
|
|
|
|
finalize();
|
|
|
|
|
}
|
2023-09-26 22:57:18 +03:00
|
|
|
}
|
2023-09-30 18:19:31 +03:00
|
|
|
public void Interrupt() throws Exception {
|
|
|
|
|
}
|
2023-09-26 22:57:18 +03:00
|
|
|
protected void checkActiveThreads() throws Exception {
|
|
|
|
|
Vector<Integer> toExclude = new Vector<>();
|
|
|
|
|
//--
|
|
|
|
|
for (int i : activeThreads) {
|
|
|
|
|
Thread thread = threads.get(i);
|
|
|
|
|
if (!thread.isAlive()) {
|
|
|
|
|
toExclude.add(i);
|
|
|
|
|
kernels++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
activeThreads.removeAll(toExclude);
|
|
|
|
|
//--
|
|
|
|
|
}
|
|
|
|
|
protected void tryStartThreads() throws Exception {
|
|
|
|
|
Vector<Integer> toExclude = new Vector<>();
|
|
|
|
|
//-
|
|
|
|
|
for (int i : waitingThreads) {
|
|
|
|
|
if (kernels > 0) {
|
|
|
|
|
Thread thread = threads.get(i);
|
|
|
|
|
thread.start();
|
|
|
|
|
activeThreads.add(i);
|
|
|
|
|
kernels--;
|
|
|
|
|
toExclude.add(i);
|
|
|
|
|
} else break;
|
|
|
|
|
}
|
|
|
|
|
waitingThreads.removeAll(toExclude);
|
|
|
|
|
}
|
|
|
|
|
protected void finalize() {
|
|
|
|
|
}
|
2023-11-14 16:19:31 +03:00
|
|
|
protected void addThread(Thread thread) {
|
2023-09-26 22:57:18 +03:00
|
|
|
threads.put(threadMaxId, thread);
|
|
|
|
|
waitingThreads.add(threadMaxId);
|
|
|
|
|
threadMaxId++;
|
|
|
|
|
}
|
|
|
|
|
}
|