• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
9 #ifndef SCUDO_TSD_H_
10 #define SCUDO_TSD_H_
11 
12 #include "atomic_helpers.h"
13 #include "common.h"
14 #include "mutex.h"
15 
16 #include <limits.h> // for PTHREAD_DESTRUCTOR_ITERATIONS
17 #include <pthread.h>
18 
19 // With some build setups, this might still not be defined.
20 #ifndef PTHREAD_DESTRUCTOR_ITERATIONS
21 #define PTHREAD_DESTRUCTOR_ITERATIONS 4
22 #endif
23 
24 namespace scudo {
25 
26 template <class Allocator> struct alignas(SCUDO_CACHE_LINE_SIZE) TSD {
27   typename Allocator::CacheT Cache;
28   typename Allocator::QuarantineCacheT QuarantineCache;
29   u8 DestructorIterations = 0;
30 
initLinkerInitializedTSD31   void initLinkerInitialized(Allocator *Instance) {
32     Instance->initCache(&Cache);
33     DestructorIterations = PTHREAD_DESTRUCTOR_ITERATIONS;
34   }
initTSD35   void init(Allocator *Instance) {
36     memset(this, 0, sizeof(*this));
37     initLinkerInitialized(Instance);
38   }
39 
commitBackTSD40   void commitBack(Allocator *Instance) { Instance->commitBack(this); }
41 
tryLockTSD42   inline bool tryLock() {
43     if (Mutex.tryLock()) {
44       atomic_store_relaxed(&Precedence, 0);
45       return true;
46     }
47     if (atomic_load_relaxed(&Precedence) == 0)
48       atomic_store_relaxed(
49           &Precedence,
50           static_cast<uptr>(getMonotonicTime() >> FIRST_32_SECOND_64(16, 0)));
51     return false;
52   }
lockTSD53   inline void lock() {
54     atomic_store_relaxed(&Precedence, 0);
55     Mutex.lock();
56   }
unlockTSD57   inline void unlock() { Mutex.unlock(); }
getPrecedenceTSD58   inline uptr getPrecedence() { return atomic_load_relaxed(&Precedence); }
59 
60 private:
61   HybridMutex Mutex;
62   atomic_uptr Precedence = {};
63 };
64 
65 } // namespace scudo
66 
67 #endif // SCUDO_TSD_H_
68