xref: /llvm-project/compiler-rt/lib/rtsan/rtsan_context.cpp (revision e069434afcd21911ad36c55971bb8f754854c09f)
11adb55b1SChris Apple //===--- rtsan_context.cpp - Realtime Sanitizer -----------------*- C++ -*-===//
21adb55b1SChris Apple //
31adb55b1SChris Apple // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41adb55b1SChris Apple // See https://llvm.org/LICENSE.txt for license information.
51adb55b1SChris Apple // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61adb55b1SChris Apple //
71adb55b1SChris Apple //===----------------------------------------------------------------------===//
81adb55b1SChris Apple //
91adb55b1SChris Apple //===----------------------------------------------------------------------===//
101adb55b1SChris Apple 
113477eb72SChris Apple #include "rtsan/rtsan_context.h"
123477eb72SChris Apple #include "rtsan/rtsan.h"
131adb55b1SChris Apple 
143477eb72SChris Apple #include "sanitizer_common/sanitizer_allocator_internal.h"
151adb55b1SChris Apple 
161adb55b1SChris Apple #include <new>
171adb55b1SChris Apple #include <pthread.h>
181adb55b1SChris Apple 
19a424b792SChris Apple using namespace __sanitizer;
20*e069434aSChris Apple using namespace __rtsan;
21a424b792SChris Apple 
221adb55b1SChris Apple static pthread_key_t context_key;
231adb55b1SChris Apple static pthread_once_t key_once = PTHREAD_ONCE_INIT;
241adb55b1SChris Apple 
251adb55b1SChris Apple // InternalFree cannot be passed directly to pthread_key_create
261adb55b1SChris Apple // because it expects a signature with only one arg
271adb55b1SChris Apple static void InternalFreeWrapper(void *ptr) { __sanitizer::InternalFree(ptr); }
281adb55b1SChris Apple 
291adb55b1SChris Apple static __rtsan::Context &GetContextForThisThreadImpl() {
306032feeeSChris Apple   auto MakeThreadLocalContextKey = []() {
311adb55b1SChris Apple     CHECK_EQ(pthread_key_create(&context_key, InternalFreeWrapper), 0);
321adb55b1SChris Apple   };
331adb55b1SChris Apple 
346032feeeSChris Apple   pthread_once(&key_once, MakeThreadLocalContextKey);
35*e069434aSChris Apple   Context *current_thread_context =
36*e069434aSChris Apple       static_cast<Context *>(pthread_getspecific(context_key));
371adb55b1SChris Apple   if (current_thread_context == nullptr) {
38*e069434aSChris Apple     current_thread_context =
39*e069434aSChris Apple         static_cast<Context *>(InternalAlloc(sizeof(Context)));
40*e069434aSChris Apple     new (current_thread_context) Context();
411adb55b1SChris Apple     pthread_setspecific(context_key, current_thread_context);
421adb55b1SChris Apple   }
431adb55b1SChris Apple 
441adb55b1SChris Apple   return *current_thread_context;
451adb55b1SChris Apple }
461adb55b1SChris Apple 
471adb55b1SChris Apple __rtsan::Context::Context() = default;
481adb55b1SChris Apple 
4930d56bedSChris Apple void __rtsan::Context::RealtimePush() { realtime_depth_++; }
501adb55b1SChris Apple 
5130d56bedSChris Apple void __rtsan::Context::RealtimePop() { realtime_depth_--; }
521adb55b1SChris Apple 
5330d56bedSChris Apple void __rtsan::Context::BypassPush() { bypass_depth_++; }
541adb55b1SChris Apple 
5530d56bedSChris Apple void __rtsan::Context::BypassPop() { bypass_depth_--; }
561adb55b1SChris Apple 
5730d56bedSChris Apple bool __rtsan::Context::InRealtimeContext() const { return realtime_depth_ > 0; }
581adb55b1SChris Apple 
5930d56bedSChris Apple bool __rtsan::Context::IsBypassed() const { return bypass_depth_ > 0; }
601adb55b1SChris Apple 
61*e069434aSChris Apple Context &__rtsan::GetContextForThisThread() {
621adb55b1SChris Apple   return GetContextForThisThreadImpl();
631adb55b1SChris Apple }
64