From 61d824803c4c1a41f77a47e44949ebc93e224b37 Mon Sep 17 00:00:00 2001 From: still-flow <46608177+still-flow@users.noreply.github.com> Date: Thu, 28 May 2020 13:29:03 +0300 Subject: [PATCH] add simple concurrent compilation using something similar to round-robin scheduling --- Makefile.simple | 2 +- mymake.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/Makefile.simple b/Makefile.simple index 79c75273..d8debc78 100644 --- a/Makefile.simple +++ b/Makefile.simple @@ -162,7 +162,7 @@ savepng$(OBJ_EXTENSION): savepng.cpp $(CXX) -O2 $(CXXFLAGS) -c savepng.cpp -o $@ mymake$(EXE_EXTENSION): mymake.cpp - $(CXX) -O2 $(CXXFLAGS) mymake.cpp -o $@ + $(CXX) -O2 $(CXXFLAGS) -lpthread mymake.cpp -o $@ emscripten: hyper.html diff --git a/mymake.cpp b/mymake.cpp index 455b36be..176e665c 100644 --- a/mymake.cpp +++ b/mymake.cpp @@ -14,6 +14,8 @@ #include #include #include +#include +#include using namespace std; @@ -27,6 +29,8 @@ string compiler; string linker; string libs; +int batch_size = 1; + void set_linux() { preprocessor = "g++ -E"; compiler = "g++ -Wall -Wextra -Wno-maybe-uninitialized -Wno-unused-parameter -Wno-implicit-fallthrough -rdynamic -fdiagnostics-color=always -c"; @@ -129,6 +133,10 @@ int main(int argc, char **argv) { standard = s; else if(s.substr(0, 2) == "-l") linker += " " + s; + else if(s.substr(0, 2) == "-j") + if (s.length() == 2 || stoi(s.substr(2)) < 1) + batch_size = thread::hardware_concurrency() + 1; + else batch_size = stoi(s.substr(2)); else if(s == "-I") { opts += " " + s + " " + argv[i+1]; i++; @@ -203,10 +211,10 @@ int main(int argc, char **argv) { } string allobj = " " + obj_dir + "/hyper.o"; - + int id = 0; + vector> tasks; for(string m: modules) { - id++; string src = m + ".cpp"; string m2 = m; for(char& c: m2) if(c == '/') c = '_'; @@ -218,14 +226,45 @@ int main(int argc, char **argv) { } time_t obj_time = get_file_time(obj); if(src_time > obj_time) { - printf("compiling %s... [%d/%d]\n", m.c_str(), id, int(modules.size())); - if(system(compiler + " " + opts + " " + src + " -o " + obj)) { printf("error\n"); exit(1); } + pair task(id, compiler + " " + opts + " " + src + " -o " + obj); + tasks.push_back(task); } else { printf("ok: %s\n", m.c_str()); } allobj += " "; allobj += obj; + id++; + } + + chrono::milliseconds quantum(25); + vector> workers(batch_size); + + int tasks_amt = tasks.size(); + int tasks_taken = 0, tasks_done = 0; + bool finished = tasks.empty(); + + while (!finished) + for (auto & worker : workers) { + check_lollygagging: + if (worker.valid()) { + if (worker.wait_for(quantum) != future_status::ready) continue; + else { + int res = worker.get(); + if (res) { printf("compilation error!\n"); exit(1); } + ++tasks_done; + goto check_lollygagging; + } + } + else if (tasks_taken < tasks_amt) { + auto task = tasks[tasks_taken]; + int mid = task.first; + string cmdline = task.second; + printf("compiling %s... [%d/%d]\n", modules[mid].c_str(), tasks_taken+1, tasks_amt); + worker = async(launch::async, (int (*)(string))system, cmdline); + ++tasks_taken; + } + else if (tasks_done == tasks_amt) { finished = true; break; } } printf("linking...\n");