/**
* Author: Georg Hofferek <georg.hofferek@iaik.tugraz.at>
*/
package at.iaik.suraq.util;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import at.iaik.suraq.main.SuraqOptions;
/**
* @author Georg Hofferek <georg.hofferek@iaik.tugraz.at>
*
*/
public class SplitterBookkeeper implements Runnable {
private List<UncolorableLeafSplitter> splitters;
private List<Long> threadIds;
private boolean killed = false;
private final Timer wallclockTimer;
private final int sleepTime = SuraqOptions.getInstance()
.getSplitterBookkeeperSleepTime();
/**
*
* Constructs a new <code>SplitterBookkeeper</code>. <code>splitters</code>
* and <code>threadIds</code> must be in the same order!!
*
* @param splitters
* @param threadIds
*/
public SplitterBookkeeper(
Collection<? extends UncolorableLeafSplitter> splitters,
Collection<Long> threadIds, Timer timer) {
assert (splitters.size() == threadIds.size());
this.splitters = new ArrayList<UncolorableLeafSplitter>(splitters);
this.threadIds = new ArrayList<Long>(threadIds);
this.wallclockTimer = timer;
}
/**
*
* Constructs a new <code>SplitterBookkeeper</code>. <code>splitters</code>
* and <code>threadIds</code> must be in the same order!!
*
* @param splitters
* @param threadIds
*/
public SplitterBookkeeper(UncolorableLeafSplitter[] splitters,
Collection<Long> threadIds, Timer timer) {
assert (splitters.length == threadIds.size());
this.threadIds = new ArrayList<Long>(threadIds);
this.splitters = new ArrayList<UncolorableLeafSplitter>(
splitters.length);
for (UncolorableLeafSplitter splitter : splitters)
this.splitters.add(splitter);
this.wallclockTimer = timer;
}
/**
* Tell this bookkeeper to terminate.
*/
public void kill() {
killed = true;
}
/**
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
do {
try {
Thread.sleep(sleepTime * 1000);
} catch (InterruptedException exc) {
System.out.println("Bookkeeper got interrupted!");
}
int done = 0;
int remaining = 0;
int clausesStronger = 0;
int literalsFewer = 0;
for (UncolorableLeafSplitter splitter : splitters) {
done += splitter.getDone();
remaining += splitter.getRemaining();
clausesStronger += splitter.getNumStrongerClauses();
literalsFewer += splitter.getTotalLiteralsFewer();
}
ThreadMXBean tmxb = ManagementFactory.getThreadMXBean();
boolean cpuTime = tmxb.isThreadCpuTimeSupported();
boolean waitTime = tmxb.isThreadContentionMonitoringSupported();
long totalCpuTime = 0;
double parallelizationRatio = 0;
if (cpuTime) {
for (int count = 0; count < threadIds.size(); count++) {
long threadId = threadIds.get(count);
long increment = tmxb.getThreadCpuTime(threadId);
increment = increment >= 0 ? increment : splitters.get(
count).getTotalCpuTime();
assert (increment >= 0);
totalCpuTime += increment;
}
parallelizationRatio = totalCpuTime
/ (wallclockTimer.getTotalTimeMillis() * 1000d * 1000d);
}
long totalWaitTime = 0;
if (waitTime) {
for (int count = 0; count < threadIds.size(); count++) {
long threadId = threadIds.get(count);
long increment = tmxb.getThreadInfo(threadId) == null ? splitters
.get(count).getTotalWaitTime() : tmxb
.getThreadInfo(threadId).getBlockedTime();
assert (increment >= 0);
totalWaitTime += increment;
}
}
synchronized (Util.class) {
Util.printToSystemOutWithWallClockTimePrefix(" "
+ "OVERALL: " + ": " + literalsFewer
+ " literals saved so far in " + clausesStronger
+ " clauses.");
Util.printToSystemOutWithWallClockTimePrefix(" "
+ "OVERALL " + ": " + "Done " + done + ". ("
+ remaining + " remaining.)");
if (cpuTime) {
Util.printToSystemOutWithWallClockTimePrefix(" "
+ "OVERALL: Total CPU time (ns): "
+ Util.veryLargeNumberFormatter
.format(totalCpuTime));
Util.printToSystemOutWithWallClockTimePrefix(" "
+ "OVERALL: Parallelization ratio: "
+ parallelizationRatio);
}
if (waitTime) {
Util.printToSystemOutWithWallClockTimePrefix(" "
+ "OVERALL: Wait time (ms): "
+ Util.largeNumberFormatter.format(totalWaitTime));
}
}
} while (!killed);
}
}