Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/compiler-rt/lib/ctx_profile/RootAutoDetector.h
213766 views
1
/*===- RootAutodetector.h- auto-detect roots for ctxprof -----------------===*\
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 CTX_PROFILE_ROOTAUTODETECTOR_H_
10
#define CTX_PROFILE_ROOTAUTODETECTOR_H_
11
12
#include "sanitizer_common/sanitizer_dense_map.h"
13
#include "sanitizer_common/sanitizer_internal_defs.h"
14
#include "sanitizer_common/sanitizer_stacktrace.h"
15
#include "sanitizer_common/sanitizer_vector.h"
16
#include <pthread.h>
17
#include <sanitizer/common_interface_defs.h>
18
19
using namespace __asan;
20
using namespace __sanitizer;
21
22
namespace __ctx_profile {
23
24
/// Capture all the stack traces observed for a specific thread. The "for a
25
/// specific thread" part is not enforced, but assumed in determineRoots.
26
class PerThreadCallsiteTrie {
27
protected:
28
/// A trie. A node is the address of a callsite in a function activation. A
29
/// child is a callsite in the activation made from the callsite
30
/// corresponding to the parent.
31
struct Trie final {
32
const uptr CallsiteAddress;
33
uint64_t Count = 0;
34
DenseMap<uptr, Trie> Children;
35
36
Trie(uptr CallsiteAddress = 0) : CallsiteAddress(CallsiteAddress) {}
37
};
38
Trie TheTrie;
39
40
/// Return the runtime start address of the function that contains the call at
41
/// the runtime address CallsiteAddress. May be overriden for easy testing.
42
virtual uptr getFctStartAddr(uptr CallsiteAddress) const;
43
44
public:
45
PerThreadCallsiteTrie(const PerThreadCallsiteTrie &) = delete;
46
PerThreadCallsiteTrie(PerThreadCallsiteTrie &&) = default;
47
PerThreadCallsiteTrie() = default;
48
49
virtual ~PerThreadCallsiteTrie() = default;
50
51
void insertStack(const StackTrace &ST);
52
53
/// Return the runtime address of root functions, as determined for this
54
/// thread, together with the number of samples that included them.
55
DenseMap<uptr, uint64_t> determineRoots() const;
56
};
57
58
class RootAutoDetector final {
59
// A prime number. We may want to make this configurable at collection start.
60
static const uint64_t SampleRate = 6113;
61
const unsigned WaitSeconds;
62
pthread_t WorkerThread;
63
64
struct PerThreadSamples {
65
PerThreadSamples(RootAutoDetector &Parent);
66
67
PerThreadCallsiteTrie TrieRoot;
68
SpinMutex M;
69
};
70
SpinMutex AllSamplesMutex;
71
SANITIZER_GUARDED_BY(AllSamplesMutex)
72
Vector<PerThreadSamples *> AllSamples;
73
atomic_uintptr_t &FunctionDataListHead;
74
atomic_uintptr_t &Self;
75
void collectStack();
76
77
public:
78
RootAutoDetector(atomic_uintptr_t &FunctionDataListHead,
79
atomic_uintptr_t &Self, unsigned WaitSeconds)
80
: WaitSeconds(WaitSeconds), FunctionDataListHead(FunctionDataListHead),
81
Self(Self) {}
82
83
// Samples the stack at `SampleRate` (rate observed independently on each
84
// thread) in thread local `PerThreadCallsiteTrie`s.
85
void sample();
86
87
// Start a thread waiting `WaitSeconds`, after which it uses the
88
// `PerThreadCallsiteTrie` data observed so far over all threads to determine
89
// roots. Marks those roots by traversing the linked list of FunctionData that
90
// starts at `FunctionDataListHead`, and assigning their `CtxRoot`. Finally,
91
// resets the `Self` atomic, so that other threads don't continue calling
92
// `sample`.
93
void start();
94
95
// join the waiting thread.
96
void join();
97
};
98
99
} // namespace __ctx_profile
100
#endif
101
102