package zeta;
import java.io.File;
public class ZetaCalc implements Runnable {
public ZetaCalc() {
ZetaInfo.init(properties);
try {
task = TaskManager.getTask(properties.get("task", "zeta-zeros"));
} catch (Exception e) {
ZetaInfo.handle(e);
return;
}
checkExit();
workUnitManager = task.getWorkUnitManager();
try {
Runtime.getRuntime().addShutdownHook(new Thread() { public void run() {
int wait = task.stop();
try {
Thread.sleep(wait);
} catch (InterruptedException ex) {
}
}
});
} catch (Throwable t) {
ZetaInfo.handle(t);
}
String standardOutput = properties.get("standard.output");
if (standardOutput != null && standardOutput.equals("false")) {
task.setLog(false);
}
String resources = properties.get("resources");
if (resources != null) {
task.setResources(properties.get("resources", 0));
}
}
public void run() {
if (properties.get("exit.time", 0) > 0) {
final long stopTimeMillis = System.currentTimeMillis() + properties.get("exit.time", 0)*1000;
Thread thread = new Thread() {
public void run() {
while (stopTimeMillis > System.currentTimeMillis()) {
try {
Thread.sleep(stopTimeMillis-System.currentTimeMillis());
} catch (InterruptedException ex) {
}
}
System.exit(1);
}
};
thread.start();
}
File file = new File("nohup.out");
file.delete();
String activeAt = properties.get("active.at");
if (activeAt != null && activeAt.length() > 0 && "zeta-zeros".equals(task.getTaskname()) && "0131 0132 0133 0134 0135 0136 0137 0138".indexOf(task.getVersion()) >= 0) { ZetaInfo.write("Warning: Workload scheduling is not supported by the library (" + task.getVersion() + ").");
activeAt = null;
}
final WorkloadScheduler workloadScheduler = new WorkloadScheduler(activeAt);
if (!workloadScheduler.isAlwaysActive()) {
Thread thread = new Thread() {
public void run() {
while (true) {
try {
long millis = workloadScheduler.getTimeMillisToNextTimeframe();
if (computationIsActive > 0) {
if (workloadScheduler.isActive()) {
StringBuffer buffer = new StringBuffer(150);
buffer.append("Continue computing");
appendTimeInfo(millis, buffer);
ZetaInfo.write(buffer.toString());
} else {
ZetaInfo.write("The workload scheduler stops the computation.");
task.stop();
}
}
Thread.sleep(millis);
} catch (InterruptedException ex) {
} catch (Throwable t) { ZetaInfo.handle(t);
try {
Thread.sleep(60000); } catch (InterruptedException ex) {
}
}
}
}
};
thread.start();
}
final int processors = properties.get("processors", 1);
for (int i = 0; i < processors || i == 0; ++i) {
Thread thread = new Thread() {
public void run() {
WorkUnit workUnit = null;
while (true) {
long millis = workloadScheduler.getTimeMillisToNextTimeframe();
if (workloadScheduler.isActive()) {
if (this == outputThread) {
StringBuffer buffer = new StringBuffer(150);
if (processors == 1) {
buffer.append("Computing on 1 processor");
} else {
buffer.append("Computing on ");
buffer.append(processors);
buffer.append(" processors");
}
if (!workloadScheduler.isAlwaysActive()) {
appendTimeInfo(millis, buffer);
}
ZetaInfo.write(buffer.toString());
}
if (workUnit == null) {
workUnit = workUnitManager.getWorkUnit();
}
++computationIsActive;
if (workUnit != null && task.start(workUnit) == 0) {
--computationIsActive;
checkExit();
workUnitManager.submit(workUnit, (processors == 0), true);
workUnit = null;
} else {
--computationIsActive;
checkExit();
workUnitManager.submit(null, (processors == 0), true); try {
Thread.sleep(60000); } catch (InterruptedException ex) {
}
checkExit();
}
} else {
long stopTimeMillis = System.currentTimeMillis() + millis;
if (this == outputThread) {
StringBuffer buffer = new StringBuffer(150);
buffer.append("The computation paused");
appendTimeInfo(millis, buffer);
ZetaInfo.write(buffer.toString());
}
if (exitFile != null) {
while (stopTimeMillis > System.currentTimeMillis()) {
try {
Thread.sleep(Math.min(60000, stopTimeMillis-System.currentTimeMillis()));
} catch (InterruptedException ex) {
}
checkExit();
}
} else {
try {
Thread.sleep(millis);
} catch (InterruptedException ex) {
}
}
}
}
}
};
if (i == 0) {
outputThread = thread;
}
thread.start();
}
}
private void appendTimeInfo(long millis, StringBuffer buffer) {
long t = millis/60000;
if (t == 60) {
buffer.append(" at least 1 hour.");
} else if (t > 60) {
if (t%60 == 0) {
buffer.append(" at least ");
buffer.append(t/60);
buffer.append(" hours.");
} else if (t < 120) {
buffer.append(" at least 1 hour and ");
buffer.append(t%60);
buffer.append(" minutes.");
} else {
buffer.append(" at least ");
buffer.append(t/60);
buffer.append(" hours and ");
buffer.append(t%60);
buffer.append(" minutes.");
}
} else if (t > 1) {
buffer.append(" at least ");
buffer.append(t);
buffer.append(" minutes.");
} else {
buffer.append(" about 1 minute.");
}
}
private void checkExit() {
if (exitFile != null && exitFile.exists()) {
exitFile.delete();
task.stop();
System.exit(1);
}
}
private File getExitFile() {
String s = properties.get("exit.filename");
return (s == null || s.length() == 0)? null : new File(s);
}
private ZetaProperties properties = new ZetaProperties();
private Task task;
private WorkUnitManager workUnitManager;
private Thread outputThread = null;
private int computationIsActive = 0;
private File exitFile = getExitFile();
}