130 lines · c
1//===-- memprof_thread.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-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of MemProfiler, a memory profiler.10//11// MemProf-private header for memprof_thread.cpp.12//===----------------------------------------------------------------------===//13 14#ifndef MEMPROF_THREAD_H15#define MEMPROF_THREAD_H16 17#include "memprof_allocator.h"18#include "memprof_internal.h"19#include "memprof_stats.h"20#include "sanitizer_common/sanitizer_common.h"21#include "sanitizer_common/sanitizer_libc.h"22#include "sanitizer_common/sanitizer_thread_registry.h"23 24namespace __sanitizer {25struct DTLS;26} // namespace __sanitizer27 28namespace __memprof {29 30class MemprofThread;31 32// These objects are created for every thread and are never deleted,33// so we can find them by tid even if the thread is long dead.34struct MemprofThreadContext final : public ThreadContextBase {35 explicit MemprofThreadContext(int tid)36 : ThreadContextBase(tid), announced(false),37 destructor_iterations(GetPthreadDestructorIterations()),38 thread(nullptr) {}39 bool announced;40 u8 destructor_iterations;41 MemprofThread *thread;42 43 void OnCreated(void *arg) override;44 void OnFinished() override;45};46 47// MemprofThreadContext objects are never freed, so we need many of them.48COMPILER_CHECK(sizeof(MemprofThreadContext) <= 256);49 50// MemprofThread are stored in TSD and destroyed when the thread dies.51class MemprofThread {52public:53 static MemprofThread *Create(thread_callback_t start_routine, void *arg,54 u32 parent_tid, StackTrace *stack,55 bool detached);56 static void TSDDtor(void *tsd);57 void Destroy();58 59 struct InitOptions;60 void Init(const InitOptions *options = nullptr);61 62 thread_return_t ThreadStart(ThreadID os_id,63 atomic_uintptr_t *signal_thread_is_registered);64 65 uptr stack_top();66 uptr stack_bottom();67 uptr stack_size();68 uptr tls_begin() { return tls_begin_; }69 uptr tls_end() { return tls_end_; }70 DTLS *dtls() { return dtls_; }71 u32 tid() { return context_->tid; }72 MemprofThreadContext *context() { return context_; }73 void set_context(MemprofThreadContext *context) { context_ = context; }74 75 bool AddrIsInStack(uptr addr);76 77 // True is this thread is currently unwinding stack (i.e. collecting a stack78 // trace). Used to prevent deadlocks on platforms where libc unwinder calls79 // malloc internally. See PR17116 for more details.80 bool isUnwinding() const { return unwinding_; }81 void setUnwinding(bool b) { unwinding_ = b; }82 83 MemprofThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }84 MemprofStats &stats() { return stats_; }85 86private:87 // NOTE: There is no MemprofThread constructor. It is allocated88 // via mmap() and *must* be valid in zero-initialized state.89 90 void SetThreadStackAndTls(const InitOptions *options);91 92 struct StackBounds {93 uptr bottom;94 uptr top;95 };96 StackBounds GetStackBounds() const;97 98 MemprofThreadContext *context_;99 thread_callback_t start_routine_;100 void *arg_;101 102 uptr stack_top_;103 uptr stack_bottom_;104 105 uptr tls_begin_;106 uptr tls_end_;107 DTLS *dtls_;108 109 MemprofThreadLocalMallocStorage malloc_storage_;110 MemprofStats stats_;111 bool unwinding_;112};113 114// Returns a single instance of registry.115ThreadRegistry &memprofThreadRegistry();116 117// Must be called under ThreadRegistryLock.118MemprofThreadContext *GetThreadContextByTidLocked(u32 tid);119 120// Get the current thread. May return 0.121MemprofThread *GetCurrentThread();122void SetCurrentThread(MemprofThread *t);123u32 GetCurrentTidOrInvalid();124 125// Used to handle fork().126void EnsureMainThreadIDIsCorrect();127} // namespace __memprof128 129#endif // MEMPROF_THREAD_H130