Skip to content

Commit 339b71d

Browse files
committed
Background house-keeping & pre-existing thread
Break apart ProcessBackgroundActions into an "Init" and "Tick" stage and leave periodic invocation to the caller. This lets users reduce the number of threads spun up by 1 if they already have a background house keeping thread that knows when (& perhaps even how much) memory to free.
1 parent 5d35433 commit 339b71d

File tree

4 files changed

+69
-26
lines changed

4 files changed

+69
-26
lines changed

tcmalloc/background.cc

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -99,43 +99,54 @@ void ShuffleCpuCaches() {
9999
GOOGLE_MALLOC_SECTION_END
100100

101101
// Release memory to the system at a constant rate.
102-
void MallocExtension_Internal_ProcessBackgroundActions() {
103-
tcmalloc::MallocExtension::MarkThreadIdle();
102+
static absl::Time prev_time;
103+
static absl::Time last_shuffle;
104104

105+
void MallocExtension_Internal_ProcessBackgroundActionsInit() {
105106
// Initialize storage for ReleasePerCpuMemoryToOS().
106107
CPU_ZERO(&tcmalloc::tcmalloc_internal::prev_allowed_cpus);
107108

108-
absl::Time prev_time = absl::Now();
109+
prev_time = absl::Now();
110+
last_shuffle = absl::InfinitePast();
111+
}
112+
113+
void MallocExtension_Internal_ProcessBackgroundActions() {
109114
constexpr absl::Duration kSleepTime = absl::Seconds(1);
110115

116+
tcmalloc::MallocExtension::MarkThreadIdle();
117+
MallocExtension_Internal_ProcessBackgroundActionsInit();
118+
119+
while (true) {
120+
MallocExtension_Internal_ProcessBackgroundActionsTick();
121+
absl::SleepFor(kSleepTime);
122+
}
123+
}
124+
125+
void MallocExtension_Internal_ProcessBackgroundActionsTick() {
111126
// Shuffle per-cpu caches once per kCpuCacheShufflePeriod secs.
112127
constexpr absl::Duration kCpuCacheShufflePeriod = absl::Seconds(5);
113-
absl::Time last_shuffle = absl::InfinitePast();
114128

115-
while (true) {
116-
absl::Time now = absl::Now();
117-
const ssize_t bytes_to_release =
118-
static_cast<size_t>(tcmalloc::tcmalloc_internal::Parameters::
119-
background_release_rate()) *
120-
absl::ToDoubleSeconds(now - prev_time);
121-
if (bytes_to_release > 0) { // may be negative if time goes backwards
122-
tcmalloc::MallocExtension::ReleaseMemoryToSystem(bytes_to_release);
123-
}
129+
absl::Time now = absl::Now();
130+
const ssize_t bytes_to_release =
131+
static_cast<size_t>(tcmalloc::tcmalloc_internal::Parameters::
132+
background_release_rate()) *
133+
absl::ToDoubleSeconds(now - prev_time);
134+
if (bytes_to_release > 0) { // may be negative if time goes backwards
135+
tcmalloc::MallocExtension::ReleaseMemoryToSystem(bytes_to_release);
136+
}
124137

125-
tcmalloc::tcmalloc_internal::ReleasePerCpuMemoryToOS();
138+
tcmalloc::tcmalloc_internal::ReleasePerCpuMemoryToOS();
126139

127-
const bool shuffle_per_cpu_caches =
128-
tcmalloc::tcmalloc_internal::Parameters::shuffle_per_cpu_caches();
140+
const bool shuffle_per_cpu_caches =
141+
tcmalloc::tcmalloc_internal::Parameters::shuffle_per_cpu_caches();
129142

130-
if (shuffle_per_cpu_caches) {
131-
if (now - last_shuffle >= kCpuCacheShufflePeriod) {
132-
tcmalloc::tcmalloc_internal::ShuffleCpuCaches();
133-
last_shuffle = now;
134-
}
143+
if (shuffle_per_cpu_caches) {
144+
if (now - last_shuffle >= kCpuCacheShufflePeriod) {
145+
tcmalloc::tcmalloc_internal::ShuffleCpuCaches();
146+
last_shuffle = now;
135147
}
136-
137-
tcmalloc::tcmalloc_internal::Static().sharded_transfer_cache().Plunder();
138-
prev_time = now;
139-
absl::SleepFor(kSleepTime);
140148
}
149+
150+
tcmalloc::tcmalloc_internal::Static().sharded_transfer_cache().Plunder();
151+
prev_time = now;
141152
}

tcmalloc/internal_malloc_extension.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ ABSL_ATTRIBUTE_WEAK void MallocExtension_Internal_SetProfileSamplingRate(
101101
int64_t);
102102

103103
ABSL_ATTRIBUTE_WEAK void MallocExtension_Internal_ProcessBackgroundActions();
104+
ABSL_ATTRIBUTE_WEAK void MallocExtension_Internal_ProcessBackgroundActionsInit();
105+
ABSL_ATTRIBUTE_WEAK void MallocExtension_Internal_ProcessBackgroundActionsTick();
104106

105107
ABSL_ATTRIBUTE_WEAK tcmalloc::MallocExtension::BytesPerSecond
106108
MallocExtension_Internal_GetBackgroundReleaseRate();

tcmalloc/malloc_extension.cc

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,9 +425,26 @@ void MallocExtension::ProcessBackgroundActions() {
425425
#endif
426426
}
427427

428+
void MallocExtension::ProcessBackgroundActionsInit() {
429+
#if ABSL_INTERNAL_HAVE_WEAK_MALLOCEXTENSION_STUBS
430+
if (NeedsProcessBackgroundActions()) {
431+
MallocExtension_Internal_ProcessBackgroundActionsInit();
432+
}
433+
#endif
434+
}
435+
436+
void MallocExtension::ProcessBackgroundActionsTick() {
437+
#if ABSL_INTERNAL_HAVE_WEAK_MALLOCEXTENSION_STUBS
438+
if (NeedsProcessBackgroundActions()) {
439+
MallocExtension_Internal_ProcessBackgroundActionsTick();
440+
}
441+
#endif
442+
}
443+
428444
bool MallocExtension::NeedsProcessBackgroundActions() {
429445
#if ABSL_INTERNAL_HAVE_WEAK_MALLOCEXTENSION_STUBS
430-
return &MallocExtension_Internal_ProcessBackgroundActions != nullptr;
446+
static bool needed = &MallocExtension_Internal_ProcessBackgroundActions != nullptr;
447+
return needed;
431448
#else
432449
return false;
433450
#endif

tcmalloc/malloc_extension.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,19 @@ class MallocExtension final {
433433
// null if the implementation does not support profiling.
434434
static AllocationProfilingToken StartAllocationProfiling();
435435

436+
// Initializes the state needed for this thread to call
437+
// ProcessBackgroundActionsTick. This is the counterpart to
438+
// ProcessBackgroundActions that allows co-operative task keeping on a thread
439+
// that is performing other task keeping.
440+
static void ProcessBackgroundActionsInit();
441+
442+
// This is to be called periodically to run housekeeping actions for the
443+
// allocator off of the main allocation paths of new/delete. Note that unlike
444+
// ProcessBackgroundActions, the thread is not automatically marked as
445+
// idle/busy and the caller is responsible for doing that correctly.
446+
// See ProcessBackgroundActions for details of the actions performed.
447+
static void ProcessBackgroundActionsTick();
448+
436449
// Runs housekeeping actions for the allocator off of the main allocation path
437450
// of new/delete. As of 2020, this includes:
438451
// * Inspecting the current CPU mask and releasing memory from inaccessible

0 commit comments

Comments
 (0)