#include <stddef.h>
#include <memory>
#include <vector>
#include "base/barrier_closure.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/bind.h"
#include "base/threading/simple_thread.h"
#include "base/threading/thread_local_storage.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/perf/perf_result_reporter.h"
#if BUILDFLAG(IS_WIN)
#include <windows.h>
#include "base/win/windows_types.h"
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#include <pthread.h>
#endif
namespace base {
namespace internal {
namespace {
constexpr size_t kCount = …;
constexpr char kMetricPrefixThreadLocalStorage[] = …;
constexpr char kMetricBaseRead[] = …;
constexpr char kMetricBaseWrite[] = …;
constexpr char kMetricBaseReadWrite[] = …;
constexpr char kMetricSuffixThroughput[] = …;
constexpr char kMetricSuffixOperationTime[] = …;
constexpr char kStoryBaseTLS[] = …;
#if BUILDFLAG(IS_WIN)
constexpr char kStoryBasePlatformFLS[] = "platform_fiber_local_storage";
#endif
constexpr char kStoryBasePlatformTLS[] = …;
constexpr char kStoryBaseCPPTLS[] = …;
constexpr char kStorySuffixFourThreads[] = …;
perf_test::PerfResultReporter SetUpReporter(const std::string& story_name) { … }
class TLSThread : public SimpleThread { … };
class ThreadLocalStoragePerfTest : public testing::Test { … };
}
TEST_F(ThreadLocalStoragePerfTest, ThreadLocalStorage) { … }
#if BUILDFLAG(IS_WIN)
void WINAPI destroy(void*) {}
TEST_F(ThreadLocalStoragePerfTest, PlatformFls) {
DWORD key = FlsAlloc(destroy);
ASSERT_NE(PlatformThreadLocalStorage::TLS_KEY_OUT_OF_INDEXES, key);
auto read = [&]() { return reinterpret_cast<intptr_t>(FlsGetValue(key)); };
auto write = [&](intptr_t value) {
FlsSetValue(key, reinterpret_cast<void*>(value));
};
Benchmark(kStoryBasePlatformFLS, read, write, 10000000, 1);
Benchmark(std::string(kStoryBasePlatformFLS) + kStorySuffixFourThreads, read,
write, kCount, 4);
}
TEST_F(ThreadLocalStoragePerfTest, PlatformTls) {
DWORD key = TlsAlloc();
ASSERT_NE(PlatformThreadLocalStorage::TLS_KEY_OUT_OF_INDEXES, key);
auto read = [&]() { return reinterpret_cast<intptr_t>(TlsGetValue(key)); };
auto write = [&](intptr_t value) {
TlsSetValue(key, reinterpret_cast<void*>(value));
};
Benchmark(kStoryBasePlatformTLS, read, write, 10000000, 1);
Benchmark(std::string(kStoryBasePlatformTLS) + kStorySuffixFourThreads, read,
write, kCount, 4);
}
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
TEST_F(ThreadLocalStoragePerfTest, PlatformTls) { … }
#endif
TEST_F(ThreadLocalStoragePerfTest, Cpp11Tls) { … }
}
}