Skip to content

Commit 099bcef

Browse files
committed
feat universal: allow safe thread_local usage, add utilities for randomness
1 parent e119309 commit 099bcef

File tree

36 files changed

+855
-265
lines changed

36 files changed

+855
-265
lines changed

.mapping.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3067,8 +3067,10 @@
30673067
"universal/include/userver/cache/lru_set.hpp":"taxi/uservices/userver/universal/include/userver/cache/lru_set.hpp",
30683068
"universal/include/userver/compiler/demangle.hpp":"taxi/uservices/userver/universal/include/userver/compiler/demangle.hpp",
30693069
"universal/include/userver/compiler/impl/constexpr.hpp":"taxi/uservices/userver/universal/include/userver/compiler/impl/constexpr.hpp",
3070+
"universal/include/userver/compiler/impl/lifetime.hpp":"taxi/uservices/userver/universal/include/userver/compiler/impl/lifetime.hpp",
30703071
"universal/include/userver/compiler/impl/tls.hpp":"taxi/uservices/userver/universal/include/userver/compiler/impl/tls.hpp",
30713072
"universal/include/userver/compiler/select.hpp":"taxi/uservices/userver/universal/include/userver/compiler/select.hpp",
3073+
"universal/include/userver/compiler/thread_local.hpp":"taxi/uservices/userver/universal/include/userver/compiler/thread_local.hpp",
30723074
"universal/include/userver/crypto/algorithm.hpp":"taxi/uservices/userver/universal/include/userver/crypto/algorithm.hpp",
30733075
"universal/include/userver/crypto/base64.hpp":"taxi/uservices/userver/universal/include/userver/crypto/base64.hpp",
30743076
"universal/include/userver/crypto/basic_types.hpp":"taxi/uservices/userver/universal/include/userver/crypto/basic_types.hpp",
@@ -3078,6 +3080,7 @@
30783080
"universal/include/userver/crypto/hash.hpp":"taxi/uservices/userver/universal/include/userver/crypto/hash.hpp",
30793081
"universal/include/userver/crypto/private_key.hpp":"taxi/uservices/userver/universal/include/userver/crypto/private_key.hpp",
30803082
"universal/include/userver/crypto/public_key.hpp":"taxi/uservices/userver/universal/include/userver/crypto/public_key.hpp",
3083+
"universal/include/userver/crypto/random.hpp":"taxi/uservices/userver/universal/include/userver/crypto/random.hpp",
30813084
"universal/include/userver/crypto/signers.hpp":"taxi/uservices/userver/universal/include/userver/crypto/signers.hpp",
30823085
"universal/include/userver/crypto/verifiers.hpp":"taxi/uservices/userver/universal/include/userver/crypto/verifiers.hpp",
30833086
"universal/include/userver/decimal64/decimal64.hpp":"taxi/uservices/userver/universal/include/userver/decimal64/decimal64.hpp",
@@ -3276,6 +3279,8 @@
32763279
"universal/src/compiler/demangle_test.cpp":"taxi/uservices/userver/universal/src/compiler/demangle_test.cpp",
32773280
"universal/src/compiler/relax_cpu.hpp":"taxi/uservices/userver/universal/src/compiler/relax_cpu.hpp",
32783281
"universal/src/compiler/select_test.cpp":"taxi/uservices/userver/universal/src/compiler/select_test.cpp",
3282+
"universal/src/compiler/thread_local.cpp":"taxi/uservices/userver/universal/src/compiler/thread_local.cpp",
3283+
"universal/src/compiler/thread_local_test.cpp":"taxi/uservices/userver/universal/src/compiler/thread_local_test.cpp",
32793284
"universal/src/crypto/algorithm.cpp":"taxi/uservices/userver/universal/src/crypto/algorithm.cpp",
32803285
"universal/src/crypto/base.cpp":"taxi/uservices/userver/universal/src/crypto/base.cpp",
32813286
"universal/src/crypto/base64.cpp":"taxi/uservices/userver/universal/src/crypto/base64.cpp",
@@ -3290,6 +3295,7 @@
32903295
"universal/src/crypto/private_key.cpp":"taxi/uservices/userver/universal/src/crypto/private_key.cpp",
32913296
"universal/src/crypto/public_key.cpp":"taxi/uservices/userver/universal/src/crypto/public_key.cpp",
32923297
"universal/src/crypto/public_key_test.cpp":"taxi/uservices/userver/universal/src/crypto/public_key_test.cpp",
3298+
"universal/src/crypto/random.cpp":"taxi/uservices/userver/universal/src/crypto/random.cpp",
32933299
"universal/src/crypto/signature_test.cpp":"taxi/uservices/userver/universal/src/crypto/signature_test.cpp",
32943300
"universal/src/crypto/signers.cpp":"taxi/uservices/userver/universal/src/crypto/signers.cpp",
32953301
"universal/src/crypto/verifiers.cpp":"taxi/uservices/userver/universal/src/crypto/verifiers.cpp",

core/include/userver/rcu/rcu.hpp

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include <list>
99
#include <unordered_set>
1010

11-
#include <userver/compiler/impl/tls.hpp>
11+
#include <userver/compiler/thread_local.hpp>
1212
#include <userver/engine/async.hpp>
1313
#include <userver/engine/mutex.hpp>
1414
#include <userver/logging/log.hpp>
@@ -64,13 +64,8 @@ struct CachedData {
6464
};
6565

6666
template <typename T, typename RcuTraits>
67-
USERVER_IMPL_PREVENT_TLS_CACHING CachedData<T, RcuTraits>& GetCachedData() {
68-
thread_local CachedData<T, RcuTraits> cache;
69-
70-
// NOLINTNEXTLINE
71-
USERVER_IMPL_PREVENT_TLS_CACHING_ASM;
72-
return cache;
73-
}
67+
inline compiler::ThreadLocal local_cached_data =
68+
[] { return CachedData<T, RcuTraits>{}; };
7469

7570
uint64_t GetNextEpoch() noexcept;
7671

@@ -415,8 +410,8 @@ class Variable final {
415410
private:
416411
T* GetCurrent() const { return current_.load(); }
417412

418-
impl::HazardPointerRecord<T, RcuTraits>* MakeHazardPointerCached() const {
419-
auto& cache = impl::GetCachedData<T, RcuTraits>();
413+
impl::HazardPointerRecord<T, RcuTraits>* MakeHazardPointerCached(
414+
impl::CachedData<T, RcuTraits>& cache) const {
420415
auto* hp = cache.hp;
421416
T* ptr = nullptr;
422417
if (hp && cache.variable == this && cache.variable_epoch == epoch_) {
@@ -448,16 +443,16 @@ class Variable final {
448443
}
449444

450445
impl::HazardPointerRecord<T, RcuTraits>& MakeHazardPointer() const {
451-
auto* hp = MakeHazardPointerCached();
446+
auto cache = impl::local_cached_data<T, RcuTraits>.Use();
447+
auto* hp = MakeHazardPointerCached(*cache);
452448
if (!hp) {
453449
hp = MakeHazardPointerFast();
454450
// all buckets are full, create a new one
455451
if (!hp) hp = MakeHazardPointerSlow();
456452

457-
auto& cache = impl::GetCachedData<T, RcuTraits>();
458-
cache.hp = hp;
459-
cache.variable = this;
460-
cache.variable_epoch = epoch_;
453+
cache->hp = hp;
454+
cache->variable = this;
455+
cache->variable_epoch = epoch_;
461456
}
462457
UASSERT(&hp->owner == this);
463458
return *hp;

core/include/userver/storages/secdist/secdist.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ class Secdist final {
144144
EventSource::Function&& func);
145145

146146
class Impl;
147-
utils::FastPimpl<Impl, 1136, 16> impl_;
147+
utils::FastPimpl<Impl, 1152, 16> impl_;
148148
};
149149

150150
template <typename Class>

core/include/userver/utils/periodic_task.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <chrono>
77
#include <functional>
88
#include <optional>
9+
#include <random>
910
#include <string>
1011

1112
#include <userver/engine/condition_variable.hpp>
@@ -214,6 +215,7 @@ class PeriodicTask final {
214215
rcu::Variable<Settings> settings_;
215216
engine::SingleConsumerEvent changed_event_;
216217
std::atomic<bool> should_force_step_{false};
218+
std::optional<std::minstd_rand> mutate_period_random_;
217219

218220
// For kNow only
219221
engine::Mutex step_mutex_;

core/src/dump/common_test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ TYPED_TEST(DumpCommonNumeric, Numeric) {
5151
EXPECT_TRUE(std::isnan(dump::FromBinary<Num>(
5252
dump::ToBinary<Num>(std::numeric_limits<Num>::quiet_NaN()))));
5353
} else {
54-
auto& engine = utils::DefaultRandom();
5554
// 8-bit types are not allowed in uniform_int_distribution, so increase the
5655
// T size.
5756
std::uniform_int_distribution<std::common_type_t<Num, unsigned short>>
5857
distribution(std::numeric_limits<Num>::min(),
5958
std::numeric_limits<Num>::max());
6059
for (int i = 0; i < 1000; ++i) {
61-
TestWriteReadCycle(static_cast<Num>(distribution(engine)));
60+
TestWriteReadCycle(
61+
static_cast<Num>(utils::WithDefaultRandom(distribution)));
6262
}
6363
}
6464
}

core/src/dump/operations_encrypted.cpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include <cryptopp/modes.h>
99
#include <cryptopp/osrng.h>
1010

11-
#include <userver/compiler/impl/tls.hpp>
11+
#include <userver/crypto/random.hpp>
1212
#include <userver/fs/blocking/write.hpp>
1313
#include <userver/utils/assert.hpp>
1414
#include <userver/utils/cpu_relax.hpp>
@@ -48,23 +48,12 @@ inline const unsigned char* GetBytes(const T& data) {
4848
return reinterpret_cast<const unsigned char*>(data.GetUnderlying().data());
4949
}
5050

51-
USERVER_IMPL_PREVENT_TLS_CACHING IV GenerateIv() {
52-
unsigned char iv[kIvSize];
53-
thread_local ::CryptoPP::AutoSeededRandomPool pool;
54-
55-
// NOLINTNEXTLINE
56-
USERVER_IMPL_PREVENT_TLS_CACHING_ASM;
57-
pool.GenerateBlock(iv, kIvSize);
58-
59-
return IV(iv, iv + kIvSize);
60-
}
61-
6251
EncryptedWriter::EncryptedWriter(std::string filename,
6352
const SecretKey& secret_key,
6453
boost::filesystem::perms perms,
6554
tracing::ScopeTime& scope)
6655
: impl_(std::move(filename), &scope) {
67-
auto iv = GenerateIv();
56+
IV iv{crypto::GenerateRandomBlock(kIvSize)};
6857
impl_->encryption.SetKeyWithIV(GetBytes(secret_key),
6958
secret_key.GetUnderlying().size(),
7059
GetBytes(iv), iv.size());
@@ -114,11 +103,11 @@ EncryptedReader::EncryptedReader(std::string filename,
114103
const SecretKey& secret_key) {
115104
impl_->filename = filename;
116105

117-
bool pump_all = false;
106+
constexpr bool kPumpAll = false;
118107

119108
IV iv;
120109
impl_->file = std::make_unique<::CryptoPP::FileSource>(
121-
impl_->filename.c_str(), pump_all,
110+
impl_->filename.c_str(), kPumpAll,
122111
new ::CryptoPP::StringSink(iv.GetUnderlying()));
123112

124113
auto& file = *impl_->file;

core/src/engine/mutex_benchmark.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ void generic_contention_with_payload(benchmark::State& state) {
180180
while (run) {
181181
m->lock();
182182
for (int i = 0; i < 10; ++i) {
183-
benchmark::DoNotOptimize(utils::DefaultRandom()());
183+
benchmark::DoNotOptimize(utils::Rand());
184184
}
185185
m->unlock();
186186
++local_lock_unlock_count;
@@ -194,7 +194,7 @@ void generic_contention_with_payload(benchmark::State& state) {
194194
for ([[maybe_unused]] auto _ : state) {
195195
m->lock();
196196
for (int i = 0; i < 10; ++i) {
197-
benchmark::DoNotOptimize(utils::DefaultRandom()());
197+
benchmark::DoNotOptimize(utils::Rand());
198198
}
199199
m->unlock();
200200
++local_lock_unlock_count;

core/src/engine/task/task_context.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <engine/coro/pool.hpp>
1010
#include <logging/log_extra_stacktrace.hpp>
11+
#include <userver/compiler/impl/tls.hpp>
1112
#include <userver/engine/exception.hpp>
1213
#include <userver/engine/impl/task_context_factory.hpp>
1314
#include <userver/engine/task/cancel.hpp>
@@ -20,7 +21,6 @@
2021
#include <engine/task/coro_unwinder.hpp>
2122
#include <engine/task/cxxabi_eh_globals.hpp>
2223
#include <engine/task/task_processor.hpp>
23-
#include <userver/compiler/impl/tls.hpp>
2424
#include <utils/impl/assert_extra.hpp>
2525

2626
USERVER_NAMESPACE_BEGIN
@@ -52,17 +52,14 @@ impl::TaskContext& GetCurrentTaskContext() noexcept {
5252
"outside of coroutine context");
5353
}
5454

55-
// NOLINTNEXTLINE
5655
USERVER_IMPL_PREVENT_TLS_CACHING_ASM;
5756

5857
return *current_task_context_ptr;
5958
}
6059

6160
USERVER_IMPL_PREVENT_TLS_CACHING
6261
impl::TaskContext* GetCurrentTaskContextUnchecked() noexcept {
63-
// NOLINTNEXTLINE
6462
USERVER_IMPL_PREVENT_TLS_CACHING_ASM;
65-
6663
return current_task_context_ptr;
6764
}
6865

core/src/engine/task/task_counter.cpp

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
#include <engine/task/task_counter.hpp>
22

3-
#include <algorithm>
43
#include <thread>
54

6-
#include <userver/compiler/impl/constexpr.hpp>
7-
#include <userver/compiler/impl/tls.hpp>
5+
#include <userver/compiler/thread_local.hpp>
86
#include <userver/utils/assert.hpp>
97

108
USERVER_NAMESPACE_BEGIN
@@ -22,16 +20,9 @@ struct LocalTaskCounterData final {
2220
std::size_t task_processor_thread_index{};
2321
};
2422

25-
thread_local USERVER_IMPL_CONSTINIT LocalTaskCounterData
26-
local_task_counter_data;
27-
28-
USERVER_IMPL_PREVENT_TLS_CACHING LocalTaskCounterData
29-
GetLocalTaskCounterData() noexcept {
30-
// NOLINTNEXTLINE
31-
USERVER_IMPL_PREVENT_TLS_CACHING_ASM;
32-
33-
return local_task_counter_data;
34-
}
23+
compiler::ThreadLocal local_task_counter_data = [] {
24+
return LocalTaskCounterData{};
25+
};
3526

3627
} // namespace
3728

@@ -176,26 +167,27 @@ Rate TaskCounter::GetApproximate(GlobalCounterId id) const noexcept {
176167
}
177168

178169
void TaskCounter::Increment(LocalCounterId id) noexcept {
179-
const auto local_data = GetLocalTaskCounterData();
180-
UASSERT(local_data.local_counter == this);
181-
auto& counter = (*local_counters_[local_data.task_processor_thread_index])
170+
auto local_data = local_task_counter_data.Use();
171+
UASSERT(local_data->local_counter == this);
172+
auto& counter = (*local_counters_[local_data->task_processor_thread_index])
182173
[static_cast<std::size_t>(id)];
183174
counter.Store(counter.Load() + Rate{1});
184175
}
185176

186177
void TaskCounter::Increment(GlobalCounterId id) noexcept {
187-
const auto local_data = GetLocalTaskCounterData();
178+
auto local_data = local_task_counter_data.Use();
188179
auto& counter =
189-
(local_data.local_counter == this)
190-
? (*local_counters_[local_data.task_processor_thread_index])
180+
(local_data->local_counter == this)
181+
? (*local_counters_[local_data->task_processor_thread_index])
191182
[static_cast<std::size_t>(id)]
192183
: *global_counters_[static_cast<std::size_t>(id)];
193184
// seq_cst synchronizes-with MayHaveTasksAlive.
194185
counter.Add(Rate{1}, std::memory_order_seq_cst);
195186
}
196187

197188
void SetLocalTaskCounterData(TaskCounter& counter, std::size_t thread_id) {
198-
local_task_counter_data = {&counter, thread_id};
189+
auto local_data = local_task_counter_data.Use();
190+
*local_data = {&counter, thread_id};
199191
}
200192

201193
} // namespace engine::impl

core/src/engine/task/task_processor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ void EmitMagicNanosleep() {
5656

5757
void TaskProcessorThreadStartedHook() {
5858
utils::impl::AssertStaticRegistrationFinished();
59-
(void)utils::DefaultRandom();
59+
utils::WithDefaultRandom([](auto&) {});
6060
for (const auto& func : ThreadStartedHooks()) {
6161
func();
6262
}

0 commit comments

Comments
 (0)