Skip to content

Commit

Permalink
Introduce NumCpusMaybe() method.
Browse files Browse the repository at this point in the history
This returns std::nullopt when /sys cannot be read to determine the number of
CPUs.  In a subsequent change, we can check this first and turn off per-CPU
caches when we cannot accurately determine the maximum possible CPU ID we will
see.   See issue #245.

PiperOrigin-RevId: 667653028
Change-Id: I70e8126cb71b82d94bcd7da90e15ee16b0b69a8a
  • Loading branch information
ckennelly authored and copybara-github committed Aug 26, 2024
1 parent 72c607e commit 8369baf
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 8 deletions.
2 changes: 2 additions & 0 deletions tcmalloc/internal/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,7 @@ cc_library(
hdrs = ["sysinfo.h"],
copts = TCMALLOC_DEFAULT_COPTS,
visibility = [
"//tcmalloc:__pkg__",
"//tcmalloc:__subpackages__",
],
deps = [
Expand Down Expand Up @@ -1038,6 +1039,7 @@ cc_library(
hdrs = ["util.h"],
copts = TCMALLOC_DEFAULT_COPTS,
visibility = [
"//tcmalloc:__pkg__",
"//tcmalloc:__subpackages__",
],
deps = [
Expand Down
13 changes: 10 additions & 3 deletions tcmalloc/internal/sysinfo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ std::optional<CpuSet> ParseCpulist(

namespace sysinfo_internal {

int NumPossibleCPUsNoCache() {
std::optional<int> NumPossibleCPUsNoCache() {
int fd = signal_safe_open("/sys/devices/system/cpu/possible",
O_RDONLY | O_CLOEXEC);

Expand All @@ -121,14 +121,21 @@ int NumPossibleCPUsNoCache() {

signal_safe_close(fd);

TC_CHECK(cpus.has_value());
if (!cpus.has_value()) {
return std::nullopt;
}

std::optional<int> max_so_far;
for (int i = 0; i < kMaxCpus; ++i) {
if (cpus->IsSet(i)) {
max_so_far = std::max(i, max_so_far.value_or(-1));
}
}
TC_CHECK(max_so_far.has_value());

if (!max_so_far.has_value()) {
return std::nullopt;
}

return *max_so_far + 1;
}

Expand Down
15 changes: 11 additions & 4 deletions tcmalloc/internal/sysinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "absl/functional/function_ref.h"
#include "tcmalloc/internal/config.h"
#include "tcmalloc/internal/cpu_utils.h"
#include "tcmalloc/internal/logging.h"

GOOGLE_MALLOC_SECTION_BEGIN
namespace tcmalloc {
Expand All @@ -49,22 +50,28 @@ std::optional<CpuSet> ParseCpulist(
namespace sysinfo_internal {

// Returns the number of possible CPUs on the machine, including currently
// offline CPUs.
// offline CPUs. If this cannot be retrieved, std::nullopt is returned.
//
// The result of this function is not cached internally.
int NumPossibleCPUsNoCache();
std::optional<int> NumPossibleCPUsNoCache();

} // namespace sysinfo_internal
#endif // __linux__

inline int NumCPUs() {
inline std::optional<int> NumCPUsMaybe() {
ABSL_CONST_INIT static absl::once_flag flag;
ABSL_CONST_INIT static int result;
ABSL_CONST_INIT static std::optional<int> result;
absl::base_internal::LowLevelCallOnce(
&flag, [&]() { result = sysinfo_internal::NumPossibleCPUsNoCache(); });
return result;
}

inline int NumCPUs() {
std::optional<int> maybe_cpus = NumCPUsMaybe();
TC_CHECK(maybe_cpus.has_value());
return *maybe_cpus;
}

} // namespace tcmalloc_internal
} // namespace tcmalloc
GOOGLE_MALLOC_SECTION_END
Expand Down
2 changes: 1 addition & 1 deletion tcmalloc/internal/sysinfo_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ TEST(ParseCpulistTest, Random) {
TEST(NumCPUs, NoCache) {
const int result = []() {
AllocationGuard guard;
return sysinfo_internal::NumPossibleCPUsNoCache();
return *sysinfo_internal::NumPossibleCPUsNoCache();
}();

// TODO(b/67389555): This test may fail if there are offlined CPUs.
Expand Down

0 comments on commit 8369baf

Please sign in to comment.