File: thread_state_storage.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (131 lines) | stat: -rw-r--r-- 4,234 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_STORAGE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_STORAGE_H_

#include <cstdint>

#include "base/check_op.h"
#include "base/compiler_specific.h"
#include "third_party/blink/renderer/platform/heap/thread_local.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/stack_util.h"

namespace cppgc {
class AllocationHandle;
class HeapHandle;
}  // namespace cppgc

namespace blink {

class ThreadState;
class ThreadStateStorage;

// ThreadAffinity indicates which threads objects can be used on. We
// distinguish between objects that can be used on the main thread
// only and objects that can be used on any thread.
//
// For objects that can only be used on the main thread, we avoid going
// through thread-local storage to get to the thread state. This is
// important for performance.
enum ThreadAffinity {
  kAnyThread,
  kMainThreadOnly,
};

template <typename T, typename = void>
struct ThreadingTrait {
  STATIC_ONLY(ThreadingTrait);
  static constexpr ThreadAffinity kAffinity = kAnyThread;
};

// Storage for all ThreadState objects. This includes the main-thread
// ThreadState as well. Keep it outside the class so that PLATFORM_EXPORT
// doesn't apply to it (otherwise, clang-cl complains).
extern constinit thread_local ThreadStateStorage* g_thread_specific_
    __attribute__((tls_model(BLINK_HEAP_THREAD_LOCAL_MODEL)));

// ThreadStateStorage is the explicitly managed TLS- and global-backed storage
// for ThreadState.
class PLATFORM_EXPORT ThreadStateStorage final {
 public:
  ALWAYS_INLINE static ThreadStateStorage* MainThreadStateStorage() {
    return &main_thread_state_storage_;
  }

  BLINK_HEAP_DECLARE_THREAD_LOCAL_GETTER(Current,
                                         ThreadStateStorage*,
                                         g_thread_specific_)

  ALWAYS_INLINE cppgc::AllocationHandle& allocation_handle() const {
    return *allocation_handle_;
  }

  ALWAYS_INLINE cppgc::HeapHandle& heap_handle() const { return *heap_handle_; }

  ALWAYS_INLINE ThreadState& thread_state() const { return *thread_state_; }

  ALWAYS_INLINE bool IsMainThread() const {
    return this == MainThreadStateStorage();
  }

 private:
  static void AttachMainThread(ThreadState&,
                               cppgc::AllocationHandle&,
                               cppgc::HeapHandle&);
  static void AttachNonMainThread(ThreadState&,
                                  cppgc::AllocationHandle&,
                                  cppgc::HeapHandle&);
  static void DetachNonMainThread(ThreadStateStorage&);

  static ThreadStateStorage main_thread_state_storage_;

  ThreadStateStorage() = default;
  ThreadStateStorage(ThreadState&,
                     cppgc::AllocationHandle&,
                     cppgc::HeapHandle&);

  cppgc::AllocationHandle* allocation_handle_ = nullptr;
  cppgc::HeapHandle* heap_handle_ = nullptr;
  ThreadState* thread_state_ = nullptr;

  friend class ThreadState;
};

template <ThreadAffinity>
class ThreadStateStorageFor;

template <>
class ThreadStateStorageFor<kMainThreadOnly> {
  STATIC_ONLY(ThreadStateStorageFor);

 public:
  ALWAYS_INLINE static ThreadStateStorage* GetState() {
    auto* main_thread_storage = ThreadStateStorage::MainThreadStateStorage();
    DCHECK_EQ(main_thread_storage, ThreadStateStorage::Current());
    return main_thread_storage;
  }
};

template <>
class ThreadStateStorageFor<kAnyThread> {
  STATIC_ONLY(ThreadStateStorageFor);

 public:
  static ThreadStateStorage* GetState() {
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_ANDROID)
    // Perform a fast on main thread check on platforms with expensive TLS.
    if (!WTF::MayNotBeMainThread()) {
      return ThreadStateStorage::MainThreadStateStorage();
    }
#endif  // BUILDFLAG(IS_MAC)
    return ThreadStateStorage::Current();
  }
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_STORAGE_H_