From 40dbcc34087d11e6840d00b85295c961a62518a4 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Tue, 22 Sep 2015 23:21:51 +0200 Subject: [PATCH] Added --jobs CLI switch and CRITERION_JOBS environment variable --- CMakeLists.txt | 2 ++ include/criterion/options.h | 1 + samples/CMakeLists.txt | 2 ++ src/compat/internal.h | 5 ++++ src/compat/posix.h | 1 - src/compat/processor.c | 54 +++++++++++++++++++++++++++++++++++++ src/compat/processor.h | 31 +++++++++++++++++++++ src/core/runner.c | 3 ++- src/entry/main.c | 14 +++++++--- 9 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 src/compat/processor.c create mode 100644 src/compat/processor.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1406874..4a51244 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,6 +104,8 @@ set(SOURCE_FILES src/compat/posix.h src/compat/alloc.c src/compat/alloc.h + src/compat/processor.c + src/compat/processor.h src/io/redirect.c src/io/event.c src/io/event.h diff --git a/include/criterion/options.h b/include/criterion/options.h index 0bdcdee..49c0548 100644 --- a/include/criterion/options.h +++ b/include/criterion/options.h @@ -36,6 +36,7 @@ struct criterion_options { bool fail_fast; const char *pattern; bool short_filename; + size_t jobs; }; CR_BEGIN_C_API diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index a80f1af..dfba5a0 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -65,6 +65,7 @@ macro(add_samples DIR_ SAMPLES_) ENVIRONMENT "CRITERION_ALWAYS_SUCCEED=1" ENVIRONMENT "CRITERION_SHORT_FILENAME=1" ENVIRONMENT "CRITERION_NO_EARLY_EXIT=1" # for coverage + ENVIRONMENT "CRITERION_JOBS=1" # for output ordering ) endif () endforeach() @@ -87,6 +88,7 @@ foreach(script ${SCRIPTS}) ENVIRONMENT "CRITERION_ALWAYS_SUCCEED=1" ENVIRONMENT "CRITERION_SHORT_FILENAME=1" ENVIRONMENT "CRITERION_NO_EARLY_EXIT=1" # for coverage + ENVIRONMENT "CRITERION_JOBS=1" # for output ordering ) endforeach() diff --git a/src/compat/internal.h b/src/compat/internal.h index 29b73ab..fd5e8af 100644 --- a/src/compat/internal.h +++ b/src/compat/internal.h @@ -40,6 +40,11 @@ # include # include # include +# include +# ifdef BSD +# include +# include +# endif # endif # include "posix.h" diff --git a/src/compat/posix.h b/src/compat/posix.h index 930225a..043562d 100644 --- a/src/compat/posix.h +++ b/src/compat/posix.h @@ -55,7 +55,6 @@ # define SIGPROF 27 # define CR_EXCEPTION_TIMEOUT 0xC0001042 # else -# include # include # endif diff --git a/src/compat/processor.c b/src/compat/processor.c new file mode 100644 index 0000000..b0f5244 --- /dev/null +++ b/src/compat/processor.c @@ -0,0 +1,54 @@ +/* + * The MIT License (MIT) + * + * Copyright © 2015 Franklin "Snaipe" Mathieu + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "internal.h" + +size_t get_processor_count(void) { +#ifdef _WIN32 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + + return (size_t) sysinfo.dwNumberOfProcessors; +#elif defined(BSD) + int mib[2] = { CTL_HW, HW_AVAILCPU }; + long long count; + size_t len = sizeof (count); + + /* get the number of CPUs from the system */ + sysctl(mib, 2, &count, &len, NULL, 0); + + if (count < 1) { + mib[1] = HW_NCPU; + sysctl(mib, 2, &count, &len, NULL, 0); + + if (count < 1) + count = 1; + } + return (size_t) count; +#elif defined(__linux__) + return sysconf(_SC_NPROCESSORS_ONLN); +#else +# error System not supported +#endif +} diff --git a/src/compat/processor.h b/src/compat/processor.h new file mode 100644 index 0000000..5e6e35b --- /dev/null +++ b/src/compat/processor.h @@ -0,0 +1,31 @@ +/* + * The MIT License (MIT) + * + * Copyright © 2015 Franklin "Snaipe" Mathieu + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef COMPAT_PROCESSOR_H_ +# define COMPAT_PROCESSOR_H_ + +# include + +size_t get_processor_count(void); + +#endif /* !COMPAT_PROCESSOR_H_ */ diff --git a/src/core/runner.c b/src/core/runner.c index 3817bc6..2a29c48 100644 --- a/src/core/runner.c +++ b/src/core/runner.c @@ -30,6 +30,7 @@ #include "criterion/logging.h" #include "compat/time.h" #include "compat/posix.h" +#include "compat/processor.h" #include "string/i18n.h" #include "io/event.h" #include "stats.h" @@ -464,7 +465,7 @@ static void run_tests_async(struct criterion_test_set *set, ccrContext ctx = 0; - size_t nb_workers = 1; + size_t nb_workers = DEF(criterion_options.jobs, get_processor_count()); struct worker_set workers = { .max_workers = nb_workers, .workers = calloc(nb_workers, sizeof (struct process*)), diff --git a/src/entry/main.c b/src/entry/main.c index 5551886..6fb0787 100644 --- a/src/entry/main.c +++ b/src/entry/main.c @@ -120,6 +120,11 @@ int list_tests(bool unicode) { return 0; } +int atou(const char *str) { + int res = atoi(str); + return res < 0 ? 0 : res; +} + int criterion_handle_args(int argc, char *argv[], bool handle_unknown_arg) { static struct option opts[] = { {"verbose", optional_argument, 0, 'b'}, @@ -128,6 +133,7 @@ int criterion_handle_args(int argc, char *argv[], bool handle_unknown_arg) { {"help", no_argument, 0, 'h'}, {"list", no_argument, 0, 'l'}, {"ascii", no_argument, 0, 'k'}, + {"jobs", required_argument, 0, 'j'}, {"fail-fast", no_argument, 0, 'f'}, {"short-filename", no_argument, 0, 'S'}, #ifdef HAVE_PCRE @@ -151,7 +157,8 @@ int criterion_handle_args(int argc, char *argv[], bool handle_unknown_arg) { opt->no_early_exit = !strcmp("1", DEF(getenv("CRITERION_NO_EARLY_EXIT") , "0")); opt->fail_fast = !strcmp("1", DEF(getenv("CRITERION_FAIL_FAST") , "0")); opt->use_ascii = use_ascii; - opt->logging_threshold = atoi(DEF(getenv("CRITERION_VERBOSITY_LEVEL"), "2")); + opt->jobs = atou(DEF(getenv("CRITERION_JOBS"), "0")); + opt->logging_threshold = atou(DEF(getenv("CRITERION_VERBOSITY_LEVEL"), "2")); opt->short_filename = !strcmp("1", DEF(getenv("CRITERION_SHORT_FILENAME"), "0")); #ifdef HAVE_PCRE opt->pattern = getenv("CRITERION_TEST_PATTERN"); @@ -162,12 +169,13 @@ int criterion_handle_args(int argc, char *argv[], bool handle_unknown_arg) { bool do_list_tests = false; bool do_print_version = false; bool do_print_usage = false; - for (int c; (c = getopt_long(argc, argv, "hvlfS", opts, NULL)) != -1;) { + for (int c; (c = getopt_long(argc, argv, "hvlfj:S", opts, NULL)) != -1;) { switch (c) { - case 'b': criterion_options.logging_threshold = atoi(DEF(optarg, "1")); break; + case 'b': criterion_options.logging_threshold = atou(DEF(optarg, "1")); break; case 'y': criterion_options.always_succeed = true; break; case 'z': criterion_options.no_early_exit = true; break; case 'k': criterion_options.use_ascii = true; break; + case 'j': criterion_options.jobs = atou(optarg); break; case 'f': criterion_options.fail_fast = true; break; case 'S': criterion_options.short_filename = true; break; #ifdef HAVE_PCRE