Skip to content

Commit 7628abd

Browse files
authored
[scudo] Add tracing framework (#156112)
Add a methodology to allow tracing. By default, this is disabled, but it can be enabled for any OS that supports it. Currently, only releaseToOSXXX functions have trace points added.
1 parent a3a2599 commit 7628abd

File tree

5 files changed

+73
-4
lines changed

5 files changed

+73
-4
lines changed

compiler-rt/lib/scudo/standalone/combined.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "size_class_allocator.h"
2626
#include "stack_depot.h"
2727
#include "string_utils.h"
28+
#include "tracing.h"
2829
#include "tsd.h"
2930

3031
#include "scudo/interface.h"
@@ -671,10 +672,11 @@ class Allocator {
671672

672673
void releaseToOS(ReleaseToOS ReleaseType) {
673674
initThreadMaybe();
675+
SCUDO_SCOPED_TRACE(GetReleaseToOSTraceName(ReleaseType));
674676
if (ReleaseType == ReleaseToOS::ForceAll)
675677
drainCaches();
676678
Primary.releaseToOS(ReleaseType);
677-
Secondary.releaseToOS();
679+
Secondary.releaseToOS(ReleaseType);
678680
}
679681

680682
// Iterate over all chunks and call a callback for all busy chunks located

compiler-rt/lib/scudo/standalone/primary32.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,8 @@ uptr SizeClassAllocator32<Config>::tryReleaseToOS(uptr ClassId,
511511

512512
template <typename Config>
513513
uptr SizeClassAllocator32<Config>::releaseToOS(ReleaseToOS ReleaseType) {
514+
SCUDO_SCOPED_TRACE(GetPrimaryReleaseToOSTraceName(ReleaseType));
515+
514516
uptr TotalReleasedBytes = 0;
515517
for (uptr I = 0; I < NumClasses; I++) {
516518
if (I == SizeClassMap::BatchClassId)
@@ -1056,6 +1058,8 @@ uptr SizeClassAllocator32<Config>::releaseToOSMaybe(SizeClassInfo *Sci,
10561058
uptr ClassId,
10571059
ReleaseToOS ReleaseType)
10581060
REQUIRES(Sci->Mutex) {
1061+
SCUDO_SCOPED_TRACE(GetPrimaryReleaseToOSMaybeTraceName(ReleaseType));
1062+
10591063
const uptr BlockSize = getSizeByClassId(ClassId);
10601064

10611065
DCHECK_GE(Sci->FreeListInfo.PoppedBlocks, Sci->FreeListInfo.PushedBlocks);

compiler-rt/lib/scudo/standalone/primary64.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "stats.h"
2323
#include "string_utils.h"
2424
#include "thread_annotations.h"
25+
#include "tracing.h"
2526

2627
namespace scudo {
2728

@@ -1307,6 +1308,8 @@ uptr SizeClassAllocator64<Config>::tryReleaseToOS(uptr ClassId,
13071308

13081309
template <typename Config>
13091310
uptr SizeClassAllocator64<Config>::releaseToOS(ReleaseToOS ReleaseType) {
1311+
SCUDO_SCOPED_TRACE(GetPrimaryReleaseToOSTraceName(ReleaseType));
1312+
13101313
uptr TotalReleasedBytes = 0;
13111314
for (uptr I = 0; I < NumClasses; I++) {
13121315
if (I == SizeClassMap::BatchClassId)
@@ -1376,6 +1379,8 @@ uptr SizeClassAllocator64<Config>::releaseToOSMaybe(RegionInfo *Region,
13761379
uptr ClassId,
13771380
ReleaseToOS ReleaseType)
13781381
REQUIRES(Region->MMLock) EXCLUDES(Region->FLLock) {
1382+
SCUDO_SCOPED_TRACE(GetPrimaryReleaseToOSMaybeTraceName(ReleaseType));
1383+
13791384
const uptr BlockSize = getSizeByClassId(ClassId);
13801385
uptr BytesInFreeList;
13811386
const uptr AllocatedUserEnd =

compiler-rt/lib/scudo/standalone/secondary.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "stats.h"
2020
#include "string_utils.h"
2121
#include "thread_annotations.h"
22+
#include "tracing.h"
2223
#include "vector.h"
2324

2425
namespace scudo {
@@ -118,7 +119,7 @@ template <typename Config> class MapAllocatorNoCache {
118119
bool canCache(UNUSED uptr Size) { return false; }
119120
void disable() {}
120121
void enable() {}
121-
void releaseToOS() {}
122+
void releaseToOS(ReleaseToOS) {}
122123
void disableMemoryTagging() {}
123124
void unmapTestOnly() {}
124125
bool setOption(Option O, UNUSED sptr Value) {
@@ -351,6 +352,9 @@ class MapAllocatorCache {
351352
// same time will not actually release any extra elements. Therefore,
352353
// let any other thread continue, skipping the release.
353354
if (Mutex.tryLock()) {
355+
SCUDO_SCOPED_TRACE(
356+
GetSecondaryReleaseToOSTraceName(ReleaseToOS::Normal));
357+
354358
// TODO: Add ReleaseToOS logic to LRU algorithm
355359
releaseOlderThan(Time - static_cast<u64>(Interval) * 1000000);
356360
Mutex.unlock();
@@ -499,7 +503,9 @@ class MapAllocatorCache {
499503
return true;
500504
}
501505

502-
void releaseToOS() EXCLUDES(Mutex) {
506+
void releaseToOS([[maybe_unused]] ReleaseToOS ReleaseType) EXCLUDES(Mutex) {
507+
SCUDO_SCOPED_TRACE(GetSecondaryReleaseToOSTraceName(ReleaseType));
508+
503509
// Since this is a request to release everything, always wait for the
504510
// lock so that we guarantee all entries are released after this call.
505511
ScopedLock L(Mutex);
@@ -574,6 +580,8 @@ class MapAllocatorCache {
574580
}
575581

576582
void releaseOlderThan(u64 Time) REQUIRES(Mutex) {
583+
SCUDO_SCOPED_TRACE(GetSecondaryReleaseOlderThanTraceName());
584+
577585
if (!LRUEntries.size() || OldestTime == 0 || OldestTime > Time)
578586
return;
579587
OldestTime = 0;
@@ -669,7 +677,7 @@ template <typename Config> class MapAllocator {
669677

670678
bool setOption(Option O, sptr Value) { return Cache.setOption(O, Value); }
671679

672-
void releaseToOS() { Cache.releaseToOS(); }
680+
void releaseToOS(ReleaseToOS ReleaseType) { Cache.releaseToOS(ReleaseType); }
673681

674682
void disableMemoryTagging() { Cache.disableMemoryTagging(); }
675683

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===-- tracing.h -----------------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef SCUDO_TRACING_H_
10+
#define SCUDO_TRACING_H_
11+
12+
#if defined(SCUDO_ENABLE_TRACING)
13+
14+
// This file must include definitions for all of the functions below.
15+
#include "custom_scudo_tracing.h"
16+
17+
#else
18+
19+
// Should start a trace in the given scope, and end the trace when going out of
20+
// scope.
21+
#define SCUDO_SCOPED_TRACE(Name)
22+
23+
// Create a trace name for the call to releaseToOS.
24+
static inline const char *GetReleaseToOSTraceName(scudo::ReleaseToOS) {
25+
return nullptr;
26+
}
27+
28+
// Create a trace name for the call to releaseToOSMaybe in the primary.
29+
static inline const char *
30+
GetPrimaryReleaseToOSMaybeTraceName(scudo::ReleaseToOS) {
31+
return nullptr;
32+
}
33+
34+
static inline const char *GetPrimaryReleaseToOSTraceName(scudo::ReleaseToOS) {
35+
return nullptr;
36+
}
37+
38+
// Create a trace name for the call to releaseToOS in the secondary.
39+
static inline const char *GetSecondaryReleaseToOSTraceName(scudo::ReleaseToOS) {
40+
return nullptr;
41+
}
42+
43+
// Create a trace name for the call to releaseOlderThan in the secondary.
44+
static inline const char *GetSecondaryReleaseOlderThanTraceName() {
45+
return nullptr;
46+
}
47+
48+
#endif
49+
50+
#endif // SCUDO_TRACING_H_

0 commit comments

Comments
 (0)