summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Schürmann <daniel@schuermann.dev>2022-08-22 14:37:59 +0200
committerMarge Bot <emma+marge@anholt.net>2022-09-28 09:25:20 +0000
commitb39d2168a70ec589c60b4315079b06d123b42484 (patch)
tree48b22b02df8c1d825447cd1a47d6b23726bbda2a
parenta128d444cbf4f74b0bdd4a8ae3f1cd2a52dee122 (diff)
downloadmesa-b39d2168a70ec589c60b4315079b06d123b42484.tar.gz
aco: implement allocator_traits for monotonic_allocator<T>
For easier usage, this patch also adds aliases for std::map and std::unordered_map using this allocator. Reviewed-by: Timur Kristóf <timur.kristof@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18112>
-rw-r--r--src/amd/compiler/aco_util.h83
1 files changed, 82 insertions, 1 deletions
diff --git a/src/amd/compiler/aco_util.h b/src/amd/compiler/aco_util.h
index 676879fffdd..a046e5c123d 100644
--- a/src/amd/compiler/aco_util.h
+++ b/src/amd/compiler/aco_util.h
@@ -31,7 +31,10 @@
#include <cassert>
#include <cstddef>
+#include <functional>
#include <iterator>
+#include <map>
+#include <unordered_map>
#include <vector>
namespace aco {
@@ -423,7 +426,7 @@ public:
free(buffer);
}
- /* delete copy-constructor and -assigment to avoid double free() */
+ /* Delete copy-constructor and -assigment to avoid double free() */
monotonic_buffer_resource(const monotonic_buffer_resource&) = delete;
monotonic_buffer_resource& operator=(const monotonic_buffer_resource&) = delete;
@@ -476,6 +479,84 @@ private:
static_assert(minimum_size > sizeof(Buffer));
};
+/*
+ * Small memory allocator which wraps monotonic_buffer_resource
+ * in order to implement <allocator_traits>.
+ *
+ * This class mimics std::pmr::polymorphic_allocator with monotonic_buffer_resource
+ * as memory resource. The advantage of this specialization is the absence of
+ * virtual function calls and the propagation on swap, copy- and move assignment.
+ */
+template <typename T> class monotonic_allocator final {
+public:
+ monotonic_allocator() = delete;
+ monotonic_allocator(monotonic_buffer_resource& m) : memory_resource(m) {}
+ template <typename U>
+ explicit monotonic_allocator(const monotonic_allocator<U>& rhs)
+ : memory_resource(rhs.memory_resource)
+ {}
+
+ /* Memory Allocation */
+ T* allocate(size_t size)
+ {
+ uint32_t bytes = sizeof(T) * size;
+ return (T*)memory_resource.get().allocate(bytes, alignof(T));
+ }
+
+ /* Memory will be freed on destruction of memory_resource */
+ void deallocate(T* ptr, size_t size) {}
+
+ /* Implement <allocator_traits> */
+ using value_type = T;
+ template <class U> struct rebind {
+ using other = monotonic_allocator<U>;
+ };
+
+ typedef std::true_type propagate_on_container_copy_assignment;
+ typedef std::true_type propagate_on_container_move_assignment;
+ typedef std::true_type propagate_on_container_swap;
+
+ template <typename> friend class monotonic_allocator;
+ template <typename X, typename Y>
+ friend bool operator==(monotonic_allocator<X> const& a, monotonic_allocator<Y> const& b);
+ template <typename X, typename Y>
+ friend bool operator!=(monotonic_allocator<X> const& a, monotonic_allocator<Y> const& b);
+
+private:
+ std::reference_wrapper<monotonic_buffer_resource> memory_resource;
+};
+
+/* Necessary for <allocator_traits>. */
+template <typename X, typename Y>
+inline bool
+operator==(monotonic_allocator<X> const& a, monotonic_allocator<Y> const& b)
+{
+ return a.memory_resource.get() == b.memory_resource.get();
+}
+template <typename X, typename Y>
+inline bool
+operator!=(monotonic_allocator<X> const& a, monotonic_allocator<Y> const& b)
+{
+ return !(a == b);
+}
+
+/*
+ * aco::map - alias for std::map with monotonic_allocator
+ *
+ * This template specialization mimics std::pmr::map.
+ */
+template <class Key, class T, class Compare = std::less<Key>>
+using map = std::map<Key, T, Compare, aco::monotonic_allocator<std::pair<const Key, T>>>;
+
+/*
+ * aco::unordered_map - alias for std::unordered_map with monotonic_allocator
+ *
+ * This template specialization mimics std::pmr::unordered_map.
+ */
+template <class Key, class T, class Hash = std::hash<Key>, class Pred = std::equal_to<Key>>
+using unordered_map =
+ std::unordered_map<Key, T, Hash, Pred, aco::monotonic_allocator<std::pair<const Key, T>>>;
+
} // namespace aco
#endif // ACO_UTIL_H