grpc
third_party
abseil-cpp
absl
synchronization
internal
abseil-cpp/absl/synchronization/internal/waiter.h
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
16
#ifndef ABSL_SYNCHRONIZATION_INTERNAL_WAITER_H_
17
#define ABSL_SYNCHRONIZATION_INTERNAL_WAITER_H_
18
19
#include "absl/base/config.h"
20
21
#ifdef _WIN32
22
#include <sdkddkver.h>
23
#else
24
#include <pthread.h>
25
#endif
26
27
#ifdef __linux__
28
#include <linux/futex.h>
29
#endif
30
31
#ifdef ABSL_HAVE_SEMAPHORE_H
32
#include <semaphore.h>
33
#endif
34
35
#include <atomic>
36
#include <cstdint>
37
38
#include "absl/base/internal/thread_identity.h"
39
#include "absl/synchronization/internal/futex.h"
40
#include "absl/synchronization/internal/kernel_timeout.h"
41
42
// May be chosen at compile time via -DABSL_FORCE_WAITER_MODE=<index>
43
#define ABSL_WAITER_MODE_FUTEX 0
44
#define ABSL_WAITER_MODE_SEM 1
45
#define ABSL_WAITER_MODE_CONDVAR 2
46
#define ABSL_WAITER_MODE_WIN32 3
47
48
#if defined(ABSL_FORCE_WAITER_MODE)
49
#define ABSL_WAITER_MODE ABSL_FORCE_WAITER_MODE
50
#elif defined(_WIN32) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
51
#define ABSL_WAITER_MODE ABSL_WAITER_MODE_WIN32
52
#elif defined(ABSL_INTERNAL_HAVE_FUTEX)
53
#define ABSL_WAITER_MODE ABSL_WAITER_MODE_FUTEX
54
#elif defined(ABSL_HAVE_SEMAPHORE_H)
55
#define ABSL_WAITER_MODE ABSL_WAITER_MODE_SEM
56
#else
57
#define ABSL_WAITER_MODE ABSL_WAITER_MODE_CONDVAR
58
#endif
59
60
namespace
absl
{
61
ABSL_NAMESPACE_BEGIN
62
namespace
synchronization_internal {
63
64
// Waiter is an OS-specific semaphore.
65
class
Waiter
{
66
public
:
67
// Prepare any data to track waits.
68
Waiter
();
69
70
// Not copyable or movable
71
Waiter
(
const
Waiter
&) =
delete
;
72
Waiter
&
operator=
(
const
Waiter
&) =
delete
;
73
74
// Blocks the calling thread until a matching call to `Post()` or
75
// `t` has passed. Returns `true` if woken (`Post()` called),
76
// `false` on timeout.
77
bool
Wait
(
KernelTimeout
t);
78
79
// Restart the caller of `Wait()` as with a normal semaphore.
80
void
Post
();
81
82
// If anyone is waiting, wake them up temporarily and cause them to
83
// call `MaybeBecomeIdle()`. They will then return to waiting for a
84
// `Post()` or timeout.
85
void
Poke
();
86
87
// Returns the Waiter associated with the identity.
88
static
Waiter
*
GetWaiter
(
base_internal::ThreadIdentity
* identity) {
89
static_assert(
90
sizeof
(
Waiter
) <=
sizeof
(
base_internal::ThreadIdentity::WaiterState
),
91
"Insufficient space for Waiter"
);
92
return
reinterpret_cast<
Waiter
*
>
(identity->
waiter_state
.
data
);
93
}
94
95
// How many periods to remain idle before releasing resources
96
#ifndef ABSL_HAVE_THREAD_SANITIZER
97
static
constexpr
int
kIdlePeriods
= 60;
98
#else
99
// Memory consumption under ThreadSanitizer is a serious concern,
100
// so we release resources sooner. The value of 1 leads to 1 to 2 second
101
// delay before marking a thread as idle.
102
static
const
int
kIdlePeriods
= 1;
103
#endif
104
105
private
:
106
// The destructor must not be called since Mutex/CondVar
107
// can use PerThreadSem/Waiter after the thread exits.
108
// Waiter objects are embedded in ThreadIdentity objects,
109
// which are reused via a freelist and are never destroyed.
110
~Waiter
() =
delete
;
111
112
#if ABSL_WAITER_MODE == ABSL_WAITER_MODE_FUTEX
113
// Futexes are defined by specification to be 32-bits.
114
// Thus std::atomic<int32_t> must be just an int32_t with lockfree methods.
115
std::atomic<int32_t> futex_;
116
static_assert(
sizeof
(
int32_t
) ==
sizeof
(futex_),
"Wrong size for futex"
);
117
118
#elif ABSL_WAITER_MODE == ABSL_WAITER_MODE_CONDVAR
119
// REQUIRES: mu_ must be held.
120
void
InternalCondVarPoke();
121
122
pthread_mutex_t
mu_
;
123
pthread_cond_t
cv_
;
124
int
waiter_count_;
125
int
wakeup_count_;
// Unclaimed wakeups.
126
127
#elif ABSL_WAITER_MODE == ABSL_WAITER_MODE_SEM
128
sem_t sem_;
129
// This seems superfluous, but for Poke() we need to cause spurious
130
// wakeups on the semaphore. Hence we can't actually use the
131
// semaphore's count.
132
std::atomic<int>
wakeups_
;
133
134
#elif ABSL_WAITER_MODE == ABSL_WAITER_MODE_WIN32
135
// WinHelper - Used to define utilities for accessing the lock and
136
// condition variable storage once the types are complete.
137
class
WinHelper;
138
139
// REQUIRES: WinHelper::GetLock(this) must be held.
140
void
InternalCondVarPoke();
141
142
// We can't include Windows.h in our headers, so we use aligned character
143
// buffers to define the storage of SRWLOCK and CONDITION_VARIABLE.
144
// SRW locks and condition variables do not need to be explicitly destroyed.
145
// https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-initializesrwlock
146
// https://stackoverflow.com/questions/28975958/why-does-windows-have-no-deleteconditionvariable-function-to-go-together-with
147
alignas
(
void
*)
unsigned
char
mu_storage_[
sizeof
(
void
*)];
148
alignas
(
void
*)
unsigned
char
cv_storage_[
sizeof
(
void
*)];
149
int
waiter_count_;
150
int
wakeup_count_;
151
152
#else
153
#error Unknown ABSL_WAITER_MODE
154
#endif
155
};
156
157
}
// namespace synchronization_internal
158
ABSL_NAMESPACE_END
159
}
// namespace absl
160
161
#endif // ABSL_SYNCHRONIZATION_INTERNAL_WAITER_H_
absl::base_internal::ThreadIdentity
Definition:
abseil-cpp/absl/base/internal/thread_identity.h:137
cv_
std::condition_variable cv_
Definition:
client_callback_end2end_test.cc:733
absl::synchronization_internal::Waiter::Post
void Post()
Definition:
abseil-cpp/absl/synchronization/internal/waiter.cc:107
absl::synchronization_internal::Waiter::GetWaiter
static Waiter * GetWaiter(base_internal::ThreadIdentity *identity)
Definition:
abseil-cpp/absl/synchronization/internal/waiter.h:88
absl::synchronization_internal::Waiter::Waiter
Waiter()
Definition:
abseil-cpp/absl/synchronization/internal/waiter.cc:70
absl::synchronization_internal::Waiter::operator=
Waiter & operator=(const Waiter &)=delete
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition:
third_party/abseil-cpp/absl/base/config.h:171
wakeups_
std::vector< uint32_t > wakeups_
Definition:
filter_fuzzer.cc:572
mu_
Mutex mu_
Definition:
oob_backend_metric.cc:115
absl::base_internal::ThreadIdentity::waiter_state
struct absl::base_internal::ThreadIdentity::WaiterState waiter_state
absl::synchronization_internal::Waiter::kIdlePeriods
static constexpr int kIdlePeriods
Definition:
abseil-cpp/absl/synchronization/internal/waiter.h:97
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition:
third_party/abseil-cpp/absl/base/config.h:170
absl::base_internal::ThreadIdentity::WaiterState
Definition:
abseil-cpp/absl/base/internal/thread_identity.h:145
absl::synchronization_internal::KernelTimeout
Definition:
abseil-cpp/absl/synchronization/internal/kernel_timeout.h:44
absl::synchronization_internal::Waiter::~Waiter
~Waiter()=delete
absl::synchronization_internal::Waiter::Poke
void Poke()
Definition:
abseil-cpp/absl/synchronization/internal/waiter.cc:114
absl::synchronization_internal::Waiter
Definition:
abseil-cpp/absl/synchronization/internal/waiter.h:65
absl::synchronization_internal::Waiter::Wait
bool Wait(KernelTimeout t)
Definition:
abseil-cpp/absl/synchronization/internal/waiter.cc:74
absl
Definition:
abseil-cpp/absl/algorithm/algorithm.h:31
absl::base_internal::ThreadIdentity::WaiterState::data
char data[128]
Definition:
abseil-cpp/absl/base/internal/thread_identity.h:146
int32_t
signed int int32_t
Definition:
stdint-msvc2008.h:77
grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:52