aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/compiler-rt/lib/lsan/lsan_thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/compiler-rt/lib/lsan/lsan_thread.cpp')
-rw-r--r--contrib/llvm-project/compiler-rt/lib/lsan/lsan_thread.cpp116
1 files changed, 116 insertions, 0 deletions
diff --git a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_thread.cpp b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_thread.cpp
new file mode 100644
index 000000000000..07c7b923623f
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_thread.cpp
@@ -0,0 +1,116 @@
+//=-- lsan_thread.cpp -----------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of LeakSanitizer.
+// See lsan_thread.h for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lsan_thread.h"
+
+#include "lsan.h"
+#include "lsan_allocator.h"
+#include "lsan_common.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_placement_new.h"
+#include "sanitizer_common/sanitizer_thread_registry.h"
+#include "sanitizer_common/sanitizer_tls_get_addr.h"
+
+namespace __lsan {
+
+static ThreadRegistry *thread_registry;
+static ThreadArgRetval *thread_arg_retval;
+
+static Mutex mu_for_thread_context;
+static LowLevelAllocator allocator_for_thread_context;
+
+static ThreadContextBase *CreateThreadContext(u32 tid) {
+ Lock lock(&mu_for_thread_context);
+ return new (allocator_for_thread_context) ThreadContext(tid);
+}
+
+void InitializeThreads() {
+ alignas(alignof(ThreadRegistry)) static char
+ thread_registry_placeholder[sizeof(ThreadRegistry)];
+ thread_registry =
+ new (thread_registry_placeholder) ThreadRegistry(CreateThreadContext);
+
+ alignas(alignof(ThreadArgRetval)) static char
+ thread_arg_retval_placeholder[sizeof(ThreadArgRetval)];
+ thread_arg_retval = new (thread_arg_retval_placeholder) ThreadArgRetval();
+}
+
+ThreadArgRetval &GetThreadArgRetval() { return *thread_arg_retval; }
+
+ThreadContextLsanBase::ThreadContextLsanBase(int tid)
+ : ThreadContextBase(tid) {}
+
+void ThreadContextLsanBase::OnStarted(void *arg) {
+ SetCurrentThread(this);
+ AllocatorThreadStart();
+}
+
+void ThreadContextLsanBase::OnFinished() {
+ AllocatorThreadFinish();
+ DTLS_Destroy();
+ SetCurrentThread(nullptr);
+}
+
+u32 ThreadCreate(u32 parent_tid, bool detached, void *arg) {
+ return thread_registry->CreateThread(0, detached, parent_tid, arg);
+}
+
+void ThreadContextLsanBase::ThreadStart(u32 tid, tid_t os_id,
+ ThreadType thread_type, void *arg) {
+ thread_registry->StartThread(tid, os_id, thread_type, arg);
+}
+
+void ThreadFinish() { thread_registry->FinishThread(GetCurrentThreadId()); }
+
+void EnsureMainThreadIDIsCorrect() {
+ if (GetCurrentThreadId() == kMainTid)
+ GetCurrentThread()->os_id = GetTid();
+}
+
+///// Interface to the common LSan module. /////
+
+void GetThreadExtraStackRangesLocked(tid_t os_id,
+ InternalMmapVector<Range> *ranges) {}
+void GetThreadExtraStackRangesLocked(InternalMmapVector<Range> *ranges) {}
+
+void LockThreads() {
+ thread_registry->Lock();
+ thread_arg_retval->Lock();
+}
+
+void UnlockThreads() {
+ thread_arg_retval->Unlock();
+ thread_registry->Unlock();
+}
+
+ThreadRegistry *GetLsanThreadRegistryLocked() {
+ thread_registry->CheckLocked();
+ return thread_registry;
+}
+
+void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {
+ GetLsanThreadRegistryLocked()->RunCallbackForEachThreadLocked(
+ [](ThreadContextBase *tctx, void *threads) {
+ if (tctx->status == ThreadStatusRunning) {
+ reinterpret_cast<InternalMmapVector<tid_t> *>(threads)->push_back(
+ tctx->os_id);
+ }
+ },
+ threads);
+}
+
+void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs) {
+ GetThreadArgRetval().GetAllPtrsLocked(ptrs);
+}
+
+} // namespace __lsan