Line data Source code
1 : #pragma once 2 : 3 : #include "MemoryResource.h" 4 : #include <mutex> 5 : 6 : namespace elsa::mr 7 : { 8 : /// @brief Trivially synchs all allocations and deallocations to the wrapped resource with a 9 : /// single lock. Use this wherever PoolResource, CacheResource, RegionResource etc. are used 10 : /// in a multi-threaded context. 11 : template <typename T> 12 : class SyncResource : public T 13 : { 14 : private: 15 : std::mutex _m; 16 : 17 : protected: 18 : template <typename... Ts> 19 : SyncResource(Ts&&... args); 20 : 21 : public: 22 : /// @brief Creates a SyncResource wrapping a back-end resource, which performs the actual 23 : /// allocations. 24 : /// @param ...args Parameters passed to the constructor of the wrapped resource. 25 : /// @return A MemoryResource encapsulationg the SynchedResource 26 : template <typename... Ts> 27 : static MemoryResource make(Ts&&... args); 28 : 29 : /// @brief Allocates from the wrapped resource. Blocking until the resource is not busy. 30 : void* allocate(size_t size, size_t alignment) override; 31 : /// @brief Passes the pointer along to the wrapped resource for deallocation. Blocking until 32 : /// the resource is not busy. 33 : void deallocate(void* ptr, size_t size, size_t alignment) noexcept override; 34 : /// @brief Tries to have the wrapped resource resize the allocation. Blocking until the 35 : /// resource is not busy. 36 : bool tryResize(void* ptr, size_t size, size_t alignment, size_t newSize) noexcept override; 37 : }; 38 : 39 : template <typename T> 40 : inline void* SyncResource<T>::allocate(size_t size, size_t alignment) 41 10117 : { 42 10117 : std::unique_lock lock{_m}; 43 10117 : return T::allocate(size, alignment); 44 10117 : } 45 : 46 : template <typename T> 47 : inline void SyncResource<T>::deallocate(void* ptr, size_t size, size_t alignment) noexcept 48 10114 : { 49 10114 : std::unique_lock lock{_m}; 50 10114 : return T::deallocate(ptr, size, alignment); 51 10114 : } 52 : 53 : template <typename T> 54 : inline bool SyncResource<T>::tryResize(void* ptr, size_t size, size_t alignment, 55 : size_t newSize) noexcept 56 0 : { 57 0 : std::unique_lock lock{_m}; 58 0 : return T::tryResize(ptr, size, alignment, newSize); 59 0 : } 60 : 61 : template <typename T> 62 : template <typename... Ts> 63 : inline SyncResource<T>::SyncResource(Ts&&... args) : T{std::forward<Ts>(args)...} 64 6 : { 65 6 : } 66 : 67 : template <typename T> 68 : template <typename... Ts> 69 : inline MemoryResource SyncResource<T>::make(Ts&&... args) 70 6 : { 71 6 : return std::shared_ptr<MemResInterface>(new SyncResource<T>(std::forward<Ts>(args)...), 72 6 : [](SyncResource<T>* p) { delete p; }); 73 6 : } 74 : } // namespace elsa::mr