From patchwork Tue Oct 31 16:21:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Bunt X-Patchwork-Id: 78831 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E03FF3858022 for ; Tue, 31 Oct 2023 16:21:44 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by sourceware.org (Postfix) with ESMTPS id 021D03858C35 for ; Tue, 31 Oct 2023 16:21:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 021D03858C35 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 021D03858C35 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::32f ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698769292; cv=none; b=jr7Yvr1U6yvVtue51e+iRuv7A8ajUkF1So4fFFaWyThXZn5Mc31QLEDEzTCcHf/XHDCgJ51Z9bYv63s8JGVhdEYLCpqQoZFijnB3TyJcfiQYbBSBYvKDPG97ECGc1KBewlllGEZnNGshrXSnTf/JTiWFc/4TBuqomxb4rvHqXGs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698769292; c=relaxed/simple; bh=upYwHa1/9Fn1wICm1hVEE9CxOKh5xSPWB5oCY0WfapA=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=Ms8NaHvw+4qNN8OBpIRC1huEl0hQ/MawxQqIbWbTk15VrkypUUONz2OPDBu2XbjBJrgPKviGr4/x/L78/TJ0Nz8G7qyDy6onzl+YlBSEbJ4crLMSWZTJmdafflyWSCc6iyls7y3cZtHVA6nFdsSUFo6ElKQgSCf3ttXc4JphRO8= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-wm1-x32f.google.com with SMTP id 5b1f17b1804b1-408002b5b9fso42186565e9.3 for ; Tue, 31 Oct 2023 09:21:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1698769290; x=1699374090; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=+H7cB1woxqm5GzLGxkR1ZcE5BWSX4WwMA1+d+jQPf8o=; b=qTikKc/tmke+G1i0UoGo150xvz3/B3MqdXo6mdKSOoc2n5u4nkm1ewk6t6s6H7KBTd d4Wd1H85qAE86nxLnO5N9k9Vxw/c0CbDa7TJUkimyQ7MScn3ehYRJ2LnRmAn4dn04tYJ S1wIAHTQsw/Jng05U8TrIyOU07E1N7NihVWFlsy+gHVlBgv5K/va6Be++g/BTZZxZr6m JsYrsN/8a2QYZMGWzCLJIqDfHRvRWCeSESAoBMMC4qGvjELmUCZIkhh2sIIHCoAcCd2q qn9RkaTkXrIDlvp15InNKQMhleNPK6iYG/w6n+0c9v/4gVeHLr1jOHZX+SXM+tP/KcUZ nPyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698769290; x=1699374090; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=+H7cB1woxqm5GzLGxkR1ZcE5BWSX4WwMA1+d+jQPf8o=; b=BrNGMnPNJ2sI2sQmHl1X8cjKDl6TomItMjDcfz3xK9lWphBjS40PglUjTFHyzC6lp3 ppPppuGU+Ny/gZvOgKx6WP0clHeApTTOtYytI2/hAXVJiBoP7+76NoZmXC0CbGoYNO7d uqNLdInwgqu8ym5ASphiAipTsFTDZGQdZn2O5wLRaf1tq4tR9owJIXXsHj8y9vaDiZeg 77MyqvFdBfqqe2+CSp2tb+IKSCpSInv+vYYN/3W3h0/BIiyp/lTb/piDwuREChEYZ0ir uO+l7mc0Z1posIMt4m/D/IRvgVWWq5bUo+LIsUOibBWqVPzb0eCHbTb5QkWuJKifmBRh uV9w== X-Gm-Message-State: AOJu0Yywn1yCYnEnfAGFhUxSBOaOjBjSu+tzYMXNFpuwRMVgHGnFNAyG vCSWTFi7J0/N4prANX5SuPseemjP2dPEcSWm33I= X-Google-Smtp-Source: AGHT+IHJkgItXkM1SF5WKZGG3drVUk0qpmaKVYr9TxbQrmwt4fvcehGQypMDwHA2GZD3c88U1lOAFQ== X-Received: by 2002:a05:600c:474f:b0:405:359a:c965 with SMTP id w15-20020a05600c474f00b00405359ac965mr10941885wmo.4.1698769289538; Tue, 31 Oct 2023 09:21:29 -0700 (PDT) Received: from whitegate.warwick.linaro.com ([130.43.161.185]) by smtp.gmail.com with ESMTPSA id p12-20020a05600c358c00b004060f0a0fd5sm2192623wmq.13.2023.10.31.09.21.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Oct 2023 09:21:29 -0700 (PDT) From: Richard Bunt To: gdb-patches@sourceware.org Cc: Richard Bunt Subject: [PATCH v3] gdb: Enable early init of thread pool size Date: Tue, 31 Oct 2023 16:21:24 +0000 Message-Id: <20231031162124.2997493-1-richard.bunt@linaro.org> X-Mailer: git-send-email 2.32.0 MIME-Version: 1.0 X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org This commit enables the early initialization commands (92e4e97a9f5) to modify the number of threads used by gdb's thread pool. The motivation here is to prevent gdb from spawning a detrimental number of threads on many-core systems under environments with restrictive ulimits. With gdb before this commit, the thread pool takes the following sizes: 1. Thread pool size is initialized to 0. 2. After the maintenance commands are defined, the thread pool size is set to the number of system cores (if it has not already been set). 3. Using early initialization commands, the thread pool size can be changed using "maint set worker-threads". 4. After the first prompt, the thread pool size can be changed as in the previous step. Therefore after step 2. gdb has potentially launched hundreds of threads on a many-core system. After this change, step 2 and 3 are reversed so there is an opportunity to set the required number of threads without needing to default to the number of system cores first. There does exist a configure option (added in 261b07488b9) to disable multithreading, but this does not allow for an already deployed gdb to be configured. GDB built with GCC 13. No test suite regressions detected. Compilers: GCC, ACfL, Intel, Intel LLVM, NVHPC; Platforms: x86_64, aarch64. The scenario that interests me the most involves preventing GDB from spawning any worker threads at all. This was tested by counting the number of clones observed by strace: strace -e clone,clone3 gdb/gdb -q \ --early-init-eval-command="maint set worker-threads 0" \ -ex q ./gdb/gdb |& grep --count clone The new test relies on "gdb: install CLI uiout while processing early init files" developed by Andrew Burgess. This patch will need pushing prior to this change. --- gdb/main.c | 4 +++ gdb/maint.c | 7 ++-- gdb/maint.h | 4 +++ gdb/testsuite/gdb.base/early-init-file.exp | 40 ++++++++++++++++++++++ gdbsupport/thread-pool.cc | 4 +++ gdbsupport/thread-pool.h | 1 + 6 files changed, 56 insertions(+), 4 deletions(-) diff --git a/gdb/main.c b/gdb/main.c index 10f07be9259..5745affad3c 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -1058,6 +1058,10 @@ captured_main_1 (struct captured_main_args *context) execute_cmdargs (&cmdarg_vec, CMDARG_EARLYINIT_FILE, CMDARG_EARLYINIT_COMMAND, &ret); + /* Set the thread pool size here, so the size can be influenced by the + early initialization commands. */ + update_thread_pool_size (); + /* Initialize the extension languages. */ ext_lang_initialization (); diff --git a/gdb/maint.c b/gdb/maint.c index 0635af3dfc4..bf89d5c792c 100644 --- a/gdb/maint.c +++ b/gdb/maint.c @@ -844,8 +844,9 @@ maintenance_set_profile_cmd (const char *args, int from_tty, static int n_worker_threads = -1; -/* Update the thread pool for the desired number of threads. */ -static void +/* See maint.h. */ + +void update_thread_pool_size () { #if CXX_STD_THREAD @@ -1474,6 +1475,4 @@ such as demangling symbol names."), maintenance_selftest_option_defs, &set_selftest_cmdlist, &show_selftest_cmdlist); - - update_thread_pool_size (); } diff --git a/gdb/maint.h b/gdb/maint.h index 1741d132567..2ec2493d43d 100644 --- a/gdb/maint.h +++ b/gdb/maint.h @@ -26,6 +26,10 @@ extern void set_per_command_time (int); extern void set_per_command_space (int); +/* Update the thread pool for the desired number of threads. */ + +extern void update_thread_pool_size (); + /* Records a run time and space usage to be used as a base for reporting elapsed time or change in space. */ diff --git a/gdb/testsuite/gdb.base/early-init-file.exp b/gdb/testsuite/gdb.base/early-init-file.exp index 6426da8dacf..996d8d38b04 100644 --- a/gdb/testsuite/gdb.base/early-init-file.exp +++ b/gdb/testsuite/gdb.base/early-init-file.exp @@ -99,6 +99,25 @@ proc check_gdb_startups_up_quietly { message } { } } +# Restart GDB and check that the size of the thread pool has not been +# adjusted to match the number of machine cores at early init time. +proc check_gdb_maint_show { message } { + global gdb_prompt + global gdb_sanitizer_msg_re + gdb_exit + gdb_spawn + set setshowprefix "The number of worker threads GDB can use is" + set unset "$setshowprefix unlimited \\\(currently 0\\\)." + set final "$setshowprefix 1." + # Output when CXX_STD_THREAD is undefined. + set off "$setshowprefix 0." + gdb_test_multiple "" $message { + -re "^(${gdb_sanitizer_msg_re})?($unset|$off)\r\n($final|$off)\r\n$gdb_prompt $" { + pass $gdb_test_name + } + } +} + with_ansi_styling_terminal { # Start GDB and confirm that the version string is styled. @@ -164,4 +183,25 @@ with_ansi_styling_terminal { check_gdb_startups_up_quietly \ "check GDB starts quietly using XDG_CONFIG_HOME" } + + # Create fake home directory for the thread pool size check. + set dirs [setup_home_directories "maint-show" \ + [multi_line_input \ + "set startup-quietly on" \ + "maint show worker-threads" \ + "maint set worker-threads 1" \ + "maint show worker-threads"]] + + set home_dir [lindex $dirs 0] + + # Now arrange to use the fake home directory startup file. + save_vars { INTERNAL_GDBFLAGS env(HOME) env(XDG_CONFIG_HOME) } { + set INTERNAL_GDBFLAGS [string map {"-nx" "" "-q" ""} $INTERNAL_GDBFLAGS] + + # Now test GDB when using the HOME directory. + set env(HOME) $home_dir + unset -nocomplain env(XDG_CONFIG_HOME) + check_gdb_maint_show \ + "check early init of thread pool size" + } } diff --git a/gdbsupport/thread-pool.cc b/gdbsupport/thread-pool.cc index 1c871ed378f..a08afc37009 100644 --- a/gdbsupport/thread-pool.cc +++ b/gdbsupport/thread-pool.cc @@ -154,6 +154,7 @@ thread_pool::set_thread_count (size_t num_threads) { #if CXX_STD_THREAD std::lock_guard guard (m_tasks_mutex); + m_sized_at_least_once = true; /* If the new size is larger, start some new threads. */ if (m_thread_count < num_threads) @@ -197,6 +198,9 @@ thread_pool::set_thread_count (size_t num_threads) void thread_pool::do_post_task (std::packaged_task &&func) { + /* This assert is here to check that no tasks are posted to the pool between + its initialization and sizing. */ + gdb_assert (m_sized_at_least_once); std::packaged_task t (std::move (func)); if (m_thread_count != 0) diff --git a/gdbsupport/thread-pool.h b/gdbsupport/thread-pool.h index cb8696e1fa4..3d578e9c241 100644 --- a/gdbsupport/thread-pool.h +++ b/gdbsupport/thread-pool.h @@ -204,6 +204,7 @@ class thread_pool between the main thread and the worker threads. */ std::condition_variable m_tasks_cv; std::mutex m_tasks_mutex; + bool m_sized_at_least_once = false; #endif /* CXX_STD_THREAD */ };