using SingletonCreationError = Singleton<T, Tag, CreationErrorTag>;
TEST(Singleton, SingletonCreationError) {
- auto& vault = *SingletonVault::singleton<CreationErrorTag>();
+ SingletonVault::singleton<CreationErrorTag>();
SingletonCreationError<ErrorConstructor> error_once_singleton;
// first time should error out
[&] {didEagerInit = true; return new std::string("foo"); })
.shouldEagerInit();
folly::EventBase eb;
+ folly::Baton<> done;
vault.registrationComplete();
EXPECT_FALSE(didEagerInit);
- auto result = vault.doEagerInitVia(&eb); // a Future<Unit> is returned
+ vault.doEagerInitVia(eb, &done);
eb.loop();
- result.get(); // ensure this completed successfully and didn't hang forever
+ done.wait();
EXPECT_TRUE(didEagerInit);
sing.get_weak(); // (avoid compile error complaining about unused var 'sing')
}
for (size_t j = 0; j < kThreads; j++) {
threads.push_back(std::make_shared<std::thread>([&] {
barrier.wait();
- vault.doEagerInitVia(&exe).get();
+ vault.doEagerInitVia(exe);
}));
}
int val = 0;
};
-BENCHMARK(NormalSingleton, n) {
- for (size_t i = 0; i < n; ++i) {
+void run4Threads(std::function<void()> f) {
+ std::vector<std::thread> threads;
+ for (size_t i = 0; i < 4; ++ i) {
+ threads.emplace_back(f);
+ }
+ for (auto& thread : threads) {
+ thread.join();
+ }
+}
+
+void normalSingleton(size_t n) {
+ for (size_t i = 0; i < n; ++ i) {
doNotOptimizeAway(getNormalSingleton());
}
}
-BENCHMARK_RELATIVE(MeyersSingleton, n) {
+BENCHMARK(NormalSingleton, n) {
+ normalSingleton(n);
+}
+
+BENCHMARK(NormalSingleton4Threads, n) {
+ run4Threads([=]() {
+ normalSingleton(n);
+ });
+}
+
+void meyersSingleton(size_t n) {
for (size_t i = 0; i < n; ++i) {
doNotOptimizeAway(getMeyersSingleton());
}
}
+
+BENCHMARK_RELATIVE(MeyersSingleton, n) {
+ meyersSingleton(n);
+}
+
+BENCHMARK_RELATIVE(MeyersSingleton4Threads, n) {
+ run4Threads([=]() {
+ meyersSingleton(n);
+ });
+}
+
struct BenchmarkTag {};
template <typename T, typename Tag = detail::DefaultTag>
using SingletonBenchmark = Singleton <T, Tag, BenchmarkTag>;
struct GetTag{};
+struct GetSharedTag{};
struct GetWeakTag{};
SingletonBenchmark<BenchmarkSingleton, GetTag> benchmark_singleton_get;
+SingletonBenchmark<BenchmarkSingleton, GetSharedTag>
+benchmark_singleton_get_shared;
SingletonBenchmark<BenchmarkSingleton, GetWeakTag> benchmark_singleton_get_weak;
-BENCHMARK_RELATIVE(FollySingleton, n) {
+void follySingletonRaw(size_t n) {
+ for (size_t i = 0; i < n; ++i) {
+ SingletonBenchmark<BenchmarkSingleton, GetTag>::get();
+ }
+}
+
+BENCHMARK_RELATIVE(FollySingletonRaw, n) {
+ follySingletonRaw(n);
+}
+
+BENCHMARK_RELATIVE(FollySingletonRaw4Threads, n) {
+ run4Threads([=]() {
+ follySingletonRaw(n);
+ });
+}
+
+void follySingletonSharedPtr(size_t n) {
for (size_t i = 0; i < n; ++i) {
- SingletonBenchmark<BenchmarkSingleton, GetTag>::try_get();
+ SingletonBenchmark<BenchmarkSingleton, GetSharedTag>::try_get();
}
}
-BENCHMARK_RELATIVE(FollySingletonWeak, n) {
+BENCHMARK_RELATIVE(FollySingletonSharedPtr, n) {
+ follySingletonSharedPtr(n);
+}
+
+BENCHMARK_RELATIVE(FollySingletonSharedPtr4Threads, n) {
+ run4Threads([=]() {
+ follySingletonSharedPtr(n);
+ });
+}
+
+void follySingletonWeakPtr(size_t n) {
for (size_t i = 0; i < n; ++i) {
SingletonBenchmark<BenchmarkSingleton, GetWeakTag>::get_weak();
}
}
+BENCHMARK_RELATIVE(FollySingletonWeakPtr, n) {
+ follySingletonWeakPtr(n);
+}
+
+BENCHMARK_RELATIVE(FollySingletonWeakPtr4Threads, n) {
+ run4Threads([=]() {
+ follySingletonWeakPtr(n);
+ });
+}
+
int main(int argc, char* argv[]) {
testing::InitGoogleTest(&argc, argv);
google::InitGoogleLogging(argv[0]);