aboutsummaryrefslogtreecommitdiff
path: root/build2/b.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-02-10 08:15:48 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-02-13 12:42:42 +0200
commitabccaf9596461215fce0e32322133fb6c39be44f (patch)
tree3fc16a6e6142d65e6b47ae686ab845cc164478cc /build2/b.cxx
parentbcb2a89e111a918a48a132a2a29e0c26d724591d (diff)
Implement parallel error propagation, keep_going mode
Keep going is the default but there is now the -s|--serial-stop that makes the driver run serially and stop at first error. Also fix some lockups, other minor improvements/features.
Diffstat (limited to 'build2/b.cxx')
-rw-r--r--build2/b.cxx57
1 files changed, 31 insertions, 26 deletions
diff --git a/build2/b.cxx b/build2/b.cxx
index 0ad404a..14258b3 100644
--- a/build2/b.cxx
+++ b/build2/b.cxx
@@ -67,6 +67,10 @@ main (int argc, char* argv[])
int build2::
main (int argc, char* argv[])
{
+ tracer trace ("main");
+
+ int r (0);
+
// This is a little hack to make out baseutils for Windows work when called
// with absolute path. In a nutshell, MSYS2's exec*p() doesn't search in the
// parent's executable directory, only in PATH. And since we are running
@@ -93,8 +97,6 @@ main (int argc, char* argv[])
try
{
- tracer trace ("main");
-
// On POSIX ignore SIGPIPE which is signaled to a pipe-writing process if
// the pipe reading end is closed. Note that by default this signal
// terminates a process. Also note that there is no way to disable this
@@ -225,8 +227,7 @@ main (int argc, char* argv[])
//
catch (const system_error& e)
{
- error << "pager failed: " << e;
- return 1;
+ fail << "pager failed: " << e;
}
}
@@ -270,12 +271,16 @@ main (int argc, char* argv[])
bm["cli"] = mf {nullptr, &cli::init};
}
+ keep_going = !ops.serial_stop ();
+
// Start up the scheduler.
//
size_t jobs (0);
if (ops.jobs_specified ())
jobs = ops.jobs ();
+ else if (ops.serial_stop ())
+ jobs = 1;
if (jobs == 0)
jobs = scheduler::hardware_concurrency ();
@@ -1097,32 +1102,32 @@ main (int argc, char* argv[])
if (lifted == nullptr && skip == 0)
++mit;
} // meta-operation
-
- // Shutdown the scheduler.
- //
- scheduler::stat st (sched.shutdown ());
-
- if (verb >= (jobs > 1 ? 3 : 4))
- {
- info << "scheduler statistics:" << '\n'
- << " thread_max_active " << st.thread_max_active << '\n'
- << " thread_max_total " << st.thread_max_total << '\n'
- << " thread_helpers " << st.thread_helpers << '\n'
- << " thread_max_waiting " << st.thread_max_waiting << '\n'
- << '\n'
- << " task_queue_depth " << st.task_queue_depth << '\n'
- << " task_queue_full " << st.task_queue_full << '\n'
- << '\n'
- << " wait_queue_slots " << st.wait_queue_slots << '\n'
- << " wait_queue_collisions " << st.wait_queue_collisions << '\n';
- }
-
- return 0;
}
catch (const failed&)
{
// Diagnostics has already been issued.
+ //
+ r = 1;
+ }
+
+ // Shutdown the scheduler and print statistics.
+ //
+ scheduler::stat st (sched.shutdown ());
+
+ if (verb >= (st.thread_max_active > 1 ? 3 : 4))
+ {
+ info << "scheduler statistics:" << "\n\n"
+ << " thread_max_active " << st.thread_max_active << '\n'
+ << " thread_max_total " << st.thread_max_total << '\n'
+ << " thread_helpers " << st.thread_helpers << '\n'
+ << " thread_max_waiting " << st.thread_max_waiting << '\n'
+ << '\n'
+ << " task_queue_depth " << st.task_queue_depth << '\n'
+ << " task_queue_full " << st.task_queue_full << '\n'
+ << '\n'
+ << " wait_queue_slots " << st.wait_queue_slots << '\n'
+ << " wait_queue_collisions " << st.wait_queue_collisions << '\n';
}
- return 1;
+ return r;
}