From 0d0f186053087c3705ee4c01f6b7f4bf7832c063 Mon Sep 17 00:00:00 2001 From: Evan Martin Date: Tue, 1 Feb 2011 10:14:43 -0800 Subject: [PATCH] parallelism flag, guess based on cpuinfo --- src/build.h | 3 ++- src/ninja.cc | 44 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/build.h b/src/build.h index 843e907..a1d6d4c 100644 --- a/src/build.h +++ b/src/build.h @@ -60,7 +60,7 @@ struct CommandRunner { }; struct BuildConfig { - BuildConfig() : verbosity(NORMAL), dry_run(false) {} + BuildConfig() : verbosity(NORMAL), dry_run(false), parallelism(1) {} enum Verbosity { NORMAL, @@ -69,6 +69,7 @@ struct BuildConfig { }; Verbosity verbosity; bool dry_run; + int parallelism; }; struct Builder { diff --git a/src/ninja.cc b/src/ninja.cc index 6100357..6e441b6 100644 --- a/src/ninja.cc +++ b/src/ninja.cc @@ -3,6 +3,7 @@ #include #include #include +#include #include "build.h" #include "build_log.h" @@ -26,20 +27,46 @@ option options[] = { { } }; -void usage() { +void usage(const BuildConfig& config) { fprintf(stderr, "usage: ninja [options] target\n" "\n" "options:\n" " -i FILE specify input build file [default=build.ninja]\n" +" -j N run N jobs in parallel [default=%d]\n" " -n dry run (don't run commands but pretend they succeeded)\n" " -v show all command lines\n" "\n" " -t TOOL run a subtool. tools are:\n" " browse browse dependency graph in a web browser\n" " graph output graphviz dot file for targets\n" -" query show inputs/outputs for a path\n" - ); +" query show inputs/outputs for a path\n", + config.parallelism); +} + +int GuessParallelism() { + int processors = 0; + + const char kProcessorPrefix[] = "processor\t"; + char buf[16 << 10]; + FILE* f = fopen("/proc/cpuinfo", "r"); + if (!f) + return 2; + while (fgets(buf, sizeof(buf), f)) { + if (strncmp(buf, kProcessorPrefix, sizeof(kProcessorPrefix) - 1) == 0) + ++processors; + } + fclose(f); + + switch (processors) { + case 0: + case 1: + return 2; + case 2: + return 3; + default: + return processors + 2; + } } struct RealFileReader : public ManifestParser::FileReader { @@ -114,12 +141,17 @@ int main(int argc, char** argv) { const char* input_file = "build.ninja"; string tool; + config.parallelism = GuessParallelism(); + int opt; - while ((opt = getopt_long(argc, argv, "hi:nt:v", options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "hi:j:nt:v", options, NULL)) != -1) { switch (opt) { case 'i': input_file = optarg; break; + case 'j': + config.parallelism = atoi(optarg); + break; case 'n': config.dry_run = true; break; @@ -131,13 +163,13 @@ int main(int argc, char** argv) { break; case 'h': default: - usage(); + usage(config); return 1; } } if (optind >= argc) { fprintf(stderr, "expected target to build\n"); - usage(); + usage(config); return 1; } argv += optind; -- 2.7.4