|*
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|* See https://llvm.org/LICENSE.txt for license information.
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|*
\*===----------------------------------------------------------------------===*/
#ifndef CTX_PROFILE_ROOTAUTODETECTOR_H_
#define CTX_PROFILE_ROOTAUTODETECTOR_H_
#include "sanitizer_common/sanitizer_dense_map.h"
#include "sanitizer_common/sanitizer_internal_defs.h"
#include "sanitizer_common/sanitizer_stacktrace.h"
#include "sanitizer_common/sanitizer_vector.h"
#include <pthread.h>
#include <sanitizer/common_interface_defs.h>
using namespace __asan;
using namespace __sanitizer;
namespace __ctx_profile {
class PerThreadCallsiteTrie {
protected:
struct Trie final {
const uptr CallsiteAddress;
uint64_t Count = 0;
DenseMap<uptr, Trie> Children;
Trie(uptr CallsiteAddress = 0) : CallsiteAddress(CallsiteAddress) {}
};
Trie TheTrie;
virtual uptr getFctStartAddr(uptr CallsiteAddress) const;
public:
PerThreadCallsiteTrie(const PerThreadCallsiteTrie &) = delete;
PerThreadCallsiteTrie(PerThreadCallsiteTrie &&) = default;
PerThreadCallsiteTrie() = default;
virtual ~PerThreadCallsiteTrie() = default;
void insertStack(const StackTrace &ST);
DenseMap<uptr, uint64_t> determineRoots() const;
};
class RootAutoDetector final {
static const uint64_t SampleRate = 6113;
const unsigned WaitSeconds;
pthread_t WorkerThread;
struct PerThreadSamples {
PerThreadSamples(RootAutoDetector &Parent);
PerThreadCallsiteTrie TrieRoot;
SpinMutex M;
};
SpinMutex AllSamplesMutex;
SANITIZER_GUARDED_BY(AllSamplesMutex)
Vector<PerThreadSamples *> AllSamples;
atomic_uintptr_t &FunctionDataListHead;
atomic_uintptr_t &Self;
void collectStack();
public:
RootAutoDetector(atomic_uintptr_t &FunctionDataListHead,
atomic_uintptr_t &Self, unsigned WaitSeconds)
: WaitSeconds(WaitSeconds), FunctionDataListHead(FunctionDataListHead),
Self(Self) {}
void sample();
void start();
void join();
};
}
#endif