From 11911621982c1fef8d5ae4335c389560f876bc32 Mon Sep 17 00:00:00 2001 From: q66 Date: Wed, 3 May 2017 21:09:25 +0200 Subject: [PATCH] separate thread for stdout in buildsystem This allows messages to be printed in sequence instead of multiple prints in parallel mangling the output. --- build.cc | 70 +++++++++++++++++++++++++++-------------- examples/concurrency.cc | 2 +- 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/build.cc b/build.cc index 4f1d6f5..5f7561f 100644 --- a/build.cc +++ b/build.cc @@ -20,6 +20,7 @@ #include "ostd/string.hh" #include "ostd/filesystem.hh" #include "ostd/thread_pool.hh" +#include "ostd/channel.hh" namespace fs = ostd::filesystem; @@ -133,14 +134,15 @@ static void exec_command( } } -static void print_command( +static std::string get_command( std::string const &cmd, std::vector const &args ) { - ostd::write(cmd); + std::string ret = cmd; for (auto &s: args) { - ostd::writef(" %s", s); + ret += ' '; + ret += s; } - ostd::writeln(); + return ret; } static void add_args(std::vector &args, std::string const &cmdl) { @@ -171,22 +173,6 @@ static void try_remove(fs::path const &path, bool all = false) { static bool verbose = false; -template -static void echo_q(ostd::string_range fmt, A const &...args) { - if (!verbose) { - ostd::writefln(fmt, args...); - } -} - -static void exec_v( - std::string const &cmd, std::vector const &args -) { - if (verbose) { - print_command(cmd, args); - } - exec_command(cmd, args); -} - int main(int argc, char **argv) { bool build_examples = true; bool build_testsuite = true; @@ -287,6 +273,39 @@ int main(int argc, char **argv) { return 0; } + /* a queue of stuff to print to stdout */ + ostd::channel io_msgs; + + /* a thread which reads from the queue */ + std::thread io_thread{[&io_msgs]() { + try { + for (;;) { + /* wait for a msg; if closed, throw channel_error */ + ostd::writeln(io_msgs.get()); + } + } catch (ostd::channel_error const &) { + /* the queue is empty and closed, thread is done */ + return; + } + }}; + + auto echo_q = [&io_msgs](ostd::string_range fmt, auto const &...args) { + if (!verbose) { + auto app = ostd::appender(); + ostd::format(app, fmt, args...); + io_msgs.put(std::move(app.get())); + } + }; + + auto exec_v = [&io_msgs]( + std::string const &cmd, std::vector const &args + ) { + if (verbose) { + io_msgs.put(get_command(cmd, args)); + } + exec_command(cmd, args); + }; + auto call_cxx = [&]( std::string const &input, std::string const &output, bool shared ) { @@ -459,7 +478,7 @@ int main(int argc, char **argv) { } }; - ostd::writeln("Building the library..."); + echo_q("Building the library..."); for (auto aso: ASM_SOURCES) { build_obj(ASM_SOURCE_DIR / aso, ".S", call_as, asm_obj, asm_dynobj); } @@ -487,7 +506,7 @@ int main(int argc, char **argv) { } if (build_examples) { - ostd::writeln("Building examples..."); + echo_q("Building examples..."); for (auto ex: EXAMPLES) { futures.push(tp.push([&build_example, ex]() { build_example(ex); @@ -496,11 +515,11 @@ int main(int argc, char **argv) { } if (build_testsuite) { - ostd::writeln("Building tests..."); + echo_q("Building tests..."); build_test_runner(); if (!fs::is_directory(TEST_DIR)) { if (!fs::create_directory(TEST_DIR)) { - ostd::writeln("Failed creating test directory"); + echo_q("Failed creating test directory"); return 1; } } @@ -521,5 +540,8 @@ int main(int argc, char **argv) { exec_v("./test_runner", { TEST_DIR.string() }); } + io_msgs.close(); + io_thread.join(); + return 0; } diff --git a/examples/concurrency.cc b/examples/concurrency.cc index eccf49f..e897576 100644 --- a/examples/concurrency.cc +++ b/examples/concurrency.cc @@ -13,7 +13,7 @@ using namespace ostd; * task, which may or may not run in parallel with the other one depending * on the scheduler currently in use - several schedulers are shown */ -auto input_array = { 150, 38, 76, 25, 67, 18, -15, 215, 25, -10 }; +auto input_array = { 150, 38, 76, 25, 67, 18, -15, 215, 25, -10 }; auto first_half = iter(input_array).slice(0, input_array.size() / 2); auto second_half = iter(input_array).slice(input_array.size() / 2);