20 #include <initializer_list>
27 #include "absl/base/thread_annotations.h"
28 #include "absl/strings/str_cat.h"
29 #include "absl/types/optional.h"
45 StressTest(
size_t num_quotas,
size_t num_allocators) {
46 for (
size_t i = 0;
i < num_quotas; ++
i) {
50 std::uniform_int_distribution<size_t> dist(0, num_quotas - 1);
51 for (
size_t i = 0;
i < num_allocators; ++
i) {
59 std::vector<std::thread>
threads;
63 for (
int i = 0;
i < 2;
i++)
threads.push_back(
Run(Resizer));
73 threads.push_back(
Run([allocator, pass](StatePtr st)
mutable {
74 if (st->RememberReservation(
75 allocator->MakeReservation(st->RandomRequest()))) {
76 allocator->PostReclaimer(
77 pass, [st](absl::optional<ReclamationSweep> sweep) {
78 if (!sweep.has_value()) return;
79 st->ForgetReservations();
90 done_.store(
true, std::memory_order_relaxed);
103 explicit State(StressTest*
test)
113 MemoryQuota* RandomQuota() {
119 MemoryOwner* RandomAllocator() {
128 MemoryRequest RandomRequest() {
134 return MemoryRequest(a);
144 bool RememberReservation(MemoryAllocator::Reservation reservation)
147 bool was_empty = reservations_.empty();
148 reservations_.emplace_back(
std::move(reservation));
154 std::vector<MemoryAllocator::Reservation> ForgetReservations()
164 std::mt19937
g_{std::random_device()()};
179 std::vector<MemoryAllocator::Reservation> reservations_
183 using StatePtr = std::shared_ptr<State>;
186 static void Resizer(StatePtr st) {
187 auto* quota = st->RandomQuota();
188 size_t size = st->RandomQuotaSize();
189 quota->SetSize(
size);
197 template <
typename Fn>
200 auto state = std::make_shared<State>(
this);
201 while (!
done_.load(std::memory_order_relaxed)) {
224 if (
sizeof(
void*) != 8) {
227 "This test assumes 64-bit processors in the values it uses for sizes. "
228 "Since this test is mostly aimed at TSAN coverage, and that's mostly "
229 "platform independent, we simply skip this test in 32-bit builds.");
232 grpc_core::StressTest(16, 64).Run(8);