Merge mozilla-central to autoland. a=merge CLOSED TREE
[gecko.git] / memory / build / mozmemory_utils.h
blobaf9e96b4c7b13f9ed54b10e1dbd47f66ffd7d65e
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozjemalloc_utils_h
8 #define mozjemalloc_utils_h
10 #include <optional>
11 #include <type_traits>
13 #if defined(MOZ_MEMORY) && defined(XP_WIN)
14 # include "mozmemory_wrap.h"
15 #endif
17 namespace mozilla {
19 namespace detail {
20 // Helper for StallAndRetry error messages.
21 template <typename T>
22 constexpr bool is_std_optional = false;
23 template <typename T>
24 constexpr bool is_std_optional<std::optional<T>> = true;
25 } // namespace detail
27 struct StallSpecs {
28 // Maximum number of retry-attempts before giving up.
29 size_t maxAttempts;
30 // Delay time between successive events.
31 size_t delayMs;
33 // Retry a fallible operation until it succeeds or until we've run out of
34 // retries.
36 // Note that this invokes `aDelayFunc` immediately upon being called! It's
37 // intended for use in the unhappy path, after an initial attempt has failed.
39 // The function type here may be read:
40 // ```
41 // fn StallAndRetry<R>(
42 // delay_func: impl Fn(usize) -> (),
43 // operation: impl Fn() -> Option<R>,
44 // ) -> Option<R>;
45 // ```
47 template <typename DelayFunc, typename OpFunc>
48 auto StallAndRetry(DelayFunc&& aDelayFunc, OpFunc&& aOperation) const
49 -> decltype(aOperation()) {
51 // Explicit typecheck for OpFunc, to provide an explicit error message.
52 using detail::is_std_optional;
53 static_assert(is_std_optional<decltype(aOperation())>,
54 "aOperation() must return std::optional");
56 // (clang's existing error messages suffice for aDelayFunc.)
59 for (size_t i = 0; i < maxAttempts; ++i) {
60 aDelayFunc(delayMs);
61 if (const auto opt = aOperation()) {
62 return opt;
65 return std::nullopt;
69 #if defined(MOZ_MEMORY) && defined(XP_WIN)
70 MOZ_JEMALLOC_API StallSpecs GetAllocatorStallSpecs();
71 #endif
73 } // namespace mozilla
75 #endif // mozjemalloc_utils_h