TEST timeseries_histogram_test SOURCES TimeseriesHistogramTest.cpp
TEST timeseries_test SOURCES TimeseriesTest.cpp
+ DIRECTORY synchronization/test/
+ TEST call_once_test SOURCES CallOnceTest.cpp
+
DIRECTORY test/
TEST ahm_int_stress_test SOURCES AHMIntStressTest.cpp
TEST arena_test SOURCES ArenaTest.cpp
TEST bit_iterator_test SOURCES BitIteratorTest.cpp
TEST bits_test SOURCES BitsTest.cpp
TEST cacheline_padded_test SOURCES CachelinePaddedTest.cpp
- TEST call_once_test SOURCES CallOnceTest.cpp
TEST checksum_test SOURCES ChecksumTest.cpp
TEST clock_gettime_wrappers_test SOURCES ClockGettimeWrappersTest.cpp
TEST concurrent_skip_list_test SOURCES ConcurrentSkipListTest.cpp
+++ /dev/null
-/*
- * Copyright 2017 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Drop-in replacement for std::call_once() with a fast path, which the GCC
- * implementation lacks. The tradeoff is a slightly larger `once_flag' struct
- * (8 bytes vs 4 bytes with GCC on Linux/x64).
- *
- * $ call_once_test --benchmark --bm_min_iters=100000000 --threads=16
- * ============================================================================
- * folly/test/CallOnceTest.cpp relative time/iter iters/s
- * ============================================================================
- * StdCallOnceBench 3.54ns 282.82M
- * FollyCallOnceBench 698.48ps 1.43G
- * ============================================================================
- */
-
-#pragma once
-
-#include <atomic>
-#include <mutex>
-#include <utility>
-
-#include <folly/Likely.h>
-#include <folly/Portability.h>
-#include <folly/SharedMutex.h>
-
-namespace folly {
-
-class once_flag {
- public:
- constexpr once_flag() noexcept = default;
- once_flag(const once_flag&) = delete;
- once_flag& operator=(const once_flag&) = delete;
-
- template <typename Callable, class... Args>
- friend void call_once(once_flag& flag, Callable&& f, Args&&... args);
- template <typename Callable, class... Args>
- friend void call_once_impl_no_inline(once_flag& flag,
- Callable&& f,
- Args&&... args);
-
- private:
- std::atomic<bool> called_{false};
- folly::SharedMutex mutex_;
-};
-
-template <class Callable, class... Args>
-void FOLLY_ALWAYS_INLINE
-call_once(once_flag& flag, Callable&& f, Args&&... args) {
- if (LIKELY(flag.called_.load(std::memory_order_acquire))) {
- return;
- }
- call_once_impl_no_inline(
- flag, std::forward<Callable>(f), std::forward<Args>(args)...);
-}
-
-// Implementation detail: out-of-line slow path
-template <class Callable, class... Args>
-void FOLLY_NOINLINE
-call_once_impl_no_inline(once_flag& flag, Callable&& f, Args&&... args) {
- std::lock_guard<folly::SharedMutex> lg(flag.mutex_);
- if (flag.called_) {
- return;
- }
-
- std::forward<Callable>(f)(std::forward<Args>(args)...);
-
- flag.called_.store(true, std::memory_order_release);
-}
-}
Benchmark.h \
Bits.h \
CachelinePadded.h \
- CallOnce.h \
Chrono.h \
ClockGettimeWrappers.h \
ConcurrentSkipList.h \
stats/MultiLevelTimeSeries.h \
stats/TimeseriesHistogram-defs.h \
stats/TimeseriesHistogram.h \
+ synchronization/CallOnce.h \
stop_watch.h \
String.h \
String-inl.h \
#include <mutex>
#include <random>
-#include <folly/CallOnce.h>
#include <folly/File.h>
#include <folly/FileUtil.h>
#include <folly/SingletonThreadLocal.h>
#include <folly/ThreadLocal.h>
#include <folly/portability/SysTime.h>
#include <folly/portability/Unistd.h>
+#include <folly/synchronization/CallOnce.h>
#include <glog/logging.h>
#ifdef _MSC_VER
#include <boost/utility.hpp>
#include <glog/logging.h>
-#include <folly/CallOnce.h>
#include <folly/Executor.h>
#include <folly/Function.h>
#include <folly/Portability.h>
#include <folly/io/async/Request.h>
#include <folly/io/async/TimeoutManager.h>
#include <folly/portability/Event.h>
+#include <folly/synchronization/CallOnce.h>
namespace folly {
--- /dev/null
+/*
+ * Copyright 2017 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Drop-in replacement for std::call_once() with a fast path, which the GCC
+ * implementation lacks. The tradeoff is a slightly larger `once_flag' struct
+ * (8 bytes vs 4 bytes with GCC on Linux/x64).
+ *
+ * $ call_once_test --benchmark --bm_min_iters=100000000 --threads=16
+ * ============================================================================
+ * folly/test/CallOnceTest.cpp relative time/iter iters/s
+ * ============================================================================
+ * StdCallOnceBench 3.54ns 282.82M
+ * FollyCallOnceBench 698.48ps 1.43G
+ * ============================================================================
+ */
+
+#pragma once
+
+#include <atomic>
+#include <mutex>
+#include <utility>
+
+#include <folly/Likely.h>
+#include <folly/Portability.h>
+#include <folly/SharedMutex.h>
+
+namespace folly {
+
+class once_flag {
+ public:
+ constexpr once_flag() noexcept = default;
+ once_flag(const once_flag&) = delete;
+ once_flag& operator=(const once_flag&) = delete;
+
+ template <typename Callable, class... Args>
+ friend void call_once(once_flag& flag, Callable&& f, Args&&... args);
+ template <typename Callable, class... Args>
+ friend void call_once_impl_no_inline(once_flag& flag,
+ Callable&& f,
+ Args&&... args);
+
+ private:
+ std::atomic<bool> called_{false};
+ folly::SharedMutex mutex_;
+};
+
+template <class Callable, class... Args>
+void FOLLY_ALWAYS_INLINE
+call_once(once_flag& flag, Callable&& f, Args&&... args) {
+ if (LIKELY(flag.called_.load(std::memory_order_acquire))) {
+ return;
+ }
+ call_once_impl_no_inline(
+ flag, std::forward<Callable>(f), std::forward<Args>(args)...);
+}
+
+// Implementation detail: out-of-line slow path
+template <class Callable, class... Args>
+void FOLLY_NOINLINE
+call_once_impl_no_inline(once_flag& flag, Callable&& f, Args&&... args) {
+ std::lock_guard<folly::SharedMutex> lg(flag.mutex_);
+ if (flag.called_) {
+ return;
+ }
+
+ std::forward<Callable>(f)(std::forward<Args>(args)...);
+
+ flag.called_.store(true, std::memory_order_release);
+}
+}
--- /dev/null
+/*
+ * Copyright 2017 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <folly/synchronization/CallOnce.h>
+
+#include <deque>
+#include <mutex>
+#include <thread>
+
+#include <folly/Benchmark.h>
+
+#include <glog/logging.h>
+
+DEFINE_int32(threads, 16, "benchmark concurrency");
+
+template <typename CallOnceFunc>
+void bm_impl(CallOnceFunc&& fn, int64_t iters) {
+ std::deque<std::thread> threads;
+ for (int i = 0; i < FLAGS_threads; ++i) {
+ threads.emplace_back([&fn, iters] {
+ for (int64_t j = 0; j < iters; ++j) {
+ fn();
+ }
+ });
+ }
+ for (std::thread& t : threads) {
+ t.join();
+ }
+}
+
+BENCHMARK(StdCallOnceBench, iters) {
+ std::once_flag flag;
+ int out = 0;
+ bm_impl([&] { std::call_once(flag, [&] { ++out; }); }, iters);
+ CHECK_EQ(1, out);
+}
+
+BENCHMARK(FollyCallOnceBench, iters) {
+ folly::once_flag flag;
+ int out = 0;
+ bm_impl([&] { folly::call_once(flag, [&] { ++out; }); }, iters);
+ CHECK_EQ(1, out);
+}
+
+int main(int argc, char** argv) {
+ gflags::ParseCommandLineFlags(&argc, &argv, true);
+ folly::runBenchmarks();
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright 2017 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <deque>
+#include <mutex>
+#include <thread>
+
+#include <folly/portability/GFlags.h>
+#include <folly/portability/GTest.h>
+#include <folly/synchronization/CallOnce.h>
+
+#include <glog/logging.h>
+
+DEFINE_int32(threads, 16, "benchmark concurrency");
+
+template <typename CallOnceFunc>
+void bm_impl(CallOnceFunc&& fn, int64_t iters) {
+ std::deque<std::thread> threads;
+ for (int i = 0; i < FLAGS_threads; ++i) {
+ threads.emplace_back([&fn, iters] {
+ for (int64_t j = 0; j < iters; ++j) {
+ fn();
+ }
+ });
+ }
+ for (std::thread& t : threads) {
+ t.join();
+ }
+}
+
+TEST(FollyCallOnce, Simple) {
+ folly::once_flag flag;
+ auto fn = [&](int* outp) { ++*outp; };
+ int out = 0;
+ folly::call_once(flag, fn, &out);
+ folly::call_once(flag, fn, &out);
+ ASSERT_EQ(1, out);
+}
+
+TEST(FollyCallOnce, Exception) {
+ struct ExpectedException {};
+ folly::once_flag flag;
+ size_t numCalls = 0;
+ EXPECT_THROW(
+ folly::call_once(
+ flag,
+ [&] {
+ ++numCalls;
+ throw ExpectedException();
+ }),
+ ExpectedException);
+ EXPECT_EQ(1, numCalls);
+ folly::call_once(flag, [&] { ++numCalls; });
+ EXPECT_EQ(2, numCalls);
+}
+
+TEST(FollyCallOnce, Stress) {
+ for (int i = 0; i < 100; ++i) {
+ folly::once_flag flag;
+ int out = 0;
+ bm_impl([&] { folly::call_once(flag, [&] { ++out; }); }, 100);
+ ASSERT_EQ(1, out);
+ }
+}
+++ /dev/null
-/*
- * Copyright 2017 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <folly/CallOnce.h>
-
-#include <deque>
-#include <mutex>
-#include <thread>
-
-#include <folly/Benchmark.h>
-
-#include <glog/logging.h>
-
-DEFINE_int32(threads, 16, "benchmark concurrency");
-
-template <typename CallOnceFunc>
-void bm_impl(CallOnceFunc&& fn, int64_t iters) {
- std::deque<std::thread> threads;
- for (int i = 0; i < FLAGS_threads; ++i) {
- threads.emplace_back([&fn, iters] {
- for (int64_t j = 0; j < iters; ++j) {
- fn();
- }
- });
- }
- for (std::thread& t : threads) {
- t.join();
- }
-}
-
-BENCHMARK(StdCallOnceBench, iters) {
- std::once_flag flag;
- int out = 0;
- bm_impl([&] { std::call_once(flag, [&] { ++out; }); }, iters);
- CHECK_EQ(1, out);
-}
-
-BENCHMARK(FollyCallOnceBench, iters) {
- folly::once_flag flag;
- int out = 0;
- bm_impl([&] { folly::call_once(flag, [&] { ++out; }); }, iters);
- CHECK_EQ(1, out);
-}
-
-int main(int argc, char** argv) {
- gflags::ParseCommandLineFlags(&argc, &argv, true);
- folly::runBenchmarks();
- return 0;
-}
+++ /dev/null
-/*
- * Copyright 2017 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <deque>
-#include <mutex>
-#include <thread>
-
-#include <folly/CallOnce.h>
-#include <folly/portability/GFlags.h>
-#include <folly/portability/GTest.h>
-
-#include <glog/logging.h>
-
-DEFINE_int32(threads, 16, "benchmark concurrency");
-
-template <typename CallOnceFunc>
-void bm_impl(CallOnceFunc&& fn, int64_t iters) {
- std::deque<std::thread> threads;
- for (int i = 0; i < FLAGS_threads; ++i) {
- threads.emplace_back([&fn, iters] {
- for (int64_t j = 0; j < iters; ++j) {
- fn();
- }
- });
- }
- for (std::thread& t : threads) {
- t.join();
- }
-}
-
-TEST(FollyCallOnce, Simple) {
- folly::once_flag flag;
- auto fn = [&](int* outp) { ++*outp; };
- int out = 0;
- folly::call_once(flag, fn, &out);
- folly::call_once(flag, fn, &out);
- ASSERT_EQ(1, out);
-}
-
-TEST(FollyCallOnce, Exception) {
- struct ExpectedException {};
- folly::once_flag flag;
- size_t numCalls = 0;
- EXPECT_THROW(
- folly::call_once(
- flag,
- [&] {
- ++numCalls;
- throw ExpectedException();
- }),
- ExpectedException);
- EXPECT_EQ(1, numCalls);
- folly::call_once(flag, [&] { ++numCalls; });
- EXPECT_EQ(2, numCalls);
-}
-
-TEST(FollyCallOnce, Stress) {
- for (int i = 0; i < 100; ++i) {
- folly::once_flag flag;
- int out = 0;
- bm_impl([&] { folly::call_once(flag, [&] { ++out; }); }, 100);
- ASSERT_EQ(1, out);
- }
-}