abseil-cpp/absl/synchronization/internal/create_thread_identity.cc
Go to the documentation of this file.
1 // Copyright 2017 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <stdint.h>
16 #include <new>
17 
18 // This file is a no-op if the required LowLevelAlloc support is missing.
19 #include "absl/base/internal/low_level_alloc.h"
20 #ifndef ABSL_LOW_LEVEL_ALLOC_MISSING
21 
22 #include <string.h>
23 
24 #include "absl/base/attributes.h"
25 #include "absl/base/internal/spinlock.h"
26 #include "absl/base/internal/thread_identity.h"
27 #include "absl/synchronization/internal/per_thread_sem.h"
28 
29 namespace absl {
31 namespace synchronization_internal {
32 
33 // ThreadIdentity storage is persistent, we maintain a free-list of previously
34 // released ThreadIdentity objects.
35 ABSL_CONST_INIT static base_internal::SpinLock freelist_lock(
38 
39 // A per-thread destructor for reclaiming associated ThreadIdentity objects.
40 // Since we must preserve their storage we cache them for re-use.
41 static void ReclaimThreadIdentity(void* v) {
43  static_cast<base_internal::ThreadIdentity*>(v);
44 
45  // all_locks might have been allocated by the Mutex implementation.
46  // We free it here when we are notified that our thread is dying.
47  if (identity->per_thread_synch.all_locks != nullptr) {
49  }
50 
51  // We must explicitly clear the current thread's identity:
52  // (a) Subsequent (unrelated) per-thread destructors may require an identity.
53  // We must guarantee a new identity is used in this case (this instructor
54  // will be reinvoked up to PTHREAD_DESTRUCTOR_ITERATIONS in this case).
55  // (b) ThreadIdentity implementations may depend on memory that is not
56  // reinitialized before reuse. We must allow explicit clearing of the
57  // association state in this case.
59  {
61  identity->next = thread_identity_freelist;
62  thread_identity_freelist = identity;
63  }
64 }
65 
66 // Return value rounded up to next multiple of align.
67 // Align must be a power of two.
69  return (addr + align - 1) & ~(align - 1);
70 }
71 
73  PerThreadSem::Init(identity);
74 }
75 
79  pts->next = nullptr;
80  pts->skip = nullptr;
81  pts->may_skip = false;
82  pts->waitp = nullptr;
83  pts->suppress_fatal_errors = false;
84  pts->readers = 0;
85  pts->priority = 0;
87  pts->state.store(base_internal::PerThreadSynch::State::kAvailable,
88  std::memory_order_relaxed);
89  pts->maybe_unlocking = false;
90  pts->wake = false;
91  pts->cond_waiter = false;
92  pts->all_locks = nullptr;
93  identity->blocked_count_ptr = nullptr;
94  identity->ticker.store(0, std::memory_order_relaxed);
95  identity->wait_start.store(0, std::memory_order_relaxed);
96  identity->is_idle.store(false, std::memory_order_relaxed);
97  identity->next = nullptr;
98 }
99 
101  base_internal::ThreadIdentity* identity = nullptr;
102 
103  {
104  // Re-use a previously released object if possible.
107  identity = thread_identity_freelist; // Take list-head.
109  }
110  }
111 
112  if (identity == nullptr) {
113  // Allocate enough space to align ThreadIdentity to a multiple of
114  // PerThreadSynch::kAlignment. This space is never released (it is
115  // added to a freelist by ReclaimThreadIdentity instead).
116  void* allocation = base_internal::LowLevelAlloc::Alloc(
117  sizeof(*identity) + base_internal::PerThreadSynch::kAlignment - 1);
118  // Round up the address to the required alignment.
119  identity = reinterpret_cast<base_internal::ThreadIdentity*>(
120  RoundUp(reinterpret_cast<intptr_t>(allocation),
122  OneTimeInitThreadIdentity(identity);
123  }
125 
126  return identity;
127 }
128 
129 // Allocates and attaches ThreadIdentity object for the calling thread. Returns
130 // the new identity.
131 // REQUIRES: CurrentThreadIdentity(false) == nullptr
134  // Associate the value with the current thread, and attach our destructor.
136  return identity;
137 }
138 
139 } // namespace synchronization_internal
141 } // namespace absl
142 
143 #endif // ABSL_LOW_LEVEL_ALLOC_MISSING
absl::base_internal::SpinLockHolder
Definition: third_party/abseil-cpp/absl/base/internal/spinlock.h:196
absl::base_internal::ThreadIdentity
Definition: abseil-cpp/absl/base/internal/thread_identity.h:137
ABSL_CONST_INIT
#define ABSL_CONST_INIT
Definition: abseil-cpp/absl/base/attributes.h:716
absl::base_internal::ThreadIdentity::ticker
std::atomic< int > ticker
Definition: abseil-cpp/absl/base/internal/thread_identity.h:155
absl::base_internal::PerThreadSynch::skip
PerThreadSynch * skip
Definition: abseil-cpp/absl/base/internal/thread_identity.h:66
absl::synchronization_internal::OneTimeInitThreadIdentity
void OneTimeInitThreadIdentity(base_internal::ThreadIdentity *identity)
Definition: abseil-cpp/absl/synchronization/internal/create_thread_identity.cc:72
absl::base_internal::PerThreadSynch::waitp
SynchWaitParams * waitp
Definition: abseil-cpp/absl/base/internal/thread_identity.h:123
absl::synchronization_internal::thread_identity_freelist
static ABSL_CONST_INIT base_internal::ThreadIdentity * thread_identity_freelist
Definition: abseil-cpp/absl/synchronization/internal/create_thread_identity.cc:37
absl::base_internal::ThreadIdentity::wait_start
std::atomic< int > wait_start
Definition: abseil-cpp/absl/base/internal/thread_identity.h:156
string.h
absl::synchronization_internal::CreateThreadIdentity
base_internal::ThreadIdentity * CreateThreadIdentity()
Definition: abseil-cpp/absl/synchronization/internal/create_thread_identity.cc:132
absl::base_internal::ThreadIdentity::next
ThreadIdentity * next
Definition: abseil-cpp/absl/base/internal/thread_identity.h:159
absl::base_internal::PerThreadSynch::maybe_unlocking
bool maybe_unlocking
Definition: abseil-cpp/absl/base/internal/thread_identity.h:80
absl::kConstInit
@ kConstInit
Definition: abseil-cpp/absl/base/const_init.h:70
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
absl::base_internal::PerThreadSynch
Definition: abseil-cpp/absl/base/internal/thread_identity.h:49
absl::base_internal::PerThreadSynch::wake
bool wake
Definition: abseil-cpp/absl/base/internal/thread_identity.h:73
absl::synchronization_internal::RoundUp
static intptr_t RoundUp(intptr_t addr, intptr_t align)
Definition: abseil-cpp/absl/synchronization/internal/create_thread_identity.cc:68
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
absl::base_internal::LowLevelAlloc::Free
static void Free(void *s) ABSL_ATTRIBUTE_SECTION(malloc_hook)
Definition: abseil-cpp/absl/base/internal/low_level_alloc.cc:509
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
absl::base_internal::ThreadIdentity::per_thread_synch
PerThreadSynch per_thread_synch
Definition: abseil-cpp/absl/base/internal/thread_identity.h:142
absl::base_internal::PerThreadSynch::may_skip
bool may_skip
Definition: abseil-cpp/absl/base/internal/thread_identity.h:69
intptr_t
_W64 signed int intptr_t
Definition: stdint-msvc2008.h:118
absl::base_internal::PerThreadSynch::suppress_fatal_errors
bool suppress_fatal_errors
Definition: abseil-cpp/absl/base/internal/thread_identity.h:89
absl::base_internal::ThreadIdentity::blocked_count_ptr
std::atomic< int > * blocked_count_ptr
Definition: abseil-cpp/absl/base/internal/thread_identity.h:150
absl::base_internal::SetCurrentThreadIdentity
ABSL_CONST_INIT void SetCurrentThreadIdentity(ThreadIdentity *identity, ThreadIdentityReclaimerFunction reclaimer)
Definition: abseil-cpp/absl/base/internal/thread_identity.cc:71
absl::synchronization_internal::NewThreadIdentity
static base_internal::ThreadIdentity * NewThreadIdentity()
Definition: abseil-cpp/absl/synchronization/internal/create_thread_identity.cc:100
stdint.h
absl::synchronization_internal::PerThreadSem::Init
static void Init(base_internal::ThreadIdentity *identity)
Definition: abseil-cpp/absl/synchronization/internal/per_thread_sem.cc:43
absl::base_internal::ClearCurrentThreadIdentity
void ClearCurrentThreadIdentity()
Definition: abseil-cpp/absl/base/internal/thread_identity.cc:132
absl::base_internal::PerThreadSynch::next_priority_read_cycles
int64_t next_priority_read_cycles
Definition: abseil-cpp/absl/base/internal/thread_identity.h:128
absl::synchronization_internal::freelist_lock
static ABSL_CONST_INIT base_internal::SpinLock freelist_lock(absl::kConstInit, base_internal::SCHEDULE_KERNEL_ONLY)
absl::base_internal::SCHEDULE_KERNEL_ONLY
@ SCHEDULE_KERNEL_ONLY
Definition: abseil-cpp/absl/base/internal/scheduling_mode.h:50
absl::time_internal::cctz::detail::align
CONSTEXPR_F fields align(second_tag, fields f) noexcept
Definition: abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h:325
absl::base_internal::LowLevelAlloc::Alloc
static void * Alloc(size_t request) ABSL_ATTRIBUTE_SECTION(malloc_hook)
Definition: abseil-cpp/absl/base/internal/low_level_alloc.cc:605
absl::base_internal::PerThreadSynch::next
PerThreadSynch * next
Definition: abseil-cpp/absl/base/internal/thread_identity.h:65
absl::base_internal::PerThreadSynch::readers
intptr_t readers
Definition: abseil-cpp/absl/base/internal/thread_identity.h:125
absl::synchronization_internal::ResetThreadIdentityBetweenReuse
static void ResetThreadIdentityBetweenReuse(base_internal::ThreadIdentity *identity)
Definition: abseil-cpp/absl/synchronization/internal/create_thread_identity.cc:76
absl::synchronization_internal::ReclaimThreadIdentity
static void ReclaimThreadIdentity(void *v)
Definition: abseil-cpp/absl/synchronization/internal/create_thread_identity.cc:41
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
absl::base_internal::PerThreadSynch::cond_waiter
bool cond_waiter
Definition: abseil-cpp/absl/base/internal/thread_identity.h:79
absl::base_internal::PerThreadSynch::state
std::atomic< State > state
Definition: abseil-cpp/absl/base/internal/thread_identity.h:111
absl::base_internal::PerThreadSynch::kAlignment
static constexpr int kAlignment
Definition: abseil-cpp/absl/base/internal/thread_identity.h:56
absl::base_internal::PerThreadSynch::priority
int priority
Definition: abseil-cpp/absl/base/internal/thread_identity.h:94
addr
struct sockaddr_in addr
Definition: libuv/docs/code/tcp-echo-server/main.c:10
absl::base_internal::ThreadIdentity::is_idle
std::atomic< bool > is_idle
Definition: abseil-cpp/absl/base/internal/thread_identity.h:157
absl::base_internal::PerThreadSynch::all_locks
SynchLocksHeld * all_locks
Definition: abseil-cpp/absl/base/internal/thread_identity.h:132


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:06