1 //===-- memprof_thread.h ---------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file is a part of MemProfiler, a memory profiler.
11 // MemProf-private header for memprof_thread.cpp.
12 //===----------------------------------------------------------------------===//
14 #ifndef MEMPROF_THREAD_H
15 #define MEMPROF_THREAD_H
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"
24 namespace __sanitizer
{
26 } // namespace __sanitizer
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.
34 struct MemprofThreadContext final
: public ThreadContextBase
{
35 explicit MemprofThreadContext(int tid
)
36 : ThreadContextBase(tid
), announced(false),
37 destructor_iterations(GetPthreadDestructorIterations()), stack_id(0),
40 u8 destructor_iterations
;
42 MemprofThread
*thread
;
44 void OnCreated(void *arg
) override
;
45 void OnFinished() override
;
47 struct CreateThreadContextArgs
{
48 MemprofThread
*thread
;
53 // MemprofThreadContext objects are never freed, so we need many of them.
54 COMPILER_CHECK(sizeof(MemprofThreadContext
) <= 256);
56 // MemprofThread are stored in TSD and destroyed when the thread dies.
59 static MemprofThread
*Create(thread_callback_t start_routine
, void *arg
,
60 u32 parent_tid
, StackTrace
*stack
,
62 static void TSDDtor(void *tsd
);
66 void Init(const InitOptions
*options
= nullptr);
68 thread_return_t
ThreadStart(tid_t os_id
,
69 atomic_uintptr_t
*signal_thread_is_registered
);
74 uptr
tls_begin() { return tls_begin_
; }
75 uptr
tls_end() { return tls_end_
; }
76 DTLS
*dtls() { return dtls_
; }
77 u32
tid() { return context_
->tid
; }
78 MemprofThreadContext
*context() { return context_
; }
79 void set_context(MemprofThreadContext
*context
) { context_
= context
; }
81 bool AddrIsInStack(uptr addr
);
83 // True is this thread is currently unwinding stack (i.e. collecting a stack
84 // trace). Used to prevent deadlocks on platforms where libc unwinder calls
85 // malloc internally. See PR17116 for more details.
86 bool isUnwinding() const { return unwinding_
; }
87 void setUnwinding(bool b
) { unwinding_
= b
; }
89 MemprofThreadLocalMallocStorage
&malloc_storage() { return malloc_storage_
; }
90 MemprofStats
&stats() { return stats_
; }
93 // NOTE: There is no MemprofThread constructor. It is allocated
94 // via mmap() and *must* be valid in zero-initialized state.
96 void SetThreadStackAndTls(const InitOptions
*options
);
102 StackBounds
GetStackBounds() const;
104 MemprofThreadContext
*context_
;
105 thread_callback_t start_routine_
;
115 MemprofThreadLocalMallocStorage malloc_storage_
;
120 // Returns a single instance of registry.
121 ThreadRegistry
&memprofThreadRegistry();
123 // Must be called under ThreadRegistryLock.
124 MemprofThreadContext
*GetThreadContextByTidLocked(u32 tid
);
126 // Get the current thread. May return 0.
127 MemprofThread
*GetCurrentThread();
128 void SetCurrentThread(MemprofThread
*t
);
129 u32
GetCurrentTidOrInvalid();
131 // Used to handle fork().
132 void EnsureMainThreadIDIsCorrect();
133 } // namespace __memprof
135 #endif // MEMPROF_THREAD_H