Path: blob/main/contrib/llvm-project/compiler-rt/lib/ctx_profile/RootAutoDetector.h
213766 views
/*===- RootAutodetector.h- auto-detect roots for ctxprof -----------------===*\1|*2|* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3|* See https://llvm.org/LICENSE.txt for license information.4|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5|*6\*===----------------------------------------------------------------------===*/78#ifndef CTX_PROFILE_ROOTAUTODETECTOR_H_9#define CTX_PROFILE_ROOTAUTODETECTOR_H_1011#include "sanitizer_common/sanitizer_dense_map.h"12#include "sanitizer_common/sanitizer_internal_defs.h"13#include "sanitizer_common/sanitizer_stacktrace.h"14#include "sanitizer_common/sanitizer_vector.h"15#include <pthread.h>16#include <sanitizer/common_interface_defs.h>1718using namespace __asan;19using namespace __sanitizer;2021namespace __ctx_profile {2223/// Capture all the stack traces observed for a specific thread. The "for a24/// specific thread" part is not enforced, but assumed in determineRoots.25class PerThreadCallsiteTrie {26protected:27/// A trie. A node is the address of a callsite in a function activation. A28/// child is a callsite in the activation made from the callsite29/// corresponding to the parent.30struct Trie final {31const uptr CallsiteAddress;32uint64_t Count = 0;33DenseMap<uptr, Trie> Children;3435Trie(uptr CallsiteAddress = 0) : CallsiteAddress(CallsiteAddress) {}36};37Trie TheTrie;3839/// Return the runtime start address of the function that contains the call at40/// the runtime address CallsiteAddress. May be overriden for easy testing.41virtual uptr getFctStartAddr(uptr CallsiteAddress) const;4243public:44PerThreadCallsiteTrie(const PerThreadCallsiteTrie &) = delete;45PerThreadCallsiteTrie(PerThreadCallsiteTrie &&) = default;46PerThreadCallsiteTrie() = default;4748virtual ~PerThreadCallsiteTrie() = default;4950void insertStack(const StackTrace &ST);5152/// Return the runtime address of root functions, as determined for this53/// thread, together with the number of samples that included them.54DenseMap<uptr, uint64_t> determineRoots() const;55};5657class RootAutoDetector final {58// A prime number. We may want to make this configurable at collection start.59static const uint64_t SampleRate = 6113;60const unsigned WaitSeconds;61pthread_t WorkerThread;6263struct PerThreadSamples {64PerThreadSamples(RootAutoDetector &Parent);6566PerThreadCallsiteTrie TrieRoot;67SpinMutex M;68};69SpinMutex AllSamplesMutex;70SANITIZER_GUARDED_BY(AllSamplesMutex)71Vector<PerThreadSamples *> AllSamples;72atomic_uintptr_t &FunctionDataListHead;73atomic_uintptr_t &Self;74void collectStack();7576public:77RootAutoDetector(atomic_uintptr_t &FunctionDataListHead,78atomic_uintptr_t &Self, unsigned WaitSeconds)79: WaitSeconds(WaitSeconds), FunctionDataListHead(FunctionDataListHead),80Self(Self) {}8182// Samples the stack at `SampleRate` (rate observed independently on each83// thread) in thread local `PerThreadCallsiteTrie`s.84void sample();8586// Start a thread waiting `WaitSeconds`, after which it uses the87// `PerThreadCallsiteTrie` data observed so far over all threads to determine88// roots. Marks those roots by traversing the linked list of FunctionData that89// starts at `FunctionDataListHead`, and assigning their `CtxRoot`. Finally,90// resets the `Self` atomic, so that other threads don't continue calling91// `sample`.92void start();9394// join the waiting thread.95void join();96};9798} // namespace __ctx_profile99#endif100101102