improved planner

This commit is contained in:
ALEXks
2023-12-10 16:20:10 +03:00
parent 127aec5a1d
commit 9bd5dc03f9
14 changed files with 881 additions and 845 deletions

View File

@@ -1,37 +1,37 @@
#pragma once #pragma once
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <vector> #include <vector>
template <class T> template <class T>
class Array { class Array {
private: private:
std::vector<T*> elements; std::vector<T*> elements;
public: public:
Array() { } Array() { }
virtual ~Array() { virtual ~Array() {
for (auto& elem : elements) for (auto& elem : elements)
delete elem; delete elem;
elements.clear(); elements.clear();
} }
void add(T* new_line) { void add(T* new_line) {
elements.push_back(new_line); elements.push_back(new_line);
} }
long getLength() const { long getLength() const {
return (long)elements.size(); return (long)elements.size();
} }
T* get(long i) { T* get(long i) {
return elements[i]; return elements[i];
} }
const std::vector<T*>& getElements() const { const std::vector<T*>& getElements() const {
return elements; return elements;
} }
}; };

View File

@@ -1,24 +1,24 @@
#pragma once #pragma once
#include "Supervisor.h" #include "Supervisor.h"
#include "CompilationTask.h" #include "CompilationTask.h"
class CompilationSupervisor : public Supervisor<CompilationTask> { class CompilationSupervisor : public Supervisor<CompilationTask> {
public: public:
CompilationSupervisor() { CompilationSupervisor() {
this->init("compilationTasks", 4); this->init("compilationTasks", 4);
} }
CompilationTask* getTaskById(long task_id) { CompilationTask* getTaskById(long task_id) {
for (long i = 0; i < getLength(); ++i) { for (long i = 0; i < getLength(); ++i) {
CompilationTask* task = get(i); CompilationTask* task = get(i);
if (task->getId() == task_id) if (task->getId() == task_id)
return task; return task;
} }
return NULL; return NULL;
} }
String getStatePrefix() override { String getStatePrefix() override {
return String("Compilation"); return String("Compilation");
} }
}; };

View File

@@ -1,51 +1,52 @@
#pragma once #pragma once
#include "Task.h" #include "Task.h"
#include "Text.h" #include "Text.h"
class CompilationTask : public Task { class CompilationTask : public Task {
String test_id; String test_id;
String makefile_text; String makefile_text;
public: public:
void setTestId(String* test_id_in) { void setTestId(String* test_id_in) {
test_id = String(test_id_in->getCharArray()); test_id = String(test_id_in->getCharArray());
} }
void setMakefileText(String* makefile_text_in) {
makefile_text = String(makefile_text_in->getCharArray(), '|'); void setMakefileText(String* makefile_text_in) {
} makefile_text = String(makefile_text_in->getCharArray(), '|');
virtual void print() const { }
printf("id=%ld; maxtime=%d; test_id=%s\n", id, maxtime,
test_id.getCharArray()); virtual void print() const {
printf("makefile_text=%s\n", makefile_text.getCharArray()); printf("id=%ld; maxtime=%d; test_id=%s\n", id, maxtime, test_id.getCharArray());
} printf("makefile_text=%s\n", makefile_text.getCharArray());
}
CompilationTask(Text* lines, int offset) :Task(lines, offset) {
setTestId(lines->get(offset + 2)); CompilationTask(Text* lines, int offset) :Task(lines, offset) {
setMakefileText(lines->get(offset + 3)); setTestId(lines->get(offset + 2));
setState(Waiting); setMakefileText(lines->get(offset + 3));
kernels = 1; setState(Waiting);
} kernels = 1;
}
virtual void prepareWorkspace() {
String makeFilePath = String(id) + "/Makefile"; virtual void prepareWorkspace() {
File makeFileFile = File(makeFilePath, this->makefile_text); String makeFilePath = String(id) + "/Makefile";
String tests = userWorkspace + "/projects"; File makeFileFile = File(makeFilePath, this->makefile_text);
String testPath = tests + "/" + test_id; String tests = userWorkspace + "/projects";
Utils::CopyDirectory(testPath, workspace); String testPath = tests + "/" + test_id;
} Utils::CopyDirectory(testPath, workspace);
virtual String getLaunchScriptText() { }
String modules = userWorkspace + "/modules"; virtual String getLaunchScriptText() {
String starterCall = modules + "/starter"; String modules = userWorkspace + "/modules";
String launcherCall = modules + "/launcher"; String starterCall = modules + "/starter";
return String::DQuotes(starterCall) + " " + String launcherCall = modules + "/launcher";
String::DQuotes(launcherCall) + " " + return String::DQuotes(starterCall) + " " +
String(maxtime) + " " + String::DQuotes(launcherCall) + " " +
String::DQuotes("") + " " + String(maxtime) + " " +
"make -j -f Makefile"; String::DQuotes("") + " " +
} "make -j -f Makefile";
virtual void analyseResults() { }
Task::analyseResults(); virtual void analyseResults() {
String binary = workspace + "/0"; Task::analyseResults();
state = Utils::Exists(binary) ? Done : DoneWithErrors; String binary = workspace + "/0";
} state = Utils::Exists(binary) ? Done : DoneWithErrors;
}
}; };

View File

@@ -1,70 +1,70 @@
#pragma once #pragma once
#include "String.h" #include "String.h"
#include "Text.h" #include "Text.h"
class File { class File {
FILE* ptr; FILE* ptr;
public: public:
File(String* name) { File(String* name) {
ptr = fopen(name->getCharArray(), "r"); ptr = fopen(name->getCharArray(), "r");
} }
File(const char* name) { File(const char* name) {
ptr = fopen(name, "r"); ptr = fopen(name, "r");
} }
File(const String& name, const String& text) { File(const String& name, const String& text) {
ptr = fopen(name.getCharArray(), "w"); ptr = fopen(name.getCharArray(), "w");
fprintf(ptr, "%s", text.getCharArray()); fprintf(ptr, "%s", text.getCharArray());
} }
~File() { ~File() {
Close(); Close();
} }
void Close() { void Close() {
if (ptr != NULL) { if (ptr != NULL) {
fclose(ptr); fclose(ptr);
ptr = NULL; ptr = NULL;
} }
} }
Text* readLines() { Text* readLines() {
Text* lines = new Text(); Text* lines = new Text();
int c; int c;
String* line = NULL; String* line = NULL;
bool lineStarted = false; bool lineStarted = false;
do { do {
c = fgetc(ptr); c = fgetc(ptr);
if (lineStarted) { if (lineStarted) {
switch (c) { switch (c) {
case '\r': case '\r':
break; break;
case '\n': case '\n':
case EOF: case EOF:
lines->add(line); lines->add(line);
line = NULL; line = NULL;
lineStarted = false; lineStarted = false;
break; break;
default: default:
line->addChar((char)c); line->addChar((char)c);
break; break;
} }
} }
else { else {
switch (c) { switch (c) {
case '\r': case '\r':
break; break;
case '\n': case '\n':
line = new String(); line = new String();
lines->add(line); lines->add(line);
line = NULL; line = NULL;
break; break;
case EOF: case EOF:
break; break;
default: default:
line = new String(); line = new String();
line->addChar((char)c); line->addChar((char)c);
lineStarted = true; lineStarted = true;
break; break;
} }
} }
} while (c != EOF); } while (c != EOF);
return lines; return lines;
} }
}; };

View File

@@ -1,10 +1,10 @@
#pragma once #pragma once
#include "String.h" #include "String.h"
String userWorkspace; String userWorkspace;
String packageWorkspace; String packageWorkspace;
int maxKernels; int maxKernels;
int busyKernels; int busyKernels;
int freeKernels; int freeKernels;
String dvm_drv; String dvm_drv;

View File

@@ -1,134 +1,145 @@
#define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS
using namespace std; using namespace std;
#if __cplusplus >= 201703L #if __cplusplus >= 201703L
#include <filesystem> #include <filesystem>
#else #else
#include <unistd.h> #include <unistd.h>
#endif #endif
#include "CompilationSupervisor.h" #include "CompilationSupervisor.h"
#include "RunSupervisor.h" #include "RunSupervisor.h"
#include "Global.h" #include "Global.h"
#include <signal.h> #include <signal.h>
//https://ru.wikipedia.org/wiki/%D0%A1%D0%B8%D0%B3%D0%BD%D0%B0%D0%BB_(Unix) //https://ru.wikipedia.org/wiki/%D0%A1%D0%B8%D0%B3%D0%BD%D0%B0%D0%BB_(Unix)
void hdl(int sig) void hdl(int sig)
{ {
String file_name = "GOT_SIGNAL_AT_"+ String(Utils::getAbsoluteTime()); String file_name = "GOT_SIGNAL_AT_"+ String(Utils::getAbsoluteTime());
FILE * res = fopen(file_name.getCharArray(),"w"); FILE * res = fopen(file_name.getCharArray(),"w");
fprintf(res,"%d\n", sig); fprintf(res, "%d\n", sig);
fclose(res); fclose(res);
} }
void set_handlers() { void set_handlers() {
#ifndef _WIN32 #ifndef _WIN32
struct sigaction act; struct sigaction act;
memset(&act, 0, sizeof(act)); memset(&act, 0, sizeof(act));
act.sa_handler = hdl; act.sa_handler = hdl;
sigset_t set; sigset_t set;
sigemptyset(&set); sigemptyset(&set);
//--- //---
sigaddset(&set, SIGABRT); sigaddset(&set, SIGABRT);
sigaddset(&set, SIGALRM); sigaddset(&set, SIGALRM);
sigaddset(&set, SIGBUS); sigaddset(&set, SIGBUS);
sigaddset(&set, SIGVTALRM); sigaddset(&set, SIGVTALRM);
sigaddset(&set, SIGFPE); sigaddset(&set, SIGFPE);
sigaddset(&set, SIGHUP); sigaddset(&set, SIGHUP);
sigaddset(&set, SIGILL); sigaddset(&set, SIGILL);
sigaddset(&set, SIGINT); sigaddset(&set, SIGINT);
sigaddset(&set, SIGPIPE); sigaddset(&set, SIGPIPE);
sigaddset(&set, SIGQUIT); sigaddset(&set, SIGQUIT);
sigaddset(&set, SIGSEGV); sigaddset(&set, SIGSEGV);
sigaddset(&set, SIGTERM); sigaddset(&set, SIGTERM);
sigaddset(&set, SIGTSTP); sigaddset(&set, SIGTSTP);
sigaddset(&set, SIGTTIN); sigaddset(&set, SIGTTIN);
sigaddset(&set, SIGTTOU); sigaddset(&set, SIGTTOU);
sigaddset(&set, SIGUSR1); sigaddset(&set, SIGUSR1);
sigaddset(&set, SIGUSR2); sigaddset(&set, SIGUSR2);
sigaddset(&set, SIGPOLL); sigaddset(&set, SIGPOLL);
sigaddset(&set, SIGPROF); sigaddset(&set, SIGPROF);
sigaddset(&set, SIGSYS); sigaddset(&set, SIGSYS);
sigaddset(&set, SIGTRAP); sigaddset(&set, SIGTRAP);
//sigaddset(&set, SIGURG); //sigaddset(&set, SIGURG);
//sigaddset(&set, SIGCHLD); //sigaddset(&set, SIGCHLD);
//sigaddset(&set, SIGCONT); //sigaddset(&set, SIGCONT);
sigaddset(&set, SIGVTALRM); sigaddset(&set, SIGVTALRM);
sigaddset(&set, SIGXCPU); sigaddset(&set, SIGXCPU);
sigaddset(&set, SIGXFSZ); sigaddset(&set, SIGXFSZ);
//--- //---
act.sa_mask = set; act.sa_mask = set;
//--- //---
sigaction(SIGABRT, &act, 0); sigaction(SIGABRT, &act, 0);
sigaction(SIGALRM, &act, 0); sigaction(SIGALRM, &act, 0);
sigaction(SIGBUS, &act, 0); sigaction(SIGBUS, &act, 0);
sigaction(SIGVTALRM, &act, 0); sigaction(SIGVTALRM, &act, 0);
sigaction(SIGFPE, &act, 0); sigaction(SIGFPE, &act, 0);
sigaction(SIGHUP, &act, 0); sigaction(SIGHUP, &act, 0);
sigaction(SIGILL, &act, 0); sigaction(SIGILL, &act, 0);
sigaction(SIGINT, &act, 0); sigaction(SIGINT, &act, 0);
sigaction(SIGPIPE, &act, 0); sigaction(SIGPIPE, &act, 0);
sigaction(SIGQUIT, &act, 0); sigaction(SIGQUIT, &act, 0);
sigaction(SIGSEGV, &act, 0); sigaction(SIGSEGV, &act, 0);
sigaction(SIGTERM, &act, 0); sigaction(SIGTERM, &act, 0);
sigaction(SIGTSTP, &act, 0); sigaction(SIGTSTP, &act, 0);
sigaction(SIGTTIN, &act, 0); sigaction(SIGTTIN, &act, 0);
sigaction(SIGTTOU, &act, 0); sigaction(SIGTTOU, &act, 0);
sigaction(SIGUSR1, &act, 0); sigaction(SIGUSR1, &act, 0);
sigaction(SIGUSR2, &act, 0); sigaction(SIGUSR2, &act, 0);
sigaction(SIGPOLL, &act, 0); sigaction(SIGPOLL, &act, 0);
sigaction(SIGPROF, &act, 0); sigaction(SIGPROF, &act, 0);
sigaction(SIGSYS, &act, 0); sigaction(SIGSYS, &act, 0);
sigaction(SIGTRAP, &act, 0); sigaction(SIGTRAP, &act, 0);
sigaction(SIGVTALRM, &act, 0); sigaction(SIGVTALRM, &act, 0);
sigaction(SIGXCPU, &act, 0); sigaction(SIGXCPU, &act, 0);
sigaction(SIGXFSZ, &act, 0); sigaction(SIGXFSZ, &act, 0);
#endif #endif
} }
int main(int argc, char ** argv) int main(int argc, char ** argv)
{ {
//+ //+
set_handlers(); set_handlers();
//- //-
userWorkspace = String(argv[1]); userWorkspace = String(argv[1]);
packageWorkspace = String(argv[2]); packageWorkspace = String(argv[2]);
maxKernels = atoi(argv[3]); maxKernels = atoi(argv[3]);
dvm_drv = String(argv[4]); dvm_drv = String(argv[4]);
//-- //--
freeKernels = maxKernels; freeKernels = maxKernels;
busyKernels= 0; busyKernels= 0;
//-- //--
#if __cplusplus >= 201703L #if __cplusplus >= 201703L
std::filesystem::current_path(packageWorkspace.getCharArray()); std::filesystem::current_path(packageWorkspace.getCharArray());
#else #else
chdir(packageWorkspace.getCharArray()); chdir(packageWorkspace.getCharArray());
#endif #endif
userWorkspace.println(); #if DEB
packageWorkspace.println(); userWorkspace.println();
printf("%d\n", maxKernels); packageWorkspace.println();
#ifndef _WIN32 printf("%d\n", maxKernels);
int pid = getpid(); #endif
#else
int pid = _getpid(); #ifndef _WIN32
#endif int pid = getpid();
#else
printf("PID=%d\n", pid); int pid = _getpid();
File pidFile("PID", String(pid)+"\n"); #endif
pidFile.Close();
//--- #if DEB
File startFile("STARTED", "+"); printf("PID=%d\n", pid);
startFile.Close(); #endif
//--- File pidFile("PID", String(pid)+"\n");
printf(">>>>\n"); pidFile.Close();
CompilationSupervisor * compilationSupervisor = new CompilationSupervisor(); //---
printf("%ld\n", compilationSupervisor->getLength()); File startFile("STARTED", "+");
compilationSupervisor->DoWithSchedule(maxKernels); startFile.Close();
//---
RunSupervisor * runSupervisor = new RunSupervisor(compilationSupervisor); #if DEB
printf("%ld\n", runSupervisor->getLength()); printf(">>>>\n");
runSupervisor->print(); #endif
runSupervisor->DoWithSchedule(maxKernels); CompilationSupervisor * compilationSupervisor = new CompilationSupervisor();
return 0; #if DEB
} printf("%ld\n", compilationSupervisor->getLength());
#endif
compilationSupervisor->DoWithSchedule(maxKernels);
RunSupervisor * runSupervisor = new RunSupervisor(compilationSupervisor);
#if DEB
printf("%ld\n", runSupervisor->getLength());
runSupervisor->print();
#endif
runSupervisor->DoWithSchedule(maxKernels);
return 0;
}

View File

@@ -1,26 +1,25 @@
#pragma once #pragma once
#include "CompilationSupervisor.h" #include "CompilationSupervisor.h"
#include "RunTask.h" #include "RunTask.h"
class RunSupervisor : public Supervisor<RunTask> { class RunSupervisor : public Supervisor<RunTask> {
public: public:
RunSupervisor(CompilationSupervisor* compilationSupervisor) { RunSupervisor(CompilationSupervisor* compilationSupervisor) {
this->init("runTasks", 8); this->init("runTasks", 8);
//проверить отмененные задачи. //проверить отмененные задачи.
for (long i = 0; i < getLength(); ++i) { for (long i = 0; i < getLength(); ++i) {
RunTask* task = this->get(i); RunTask* task = this->get(i);
CompilationTask* parent = compilationSupervisor->getTaskById(task->getTestCompilationTaskId()); CompilationTask* parent = compilationSupervisor->getTaskById(task->getTestCompilationTaskId());
task->setState((parent->getState() == Done) ? Waiting : Canceled); task->setState((parent->getState() == Done) ? Waiting : Canceled);
task->setParent(parent); task->setParent(parent);
printf("id=%ld; parent_id = %ld; state=%s\n", #if DEB
task->getId(), printf("id=%ld; parent_id = %ld; state=%s\n", task->getId(), task->getParent()->getId(), task->printState().getCharArray());
task->getParent()->getId(), #endif
task->printState().getCharArray()); }
} }
}
String getStatePrefix() override {
String getStatePrefix() override { return String("Running");
return String("Running"); }
} };
};

View File

@@ -1,109 +1,111 @@
#pragma once #pragma once
#include "CompilationTask.h" #include "CompilationTask.h"
class RunTask : public Task { class RunTask : public Task {
long testcompilationtask_id; long testcompilationtask_id;
String binary_name; String binary_name;
String matrix; String matrix;
String environments; String environments;
String usr_par; String usr_par;
String args; String args;
CompilationTask* parent; CompilationTask* parent;
public: public:
void print() const override { void print() const override {
printf("id=%ld; maxtime=%d; testcompilationtask_id=%ld; matrix=%s; environments=%s; usr_par=%s; args=%s kernels=%d\n", printf("id=%ld; maxtime=%d; testcompilationtask_id=%ld; matrix=%s; environments=%s; usr_par=%s; args=%s kernels=%d\n",
id, id,
maxtime, maxtime,
testcompilationtask_id, testcompilationtask_id,
matrix.getCharArray(), matrix.getCharArray(),
environments.getCharArray(), environments.getCharArray(),
usr_par.getCharArray(), usr_par.getCharArray(),
args.getCharArray(), args.getCharArray(),
kernels kernels
); );
} }
int setKernels(String* kernels_s) { int setKernels(String* kernels_s) {
return kernels = atoi(kernels_s->getCharArray()); return kernels = atoi(kernels_s->getCharArray());
} }
long setTestCompilationTaskId(String* id_s) { long setTestCompilationTaskId(String* id_s) {
return testcompilationtask_id = strtol(id_s->getCharArray(), NULL, 10); return testcompilationtask_id = strtol(id_s->getCharArray(), NULL, 10);
} }
long getTestCompilationTaskId() { long getTestCompilationTaskId() {
return testcompilationtask_id; return testcompilationtask_id;
} }
void setMatrix(String* matrix_in) { void setMatrix(String* matrix_in) {
matrix = String(matrix_in->getCharArray()); matrix = String(matrix_in->getCharArray());
} }
void setEnvironments(String* environments_in) { void setEnvironments(String* environments_in) {
environments = String(environments_in->getCharArray()); environments = String(environments_in->getCharArray());
} }
void setUsrPar(String* usr_par_in) { void setUsrPar(String* usr_par_in) {
usr_par = String(usr_par_in->getCharArray(), '|'); usr_par = String(usr_par_in->getCharArray(), '|');
} }
void setArgs(String* args_in) { void setArgs(String* args_in) {
args = String(args_in->getCharArray()); args = String(args_in->getCharArray());
} }
void setParent(CompilationTask* parent_in) { void setParent(CompilationTask* parent_in) {
parent = parent_in; parent = parent_in;
binary_name = "spf_" + String(id) + "_" + matrix.Replace(' ', '_'); binary_name = "spf_" + String(id) + "_" + matrix.Replace(' ', '_');
} }
CompilationTask* getParent() { CompilationTask* getParent() {
return parent; return parent;
} }
RunTask(Text* lines, int offset) :Task(lines, offset) { RunTask(Text* lines, int offset) :Task(lines, offset) {
setTestCompilationTaskId(lines->get(offset + 2)); setTestCompilationTaskId(lines->get(offset + 2));
setMatrix(lines->get(offset + 3)); setMatrix(lines->get(offset + 3));
setEnvironments(lines->get(offset + 4)); setEnvironments(lines->get(offset + 4));
setUsrPar(lines->get(offset + 5)); setUsrPar(lines->get(offset + 5));
setArgs(lines->get(offset + 6)); setArgs(lines->get(offset + 6));
setKernels(lines->get(offset + 7)); setKernels(lines->get(offset + 7));
} }
String getLaunchScriptText() override { String getLaunchScriptText() override {
String modules = userWorkspace + "/modules"; String modules = userWorkspace + "/modules";
String starterCall = modules + "/starter"; String starterCall = modules + "/starter";
String launcherCall = modules + "/launcher"; String launcherCall = modules + "/launcher";
//- //-
String dvm_start = String::DQuotes(dvm_drv) + " run "; String dvm_start = String::DQuotes(dvm_drv) + " run ";
if (!matrix.isEmpty()) if (!matrix.isEmpty())
dvm_start = dvm_start + matrix + " "; dvm_start = dvm_start + matrix + " ";
dvm_start = dvm_start + String::DQuotes("./" + binary_name); dvm_start = dvm_start + String::DQuotes("./" + binary_name);
if (!args.isEmpty()) if (!args.isEmpty())
dvm_start = dvm_start + " " + args; dvm_start = dvm_start + " " + args;
return String::DQuotes(starterCall) + " " + return String::DQuotes(starterCall) + " " +
String::DQuotes(launcherCall) + " " + String::DQuotes(launcherCall) + " " +
String(maxtime) + " " + String(maxtime) + " " +
String::DQuotes("killall -SIGKILL " + binary_name) + " " + String::DQuotes("killall -SIGKILL " + binary_name + " 1>/dev/null 2>/dev/null") + " " +
dvm_start; dvm_start;
} }
void prepareWorkspace() override { void prepareWorkspace() override {
String binary_src = parent->getWorkspace() + "/0"; String binary_src = parent->getWorkspace() + "/0";
String binary_dst = workspace + "/" + binary_name; String binary_dst = workspace + "/" + binary_name;
Utils::Copy(binary_src, binary_dst); Utils::Copy(binary_src, binary_dst);
if (!usr_par.isEmpty()) { if (!usr_par.isEmpty()) {
String parPath = String(id) + "/usr.par"; String parPath = String(id) + "/usr.par";
File parFile = File(parPath, usr_par); File parFile = File(parPath, usr_par);
} }
} }
String getStartCommand() override { String getStartCommand() override {
String res = workspace + "/run"; String res = workspace + "/run";
if (!environments.isEmpty()) if (!environments.isEmpty())
res = environments + " " + res; res = environments + " " + res;
printf("START %ld: %s\n", id, res.getCharArray()); #if DEB
return res; printf("START %ld: %s\n", id, res.getCharArray());
} #endif
return res;
String copyResults(const String& pathRes) override { }
String resultPath = Task::copyResults(pathRes);
if (Utils::Exists(workspace + "/sts.gz+")) { String copyResults(const String& pathRes) override {
String stsPath(resultPath + "/statistic.txt"); String resultPath = Task::copyResults(pathRes);
String dvm_start = String::DQuotes(dvm_drv) + " pa " + String::DQuotes(String(getId()) + "/sts.gz+") + " " + String::DQuotes(stsPath); if (Utils::Exists(workspace + "/sts.gz+")) {
system(dvm_start.getCharArray()); String stsPath(resultPath + "/statistic.txt");
while (!Utils::Exists(stsPath)); String dvm_start = String::DQuotes(dvm_drv) + " pa " + String::DQuotes(String(getId()) + "/sts.gz+") + " " + String::DQuotes(stsPath);
} system(dvm_start.getCharArray());
return resultPath; while (!Utils::Exists(stsPath));
} }
}; return resultPath;
}
};

View File

@@ -1,71 +1,73 @@
#pragma once #pragma once
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <string> #include <string>
class String { class String {
friend String operator+(const String& a, const String& b); friend String operator+(const String& a, const String& b);
string body; string body;
public: public:
String() { body = ""; } String() { body = ""; }
String(const char* s) { body = s; } String(const char* s) { body = s; }
String(const char* s, char ps) { String(const char* s, char ps) {
body = s; body = s;
for (long i = 0; i < getLength(); ++i) for (long i = 0; i < getLength(); ++i)
body[i] = (s[i] == ps) ? '\n' : s[i]; body[i] = (s[i] == ps) ? '\n' : s[i];
} }
String(int s) { body = to_string(s); } String(int s) { body = to_string(s); }
String(long s) { body = to_string(s); } String(long s) { body = to_string(s); }
String(long long s) { body = to_string(s); } String(long long s) { body = to_string(s); }
void println() const { printf("[%s]\n", body.c_str()); } void println() const { printf("[%s]\n", body.c_str()); }
void addChar(char c) { body += c; } void addChar(char c) { body += c; }
const char* getCharArray() const { return body.c_str(); } const char* getCharArray() const { return body.c_str(); }
const string& getBody() const { return body; } const string& getBody() const { return body; }
size_t getLength() const { return body.size(); } size_t getLength() const { return body.size(); }
bool isEmpty() const { return body.size() == 0; } bool isEmpty() const { return body.size() == 0; }
bool contains(const String& s) const { return body.find(s.getBody()) != string::npos; } bool contains(const String& s) const { return body.find(s.getBody()) != string::npos; }
bool operator==(const String& s) const { return body == s.getBody(); } bool operator==(const String& s) const { return body == s.getBody(); }
const String& operator=(const String& s) { const String& operator=(const String& s) {
body = s.getBody(); body = s.getBody();
return *this; return *this;
} }
static String DQuotes(const String& s) { static String DQuotes(const String& s) {
string tmp = '"' + s.getBody() + '"'; string tmp = '"' + s.getBody() + '"';
return String(tmp.c_str()); return String(tmp.c_str());
} }
String Replace(char f, char t) { String Replace(char f, char t) {
String res(body.c_str()); String res(body.c_str());
for (auto i = 0; i < getLength(); ++i) for (auto i = 0; i < getLength(); ++i)
res.body[i] = (body[i] == f) ? t : body[i]; res.body[i] = (body[i] == f) ? t : body[i];
return res; return res;
} }
String Remove(char f) { String Remove(char f) {
String res; String res;
for (auto i = 0; i < getLength(); ++i) for (auto i = 0; i < getLength(); ++i)
if (body[i] != f) if (body[i] != f)
res.addChar(body[i]); res.addChar(body[i]);
return res; return res;
} }
String toUpper() { String toUpper() {
String res = String(this->getCharArray()); String res = String(this->getCharArray());
for (auto i = 0; i < getLength(); ++i) for (auto i = 0; i < getLength(); ++i)
res.body[i] = toupper(body[i]); res.body[i] = toupper(body[i]);
res.println(); #if DEB
return res; res.println();
} #endif
}; return res;
}
String operator+(const String& a, const String& b) { };
return String((a.getBody() + b.getBody()).c_str());
} String operator+(const String& a, const String& b) {
return String((a.getBody() + b.getBody()).c_str());
}

View File

@@ -104,9 +104,8 @@ public:
} }
map<int, queue<T*>, std::greater<int>> sortedByKernelNeeds; map<int, queue<T*>, std::greater<int>> sortedByKernelNeeds;
size_t activeTasks = 0;
long activeTasks = 0;
long done = 0;
for (auto& task : this->getElements()) { for (auto& task : this->getElements()) {
if (task->getState() == WorkspaceReady) { if (task->getState() == WorkspaceReady) {
activeTasks++; activeTasks++;
@@ -126,6 +125,10 @@ public:
vector<int> emptyKeys; vector<int> emptyKeys;
vector<T*> toDel; vector<T*> toDel;
size_t done = 0;
size_t step = activeTasks * 0.01; // step == 1%
const double total = activeTasks;
while (activeTasks) { while (activeTasks) {
long oldActiveTasks = activeTasks; long oldActiveTasks = activeTasks;
@@ -143,8 +146,9 @@ public:
activeTaskSet.insert(task); activeTaskSet.insert(task);
task->Start(ignoreCheck); task->Start(ignoreCheck);
#if DEB
printf("start task with %d kernels and id %ld\n", task->getKernels(), task->getId()); printf("start task with %d kernels and id %ld\n", task->getKernels(), task->getId());
#endif
busyKernels += task->getKernels(); busyKernels += task->getKernels();
freeKernels = maxKernels - busyKernels; freeKernels = maxKernels - busyKernels;
} }
@@ -169,8 +173,9 @@ public:
activeTasks--; activeTasks--;
done++; done++;
busyKernels -= task->getKernels(); busyKernels -= task->getKernels();
#if DEB
printf(" done task with %d kernels and id %ld\n", task->getKernels(), task->getId()); printf(" done task with %d kernels and id %ld\n", task->getKernels(), task->getId());
#endif
buf += to_string(task->getId()) + " " + string(task->printState().getCharArray()) + " " + to_string(task->getTotalTime()) + "\n"; buf += to_string(task->getId()) + " " + string(task->printState().getCharArray()) + " " + to_string(task->getTotalTime()) + "\n";
task->copyResults(pathRes); task->copyResults(pathRes);
} }
@@ -180,8 +185,19 @@ public:
for (auto& del : toDel) for (auto& del : toDel)
activeTaskSet.erase(del); activeTaskSet.erase(del);
if (oldActiveTasks != activeTasks) if (oldActiveTasks != activeTasks) {
printf("done %ld / %ld\n", done, this->getLength()); #if DEB
printf("done %ld / %d\n", done, this->getLength());
#endif
if ((done % step) == 0) {
size_t persentDone = (done / total) * 100.0;
FILE *f = fopen("progress", "w");
if (f) {
fprintf(f, "%lld\n", persentDone);
fclose(f);
}
}
}
} }
changeState(); changeState();

View File

@@ -1,197 +1,201 @@
#pragma once #pragma once
#include <chrono> #include <chrono>
#include "File.h" #include "File.h"
#include "Utils.h" #include "Utils.h"
#include "Global.h" #include "Global.h"
enum TaskState { enum TaskState {
Inactive, //0 Inactive, //0
Waiting, //1 Waiting, //1
WorkspaceCreated, //2 WorkspaceCreated, //2
WorkspaceReady, //3 WorkspaceReady, //3
Running, //4 Running, //4
Canceled, //5 Canceled, //5
Finished, //6 Finished, //6
FinishedAbortedByTimeout, //7 FinishedAbortedByTimeout, //7
FinishedAbortedByUser, //8 FinishedAbortedByUser, //8
Done, //9 Done, //9
DoneWithErrors, //10 DoneWithErrors, //10
AbortedByTimeout, //11 AbortedByTimeout, //11
AbortedByUser, //12 AbortedByUser, //12
Crushed, //13 Crushed, //13
WrongTestFormat, //14 WrongTestFormat, //14
InternalError, //15 InternalError, //15
Queued, //16 Queued, //16
NoSuchTask, //17 NoSuchTask, //17
FailedToQueue, //18 FailedToQueue, //18
AbortingByUser, //19 AbortingByUser, //19
Unknown Unknown
}; };
enum TestType { enum TestType {
Default, //0 Default, //0
Correctness, //1 Correctness, //1
Performance, //2 Performance, //2
}; };
class Task { class Task {
protected: protected:
long id; long id;
int maxtime; int maxtime;
int kernels; //получение зависит от типа задачи. int kernels; //получение зависит от типа задачи.
String workspace; String workspace;
TaskState state = Unknown; TaskState state = Unknown;
std::chrono::system_clock::time_point start_time; std::chrono::system_clock::time_point start_time;
double total_time; double total_time;
public: public:
String printState() { String printState() {
switch (state) { switch (state) {
case Inactive: case Inactive:
return String("Inactive"); return String("Inactive");
case Waiting: case Waiting:
return String("Waiting"); return String("Waiting");
case WorkspaceCreated: case WorkspaceCreated:
return String("WorkspaceCreated"); return String("WorkspaceCreated");
case WorkspaceReady: case WorkspaceReady:
return String("WorkspaceReady"); return String("WorkspaceReady");
case Running: case Running:
return String("Running"); return String("Running");
case Canceled: case Canceled:
return String("Canceled"); return String("Canceled");
case Finished: case Finished:
return String("Finished"); return String("Finished");
case FinishedAbortedByTimeout: case FinishedAbortedByTimeout:
return String("FinishedAbortedByTimeout"); return String("FinishedAbortedByTimeout");
case FinishedAbortedByUser: case FinishedAbortedByUser:
return String("FinishedAbortedByUser"); return String("FinishedAbortedByUser");
case Done: case Done:
return String("Done"); return String("Done");
case DoneWithErrors: case DoneWithErrors:
return String("DoneWithErrors"); return String("DoneWithErrors");
case AbortedByTimeout: case AbortedByTimeout:
return String("AbortedByTimeout"); return String("AbortedByTimeout");
case AbortedByUser: case AbortedByUser:
return String("AbortedByUser"); return String("AbortedByUser");
case Crushed: case Crushed:
return String("Crushed"); return String("Crushed");
case WrongTestFormat: case WrongTestFormat:
return String("WrongTestFormat"); return String("WrongTestFormat");
case InternalError: case InternalError:
return String("InternalError"); return String("InternalError");
case Queued: case Queued:
return String("Queued"); return String("Queued");
case NoSuchTask: case NoSuchTask:
return String("NoSuchTask"); return String("NoSuchTask");
case FailedToQueue: case FailedToQueue:
return String("FailedToQueue"); return String("FailedToQueue");
case AbortingByUser: case AbortingByUser:
return String("AbortingByUser"); return String("AbortingByUser");
case Unknown: case Unknown:
return String("?"); return String("?");
default: default:
return "?"; return "?";
} }
} }
//-------------->> //-------------->>
void setStart() { start_time = std::chrono::system_clock::now(); } void setStart() { start_time = std::chrono::system_clock::now(); }
double getTotalTime() const { return total_time; } double getTotalTime() const { return total_time; }
long getId() { return id; } long getId() { return id; }
long setId(String* id_s) { long setId(String* id_s) {
return id = strtol(id_s->getCharArray(), NULL, 10); return id = strtol(id_s->getCharArray(), NULL, 10);
} }
int getMaxtime() { return maxtime; } int getMaxtime() { return maxtime; }
int setMaxtime(String* maxtime_s) { int setMaxtime(String* maxtime_s) {
return maxtime = atoi(maxtime_s->getCharArray()); return maxtime = atoi(maxtime_s->getCharArray());
} }
const String& getWorkspace() { return workspace; } const String& getWorkspace() { return workspace; }
TaskState getState() { return state; } TaskState getState() { return state; }
TaskState setState(TaskState state_in) { return state = state_in; } TaskState setState(TaskState state_in) { return state = state_in; }
Task(Text* lines, int offset) { Task(Text* lines, int offset) {
setId(lines->get(offset)); setId(lines->get(offset));
setMaxtime(lines->get(offset + 1)); setMaxtime(lines->get(offset + 1));
workspace = packageWorkspace + "/" + String(id); workspace = packageWorkspace + "/" + String(id);
} }
virtual void print() const = 0; virtual void print() const = 0;
//- //-
virtual void prepareWorkspace() {} virtual void prepareWorkspace() {}
virtual String getLaunchScriptText() = 0; virtual String getLaunchScriptText() = 0;
virtual String getStartCommand() { virtual String getStartCommand() {
return workspace + "/run"; return workspace + "/run";
} }
void createWorkspace() { void createWorkspace() {
Utils::Mkdir(workspace); Utils::Mkdir(workspace);
} }
void createLaunchScript() { void createLaunchScript() {
String launchScriptPath = workspace + "/run"; String launchScriptPath = workspace + "/run";
String launchScriptText = String launchScriptText =
String("cd ") + String::DQuotes(workspace) + "\n" + String("cd ") + String::DQuotes(workspace) + "\n" +
getLaunchScriptText(); getLaunchScriptText();
File launchScriptFile = File(launchScriptPath, launchScriptText); File launchScriptFile = File(launchScriptPath, launchScriptText);
Utils::Chmod(launchScriptPath); Utils::Chmod(launchScriptPath);
} }
int getKernels() const { return kernels; } int getKernels() const { return kernels; }
void Start(bool dontCheck = false) { void Start(bool dontCheck = false) {
if (kernels <= freeKernels || dontCheck) { if (kernels <= freeKernels || dontCheck) {
setStart(); setStart();
system(getStartCommand().getCharArray()); system(getStartCommand().getCharArray());
state = Running; state = Running;
//- //-
busyKernels = Utils::min(busyKernels + kernels, maxKernels); busyKernels = Utils::min(busyKernels + kernels, maxKernels);
freeKernels = Utils::max(0, maxKernels - busyKernels); freeKernels = Utils::max(0, maxKernels - busyKernels);
//- //-
} }
} }
//return 'true' if done, 'false' - if running //return 'true' if done, 'false' - if running
virtual bool Check() { virtual bool Check() {
if (Utils::Exists(workspace + "/DONE")) if (Utils::Exists(workspace + "/DONE"))
analyseResults(); analyseResults();
else { else {
if (Utils::Exists(workspace + "/TIMEOUT")) { if (Utils::Exists(workspace + "/TIMEOUT")) {
state = AbortedByTimeout; state = AbortedByTimeout;
//todo определить по интервалу времени на всякий случай. //todo определить по интервалу времени на всякий случай.
} }
else if (Utils::Exists(workspace + "/INTERRUPT")) { else if (Utils::Exists(workspace + "/INTERRUPT")) {
state = AbortedByUser; state = AbortedByUser;
} }
else { else {
auto end_time = std::chrono::system_clock::now(); auto end_time = std::chrono::system_clock::now();
std::chrono::duration<double> diff_time = end_time - start_time; std::chrono::duration<double> diff_time = end_time - start_time;
if (maxtime * 1.1 < diff_time.count()) { if (maxtime * 1.1 < diff_time.count()) {
printf("SET STATUS ABORTED by timer to %ld with time %f sec / %f sec", id, diff_time.count(), maxtime * 1.1); #if DEB
state = AbortedByTimeout; printf("SET STATUS ABORTED by timer to %ld with time %f sec / %f sec", id, diff_time.count(), maxtime * 1.1);
} #endif
} state = AbortedByTimeout;
} }
if (state != Running) { }
busyKernels = Utils::min(busyKernels - kernels, maxKernels); }
freeKernels = Utils::max(0, maxKernels - busyKernels); if (state != Running) {
} busyKernels = Utils::min(busyKernels - kernels, maxKernels);
return (state != Running); freeKernels = Utils::max(0, maxKernels - busyKernels);
} }
return (state != Running);
virtual void analyseResults() { }
auto end_time = std::chrono::system_clock::now();
std::chrono::duration<double> diff_time = end_time - start_time; virtual void analyseResults() {
total_time = diff_time.count(); auto end_time = std::chrono::system_clock::now();
printf("%ld done with time %f\n", id, total_time); std::chrono::duration<double> diff_time = end_time - start_time;
state = Finished; total_time = diff_time.count();
} #if DEB
virtual String copyResults(const String& pathRes) { printf("%ld done with time %f\n", id, total_time);
String resultPath(packageWorkspace + "/" + pathRes + "/" + getId()); #endif
Utils::Mkdir(resultPath); state = Finished;
Utils::Copy(workspace + "/out.txt", resultPath + "/out.txt"); }
Utils::Copy(workspace + "/err.txt", resultPath + "/err.txt"); virtual String copyResults(const String& pathRes) {
return resultPath; String resultPath(packageWorkspace + "/" + pathRes + "/" + getId());
} Utils::Mkdir(resultPath);
}; Utils::Copy(workspace + "/out.txt", resultPath + "/out.txt");
Utils::Copy(workspace + "/err.txt", resultPath + "/err.txt");
return resultPath;
}
};

View File

@@ -1,29 +1,29 @@
#pragma once #pragma once
#include "String.h" #include "String.h"
#include "Array.h" #include "Array.h"
class Text : public Array<String> { class Text : public Array<String> {
public: public:
void Print() const { void Print() const {
printf("text length=%ld\n", this->getLength()); printf("text length=%ld\n", this->getLength());
auto elems = this->getElements(); auto elems = this->getElements();
for (long i = 0; i < elems.size(); ++i) { for (long i = 0; i < elems.size(); ++i) {
printf("i=%ld; [%s]\n", i, elems[i]->getCharArray()); printf("i=%ld; [%s]\n", i, elems[i]->getCharArray());
// elements[i]->println(); // elements[i]->println();
} }
} }
bool hasMatch(const String& s) const { bool hasMatch(const String& s) const {
for (auto& elem : this->getElements()) { for (auto& elem : this->getElements()) {
if (s.contains(*elem)) { if (s.contains(*elem)) {
//printf("match: [%s]\n", elements[i]->getCharArray()); //printf("match: [%s]\n", elements[i]->getCharArray());
return true; return true;
} }
} }
//printf("no matches for [%s]\n", s.getCharArray()); //printf("no matches for [%s]\n", s.getCharArray());
return false; return false;
} }
}; };

View File

@@ -1,84 +1,84 @@
#pragma once #pragma once
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <errno.h> #include <errno.h>
#include <time.h> #include <time.h>
#include <chrono> #include <chrono>
#include <thread> #include <thread>
#if __cplusplus >= 201703L #if __cplusplus >= 201703L
#include <filesystem> #include <filesystem>
#endif #endif
#include "String.h" #include "String.h"
class Utils { class Utils {
public: public:
static int max(int a, int b) { static int max(int a, int b) {
return (a > b) ? a : b; return (a > b) ? a : b;
} }
static int min(int a, int b) { static int min(int a, int b) {
return (a > b) ? b : a; return (a > b) ? b : a;
} }
static void Mkdir(const String& path) { static void Mkdir(const String& path) {
#if __cplusplus >= 201703L #if __cplusplus >= 201703L
std::filesystem::create_directory(path.getCharArray()); std::filesystem::create_directory(path.getCharArray());
#else #else
mkdir(path.getCharArray(), 0777); mkdir(path.getCharArray(), 0777);
#endif #endif
} }
//https://stackoverflow.com/questions/4568681/using-chmod-in-a-c-program //https://stackoverflow.com/questions/4568681/using-chmod-in-a-c-program
static void Chmod(const String& path) { static void Chmod(const String& path) {
#if __cplusplus >= 201703L #if __cplusplus >= 201703L
std::filesystem::permissions(path.getCharArray(), std::filesystem::perms::all); std::filesystem::permissions(path.getCharArray(), std::filesystem::perms::all);
#else #else
String command = "chmod 777 " + String::DQuotes(path); String command = "chmod 777 " + String::DQuotes(path);
int i=system(command.getCharArray()); int i=system(command.getCharArray());
printf("chmod 777 '%s' return code = %d\n", path.getCharArray(), i); //printf("chmod 777 '%s' return code = %d\n", path.getCharArray(), i);
#endif #endif
} }
//https://stackoverflow.com/questions/230062/whats-the-best-way-to-check-if-a-file-exists-in-c //https://stackoverflow.com/questions/230062/whats-the-best-way-to-check-if-a-file-exists-in-c
static bool Exists(const String& path) { static bool Exists(const String& path) {
#if __cplusplus >= 201703L #if __cplusplus >= 201703L
return std::filesystem::exists(path.getCharArray()); return std::filesystem::exists(path.getCharArray());
#else #else
struct stat buffer; struct stat buffer;
return (stat(path.getCharArray(), &buffer) == 0); return (stat(path.getCharArray(), &buffer) == 0);
#endif #endif
} }
//in seconds //in seconds
static void Sleep(int s) { static void Sleep(int s) {
std::chrono::seconds timespan(s); std::chrono::seconds timespan(s);
std::this_thread::sleep_for(timespan); std::this_thread::sleep_for(timespan);
} }
static void Copy(const String& src, const String& dst) { static void Copy(const String& src, const String& dst) {
#if __cplusplus >= 201703L #if __cplusplus >= 201703L
std::filesystem::copy(src.getCharArray(), dst.getCharArray()); std::filesystem::copy(src.getCharArray(), dst.getCharArray());
#else #else
String command = "cp " + String::DQuotes(src) + " " + String::DQuotes(dst); String command = "cp " + String::DQuotes(src) + " " + String::DQuotes(dst);
int i = system(command.getCharArray()); int i = system(command.getCharArray());
printf("cp '%s' return code = %d\n",src.getCharArray(), i); //printf("cp '%s' return code = %d\n",src.getCharArray(), i);
#endif #endif
} }
static void CopyDirectory(const String& src, const String& dst) { static void CopyDirectory(const String& src, const String& dst) {
#if __cplusplus >= 201703L #if __cplusplus >= 201703L
std::filesystem::copy((src+ "/.").getCharArray(), dst.getCharArray(), std::filesystem::copy_options::recursive); std::filesystem::copy((src+ "/.").getCharArray(), dst.getCharArray(), std::filesystem::copy_options::recursive);
#else #else
String command = "cp -r " + String::DQuotes(src + "/.") + " " + String::DQuotes(dst); String command = "cp -r " + String::DQuotes(src + "/.") + " " + String::DQuotes(dst);
int i = system(command.getCharArray()); int i = system(command.getCharArray());
printf("cp -r '%s' return code = %d\n",src.getCharArray(),i); //printf("cp -r '%s' return code = %d\n",src.getCharArray(),i);
#endif #endif
} }
static time_t getAbsoluteTime() { static time_t getAbsoluteTime() {
return time(NULL); return time(NULL);
} }
static String getDate() { static String getDate() {
auto ttime = time(NULL); auto ttime = time(NULL);
String res(ctime(&ttime)); String res(ctime(&ttime));
return res; return res;
} }
}; };

View File

@@ -0,0 +1 @@
1