From 5b677472141b5a33767e4cf0e3fd23bd26125ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Mon, 4 Nov 2019 23:00:01 +0000 Subject: [PATCH] cpp: parametrize nthreads on threaded programs CLI Mark them as multithreaded in path_properties. Preparation for https://cirosantilli.com/linux-kernel-module-cheat/#user-mode-static-executables-with-dynamic-libraries which is likely what breaks gem5 on them. --- path_properties.py | 8 +++++--- userland/cpp/thread_get_id.cpp | 22 +++++++++++++++++++--- userland/cpp/thread_return_value.cpp | 21 +++++++++++++++++---- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/path_properties.py b/path_properties.py index 4d35371..3bc7a0b 100644 --- a/path_properties.py +++ b/path_properties.py @@ -515,12 +515,14 @@ path_properties_tuples = ( 'gem5_unimplemented_instruction': True, }, 'count.cpp': {'more_than_1s': True}, - # Need to pass -lstdc++fs but we don't have a mechanism - # to test the GCC version and only pass if >= 7. - 'temporary_directory.cpp': {'no_build': True}, 'sleep_for.cpp': { 'more_than_1s': True, }, + # Need to pass -lstdc++fs but we don't have a mechanism + # to test the GCC version and only pass if >= 7. + 'temporary_directory.cpp': {'no_build': True}, + 'thread_get_id.cpp': {'test_run_args': {'cpus': 2}}, + 'thread_return_value.cpp': {'test_run_args': {'cpus': 2}}, }, ), 'gcc': ( diff --git a/userland/cpp/thread_get_id.cpp b/userland/cpp/thread_get_id.cpp index 3d45e97..0e1099b 100644 --- a/userland/cpp/thread_get_id.cpp +++ b/userland/cpp/thread_get_id.cpp @@ -4,6 +4,7 @@ // // On Ubuntu 19.04, they ar large possibly non-consecutive numbers. +#include #include #include #include @@ -12,15 +13,30 @@ std::mutex mutex; void myfunc(int i) { + // Mutex and flush to prevent the output from + // different threads from interleaving. mutex.lock(); - std::cout << i << " " << std::this_thread::get_id() << std::endl; + std::cout << + i << " " << + std::this_thread::get_id() << std::endl + << std::flush; mutex.unlock(); } -int main() { +int main(int argc, char **argv) { std::cout << "main " << std::this_thread::get_id() << std::endl; std::vector threads; - for (unsigned int i = 0; i < 4; ++i) { + unsigned int nthreads; + + // CLI arguments. + if (argc > 1) { + nthreads = std::strtoll(argv[1], NULL, 0); + } else { + nthreads = 1; + } + + // Action. + for (unsigned int i = 0; i < nthreads; ++i) { threads.push_back(std::thread(myfunc, i)); } for (auto& thread : threads) { diff --git a/userland/cpp/thread_return_value.cpp b/userland/cpp/thread_return_value.cpp index 4f2249c..9d500ce 100644 --- a/userland/cpp/thread_return_value.cpp +++ b/userland/cpp/thread_return_value.cpp @@ -20,10 +20,23 @@ void myfunc_reference(int& i) { i = myfunc(i); } -int main() { - unsigned int nthreads = 4; - std::vector inputs{1, 2, 3, 4}; - std::vector outputs_expect{2, 3, 4, 5}; +int main(int argc, char **argv) { + unsigned int nthreads; + + // CLI arguments. + if (argc > 1) { + nthreads = std::strtoll(argv[1], NULL, 0); + } else { + nthreads = 1; + } + + // Setup inputs and expected outputs. + std::vector inputs; + std::vector outputs_expect; + for (unsigned int i = 0; i < nthreads; ++i) { + inputs.push_back(i); + outputs_expect.push_back(myfunc(i)); + } // future and sync. Nirvana. When you are not fighting to death with types: // https://stackoverflow.com/questions/10620300/can-stdasync-be-use-with-template-functions