tsd.h 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. //===-- tsd.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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef SCUDO_TSD_H_
  9. #define SCUDO_TSD_H_
  10. #include "atomic_helpers.h"
  11. #include "common.h"
  12. #include "mutex.h"
  13. #include <limits.h> // for PTHREAD_DESTRUCTOR_ITERATIONS
  14. #include <pthread.h>
  15. // With some build setups, this might still not be defined.
  16. #ifndef PTHREAD_DESTRUCTOR_ITERATIONS
  17. #define PTHREAD_DESTRUCTOR_ITERATIONS 4
  18. #endif
  19. namespace scudo {
  20. template <class Allocator> struct alignas(SCUDO_CACHE_LINE_SIZE) TSD {
  21. typename Allocator::CacheT Cache;
  22. typename Allocator::QuarantineCacheT QuarantineCache;
  23. using ThisT = TSD<Allocator>;
  24. u8 DestructorIterations = 0;
  25. void init(Allocator *Instance) {
  26. DCHECK_EQ(DestructorIterations, 0U);
  27. DCHECK(isAligned(reinterpret_cast<uptr>(this), alignof(ThisT)));
  28. Instance->initCache(&Cache);
  29. DestructorIterations = PTHREAD_DESTRUCTOR_ITERATIONS;
  30. }
  31. void commitBack(Allocator *Instance) { Instance->commitBack(this); }
  32. inline bool tryLock() {
  33. if (Mutex.tryLock()) {
  34. atomic_store_relaxed(&Precedence, 0);
  35. return true;
  36. }
  37. if (atomic_load_relaxed(&Precedence) == 0)
  38. atomic_store_relaxed(
  39. &Precedence,
  40. static_cast<uptr>(getMonotonicTime() >> FIRST_32_SECOND_64(16, 0)));
  41. return false;
  42. }
  43. inline void lock() {
  44. atomic_store_relaxed(&Precedence, 0);
  45. Mutex.lock();
  46. }
  47. inline void unlock() { Mutex.unlock(); }
  48. inline uptr getPrecedence() { return atomic_load_relaxed(&Precedence); }
  49. private:
  50. HybridMutex Mutex;
  51. atomic_uptr Precedence = {};
  52. };
  53. } // namespace scudo
  54. #endif // SCUDO_TSD_H_