ProfileBufferIndex.h (4136B)
1 /* -*- Mode: C++; tab-width: 2; 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/. */ 6 7 #ifndef ProfileBufferIndex_h 8 #define ProfileBufferIndex_h 9 10 #include "mozilla/Attributes.h" 11 12 #include <cstddef> 13 #include <cstdint> 14 15 namespace mozilla { 16 17 // Generic index into a Profiler buffer, mostly for internal usage. 18 // Intended to appear infinite (it should effectively never wrap). 19 // 0 (zero) is reserved as nullptr-like value; it may indicate failure result, 20 // or it may point at the earliest available block. 21 using ProfileBufferIndex = uint64_t; 22 23 // Externally-opaque class encapsulating a block index, i.e. a 24 // ProfileBufferIndex that is guaranteed to point at the start of a Profile 25 // buffer block (until it is destroyed, but then that index cannot be reused and 26 // functions should gracefully handle expired blocks). 27 // Users may get these from Profile buffer functions, to later access previous 28 // blocks; they should avoid converting and operating on their value. 29 class ProfileBufferBlockIndex { 30 public: 31 // Default constructor with internal 0 value, for which Profile buffers must 32 // guarantee that it is before any valid entries; All public APIs should 33 // fail gracefully, doing and/or returning Nothing. 34 ProfileBufferBlockIndex() : mBlockIndex(0) {} 35 36 // Implicit conversion from literal `nullptr` to internal 0 value, to allow 37 // convenient init/reset/comparison with 0 index. 38 MOZ_IMPLICIT ProfileBufferBlockIndex(std::nullptr_t) : mBlockIndex(0) {} 39 40 // Explicit conversion to bool, works in `if` and other tests. 41 // Only returns false for default `ProfileBufferBlockIndex{}` value. 42 explicit operator bool() const { return mBlockIndex != 0; } 43 44 // Comparison operators. Default `ProfileBufferBlockIndex{}` value is always 45 // the lowest. 46 [[nodiscard]] bool operator==(const ProfileBufferBlockIndex& aRhs) const { 47 return mBlockIndex == aRhs.mBlockIndex; 48 } 49 [[nodiscard]] bool operator!=(const ProfileBufferBlockIndex& aRhs) const { 50 return mBlockIndex != aRhs.mBlockIndex; 51 } 52 [[nodiscard]] bool operator<(const ProfileBufferBlockIndex& aRhs) const { 53 return mBlockIndex < aRhs.mBlockIndex; 54 } 55 [[nodiscard]] bool operator<=(const ProfileBufferBlockIndex& aRhs) const { 56 return mBlockIndex <= aRhs.mBlockIndex; 57 } 58 [[nodiscard]] bool operator>(const ProfileBufferBlockIndex& aRhs) const { 59 return mBlockIndex > aRhs.mBlockIndex; 60 } 61 [[nodiscard]] bool operator>=(const ProfileBufferBlockIndex& aRhs) const { 62 return mBlockIndex >= aRhs.mBlockIndex; 63 } 64 65 // Explicit conversion to ProfileBufferIndex, mostly used by internal Profile 66 // buffer code. 67 [[nodiscard]] ProfileBufferIndex ConvertToProfileBufferIndex() const { 68 return mBlockIndex; 69 } 70 71 // Explicit creation from ProfileBufferIndex, mostly used by internal 72 // Profile buffer code. 73 [[nodiscard]] static ProfileBufferBlockIndex CreateFromProfileBufferIndex( 74 ProfileBufferIndex aIndex) { 75 return ProfileBufferBlockIndex(aIndex); 76 } 77 78 private: 79 // Private to prevent easy construction from any value. Use 80 // `CreateFromProfileBufferIndex()` instead. 81 // The main reason for this indirection is to make it harder to create these 82 // objects, because only the profiler code should need to do it. Ideally, this 83 // class should be used wherever a block index should be stored, but there is 84 // so much code that uses `uint64_t` that it would be a big task to change 85 // them all. So for now we allow conversions to/from numbers, but it's as ugly 86 // as possible to make sure it doesn't get too common; and if one day we want 87 // to tackle a global change, it should be easy to find all these locations 88 // thanks to the explicit conversion functions. 89 explicit ProfileBufferBlockIndex(ProfileBufferIndex aBlockIndex) 90 : mBlockIndex(aBlockIndex) {} 91 92 ProfileBufferIndex mBlockIndex; 93 }; 94 95 } // namespace mozilla 96 97 #endif // ProfileBufferIndex_h