Avi Drissman | 8ba1bad | 2022-09-13 19:22:36 | [diff] [blame^] | 1 | // Copyright 2020 The Chromium Authors |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Leonid Baraz | ea0c6dc | 2021-11-02 20:38:05 | [diff] [blame] | 5 | #ifndef COMPONENTS_REPORTING_RESOURCES_RESOURCE_INTERFACE_H_ |
| 6 | #define COMPONENTS_REPORTING_RESOURCES_RESOURCE_INTERFACE_H_ |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 7 | |
| 8 | #include <cstdint> |
| 9 | |
Leonid Baraz | 960ea8f | 2022-05-17 01:01:06 | [diff] [blame] | 10 | #include "base/memory/ref_counted.h" |
| 11 | #include "base/memory/scoped_refptr.h" |
Anton Bikineev | 1156b5f | 2021-05-15 22:35:36 | [diff] [blame] | 12 | #include "third_party/abseil-cpp/absl/types/optional.h" |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 13 | |
| 14 | namespace reporting { |
| 15 | |
| 16 | // Interface to resources management by Storage module. |
| 17 | // Must be implemented by the caller base on the platform limitations. |
| 18 | // All APIs are non-blocking. |
Leonid Baraz | 960ea8f | 2022-05-17 01:01:06 | [diff] [blame] | 19 | class ResourceInterface : public base::RefCountedThreadSafe<ResourceInterface> { |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 20 | public: |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 21 | // Needs to be called before attempting to allocate specified size. |
| 22 | // Returns true if requested amount can be allocated. |
| 23 | // After that the caller can actually allocate it or must call |
| 24 | // |Discard| if decided not to allocate. |
Zach Trudo | f1bf7ce | 2020-12-22 21:46:15 | [diff] [blame] | 25 | virtual bool Reserve(uint64_t size) = 0; |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 26 | |
| 27 | // Reverts reservation. |
| 28 | // Must be called after the specified amount is released. |
Zach Trudo | f1bf7ce | 2020-12-22 21:46:15 | [diff] [blame] | 29 | virtual void Discard(uint64_t size) = 0; |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 30 | |
| 31 | // Returns total amount. |
Hong Xu | f8e3c130 | 2022-06-01 01:49:21 | [diff] [blame] | 32 | virtual uint64_t GetTotal() const = 0; |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 33 | |
| 34 | // Returns current used amount. |
Hong Xu | f8e3c130 | 2022-06-01 01:49:21 | [diff] [blame] | 35 | virtual uint64_t GetUsed() const = 0; |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 36 | |
| 37 | // Test only: Sets non-default usage limit. |
Zach Trudo | f1bf7ce | 2020-12-22 21:46:15 | [diff] [blame] | 38 | virtual void Test_SetTotal(uint64_t test_total) = 0; |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 39 | |
| 40 | protected: |
Leonid Baraz | 960ea8f | 2022-05-17 01:01:06 | [diff] [blame] | 41 | friend class base::RefCountedThreadSafe<ResourceInterface>; |
| 42 | |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 43 | ResourceInterface() = default; |
Leonid Baraz | 960ea8f | 2022-05-17 01:01:06 | [diff] [blame] | 44 | virtual ~ResourceInterface() = default; |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 45 | }; |
| 46 | |
| 47 | // Moveable RAII class used for scoped Reserve-Discard. |
| 48 | // |
| 49 | // Usage: |
| 50 | // { |
Leonid Baraz | 960ea8f | 2022-05-17 01:01:06 | [diff] [blame] | 51 | // ScopedReservation reservation(1024u, options.memory_resource()); |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 52 | // if (!reservation.reserved()) { |
| 53 | // // Allocation failed. |
| 54 | // return; |
| 55 | // } |
| 56 | // // Allocation succeeded. |
| 57 | // ... |
| 58 | // } // Automatically discarded. |
| 59 | // |
Leonid Baraz | a206429 | 2022-07-07 00:18:41 | [diff] [blame] | 60 | // Can be handed over to another owner by move-constructor or using HandOver |
| 61 | // method: |
| 62 | // { |
| 63 | // ScopedReservation summary; |
| 64 | // for (const uint64_t size : sizes) { |
| 65 | // ScopedReservation single_reservation(size, resource); |
| 66 | // ... |
| 67 | // summary.HandOver(single_reservation); |
| 68 | // } |
| 69 | // } |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 70 | class ScopedReservation { |
| 71 | public: |
Leonid Baraz | a206429 | 2022-07-07 00:18:41 | [diff] [blame] | 72 | // Zero-size reservation with no resource interface attached. |
| 73 | // reserved() returns false. |
| 74 | ScopedReservation() noexcept; |
| 75 | // Specified reservation, must have resource interface attached. |
Leonid Baraz | af0a319f | 2022-06-15 02:17:47 | [diff] [blame] | 76 | ScopedReservation( |
| 77 | uint64_t size, |
| 78 | scoped_refptr<ResourceInterface> resource_interface) noexcept; |
Leonid Baraz | b455392 | 2022-07-12 23:32:53 | [diff] [blame] | 79 | // New reservation on the same resource interface as |other_reservation|. |
| 80 | ScopedReservation(uint64_t size, |
| 81 | const ScopedReservation& other_reservation) noexcept; |
| 82 | // Move constructor. |
Leonid Baraz | af0a319f | 2022-06-15 02:17:47 | [diff] [blame] | 83 | ScopedReservation(ScopedReservation&& other) noexcept; |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 84 | ScopedReservation(const ScopedReservation& other) = delete; |
Leonid Baraz | af0a319f | 2022-06-15 02:17:47 | [diff] [blame] | 85 | ScopedReservation& operator=(ScopedReservation&& other) = delete; |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 86 | ScopedReservation& operator=(const ScopedReservation& other) = delete; |
| 87 | ~ScopedReservation(); |
| 88 | |
| 89 | bool reserved() const; |
Leonid Baraz | af0a319f | 2022-06-15 02:17:47 | [diff] [blame] | 90 | |
| 91 | // Reduces reservation to |new_size|. |
Santiago Castano Moreno | 150ba5f | 2021-11-12 21:34:52 | [diff] [blame] | 92 | bool Reduce(uint64_t new_size); |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 93 | |
Leonid Baraz | af0a319f | 2022-06-15 02:17:47 | [diff] [blame] | 94 | // Adds |other| to |this| without assigning or releasing any reservation. |
| 95 | // Used for seamless transition from one reservation to another (more generic |
| 96 | // than std::move). Resets |other| to non-reserved state upon return from this |
| 97 | // method. |
| 98 | void HandOver(ScopedReservation& other); |
| 99 | |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 100 | private: |
Leonid Baraz | a206429 | 2022-07-07 00:18:41 | [diff] [blame] | 101 | scoped_refptr<ResourceInterface> resource_interface_; |
Anton Bikineev | 1156b5f | 2021-05-15 22:35:36 | [diff] [blame] | 102 | absl::optional<uint64_t> size_; |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 103 | }; |
| 104 | |
Leonid Baraz | 3e8af4b | 2020-11-23 19:04:47 | [diff] [blame] | 105 | } // namespace reporting |
| 106 | |
Leonid Baraz | ea0c6dc | 2021-11-02 20:38:05 | [diff] [blame] | 107 | #endif // COMPONENTS_REPORTING_RESOURCES_RESOURCE_INTERFACE_H_ |