2 * Copyright 2017 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include <folly/Benchmark.h>
22 #include <folly/Portability.h>
23 #include <folly/concurrency/CoreCachedSharedPtr.h>
24 #include <folly/portability/GTest.h>
26 TEST(CoreCachedSharedPtr, Basic) {
27 auto p = std::make_shared<int>(1);
28 std::weak_ptr<int> wp(p);
30 folly::CoreCachedSharedPtr<int> cached(p);
31 folly::CoreCachedWeakPtr<int> wcached(cached);
33 std::shared_ptr<int> p2 = cached.get();
34 std::weak_ptr<int> wp2 = wcached.get();
35 ASSERT_TRUE(p2 != nullptr);
37 ASSERT_FALSE(wp2.expired());
42 ASSERT_FALSE(wp.expired());
43 // Here we don't know anything about wp2: could be expired even if
44 // there is a living reference to the main object.
47 ASSERT_TRUE(wp.expired());
48 ASSERT_TRUE(wp2.expired());
53 template <class Operation>
54 void parallelRun(Operation op, size_t numThreads, size_t iters) {
55 std::vector<std::thread> threads;
57 // Prevent the compiler from hoisting code out of the loop.
58 auto opNoinline = [&]() FOLLY_NOINLINE { op(); };
60 for (size_t t = 0; t < numThreads; ++t) {
61 threads.emplace_back([&] {
62 for (size_t i = 0; i < iters; ++i) {
68 for (auto& t : threads)
72 void benchmarkSharedPtrCopy(size_t numThreads, size_t iters) {
73 auto p = std::make_shared<int>(1);
74 parallelRun([&] { return p; }, numThreads, iters);
77 void benchmarkWeakPtrLock(size_t numThreads, size_t iters) {
78 auto p = std::make_shared<int>(1);
79 std::weak_ptr<int> wp = p;
80 parallelRun([&] { return wp.lock(); }, numThreads, iters);
83 void benchmarkCoreCachedSharedPtrGet(size_t numThreads, size_t iters) {
84 folly::CoreCachedSharedPtr<int> p(std::make_shared<int>(1));
85 parallelRun([&] { return p.get(); }, numThreads, iters);
88 void benchmarkCoreCachedWeakPtrLock(size_t numThreads, size_t iters) {
89 folly::CoreCachedSharedPtr<int> p(std::make_shared<int>(1));
90 folly::CoreCachedWeakPtr<int> wp(p);
91 parallelRun([&] { return wp.get().lock(); }, numThreads, iters);
96 BENCHMARK(SharedPtrSingleThread, n) {
97 benchmarkSharedPtrCopy(1, n);
99 BENCHMARK(WeakPtrSingleThread, n) {
100 benchmarkWeakPtrLock(1, n);
102 BENCHMARK(CoreCachedSharedPtrSingleThread, n) {
103 benchmarkCoreCachedSharedPtrGet(1, n);
105 BENCHMARK(CoreCachedWeakPtrSingleThread, n) {
106 benchmarkCoreCachedWeakPtrLock(1, n);
109 BENCHMARK_DRAW_LINE();
111 BENCHMARK(SharedPtr4Threads, n) {
112 benchmarkSharedPtrCopy(4, n);
114 BENCHMARK(WeakPtr4Threads, n) {
115 benchmarkWeakPtrLock(4, n);
117 BENCHMARK(CoreCachedSharedPtr4Threads, n) {
118 benchmarkCoreCachedSharedPtrGet(4, n);
120 BENCHMARK(CoreCachedWeakPtr4Threads, n) {
121 benchmarkCoreCachedWeakPtrLock(4, n);
124 BENCHMARK_DRAW_LINE();
126 BENCHMARK(SharedPtr16Threads, n) {
127 benchmarkSharedPtrCopy(16, n);
129 BENCHMARK(WeakPtr16Threads, n) {
130 benchmarkWeakPtrLock(16, n);
132 BENCHMARK(CoreCachedSharedPtr16Threads, n) {
133 benchmarkCoreCachedSharedPtrGet(16, n);
135 BENCHMARK(CoreCachedWeakPtr16Threads, n) {
136 benchmarkCoreCachedWeakPtrLock(16, n);
139 int main(int argc, char** argv) {
140 testing::InitGoogleTest(&argc, argv);
141 gflags::ParseCommandLineFlags(&argc, &argv, true);
143 auto ret = RUN_ALL_TESTS();
144 if (ret == 0 && FLAGS_benchmark) {
145 folly::runBenchmarks();