From c55bfae9dda24a060e3d6e694eb19c50c941d82d Mon Sep 17 00:00:00 2001 From: Ti Chi Robot Date: Thu, 21 Nov 2024 18:05:26 +0800 Subject: [PATCH] Fix the fail start of tiflash because of the zero division when getting cpu number (#9602) (#9626) close pingcap/tiflash#9212 Signed-off-by: ti-chi-bot Co-authored-by: xzhangxian1008 --- dbms/src/Common/getNumberOfCPUCores.cpp | 8 +++- dbms/src/Common/tests/gtest_miscellaneous.cpp | 46 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 dbms/src/Common/tests/gtest_miscellaneous.cpp diff --git a/dbms/src/Common/getNumberOfCPUCores.cpp b/dbms/src/Common/getNumberOfCPUCores.cpp index 4c2ebc9ddd4..412c2096216 100644 --- a/dbms/src/Common/getNumberOfCPUCores.cpp +++ b/dbms/src/Common/getNumberOfCPUCores.cpp @@ -44,6 +44,8 @@ void setNumberOfLogicalCPUCores(UInt16 number_of_logical_cpu_cores_) void computeAndSetNumberOfPhysicalCPUCores(UInt16 number_of_logical_cpu_cores_, UInt16 number_of_hardware_physical_cores) { + number_of_hardware_physical_cores = std::max(1, number_of_hardware_physical_cores); + // First of all, we need to take consideration of two situation: // 1. tiflash on physical machine. // In old codes, tiflash needs to set max_threads which is equal to @@ -60,7 +62,11 @@ void computeAndSetNumberOfPhysicalCPUCores(UInt16 number_of_logical_cpu_cores_, // - `(hardware_logical_cpu_cores / number_of_hardware_physical_cores)` means how many logical cpu core a physical cpu core has. // - `number_of_logical_cpu_cores_ / (hardware_logical_cpu_cores / number_of_hardware_physical_cores)` means how many physical cpu cores the tiflash process could use. (Actually, it's needless to get physical cpu cores in virtual environment, but we must ensure the behavior `1` is not broken) auto hardware_logical_cpu_cores = std::thread::hardware_concurrency(); - UInt16 physical_cpu_cores = number_of_logical_cpu_cores_ / (hardware_logical_cpu_cores / number_of_hardware_physical_cores); + + UInt16 thread_num_per_physical_core = hardware_logical_cpu_cores / number_of_hardware_physical_cores; + thread_num_per_physical_core = std::max(1, thread_num_per_physical_core); + + UInt16 physical_cpu_cores = number_of_logical_cpu_cores_ / thread_num_per_physical_core; CPUCores::number_of_physical_cpu_cores = physical_cpu_cores > 0 ? physical_cpu_cores : 1; LOG_INFO( DB::Logger::get(), diff --git a/dbms/src/Common/tests/gtest_miscellaneous.cpp b/dbms/src/Common/tests/gtest_miscellaneous.cpp new file mode 100644 index 00000000000..e4b06ba3748 --- /dev/null +++ b/dbms/src/Common/tests/gtest_miscellaneous.cpp @@ -0,0 +1,46 @@ +// Copyright 2024 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +namespace DB +{ +namespace tests +{ + +TEST(CommonMiscellaneousTest, cpuRelated) +{ + auto hardware_logical_cpu_cores = std::thread::hardware_concurrency(); + UInt16 number_of_logical_cpu_cores = std::thread::hardware_concurrency(); + + computeAndSetNumberOfPhysicalCPUCores(number_of_logical_cpu_cores, hardware_logical_cpu_cores); + ASSERT_EQ(getNumberOfPhysicalCPUCores(), hardware_logical_cpu_cores); + + computeAndSetNumberOfPhysicalCPUCores(number_of_logical_cpu_cores, 0); + ASSERT_EQ(1, getNumberOfPhysicalCPUCores()); + + UInt16 test_num = 123; + computeAndSetNumberOfPhysicalCPUCores(test_num, hardware_logical_cpu_cores * 2); + ASSERT_EQ(test_num, getNumberOfPhysicalCPUCores()); + + computeAndSetNumberOfPhysicalCPUCores(1, hardware_logical_cpu_cores * 2); + ASSERT_EQ(1, getNumberOfPhysicalCPUCores()); + + computeAndSetNumberOfPhysicalCPUCores(0, hardware_logical_cpu_cores); + ASSERT_EQ(1, getNumberOfPhysicalCPUCores()); +} + +} // namespace tests +} // namespace DB