Giacomo Gabrielli has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/13124
Change subject: base: Allocators definition
......................................................................
base: Allocators definition
Define a basic allocator. The whole point of the allocator is to be
able to have std::vector of objects that contain stats and construct
them passing parametres to the constructor.
This patch defines a basic allocator that receives a variable amount
of parametres, and when used to construct the target object, it passes
the parametres to the constructor.
The immediate goal of this patch is having the o3 LSQUnit constructor
have the sizes of the LQ and SQ as parametres, and be able to define
the threads in the o3 LSQ as a std::vector LSQUnit that is constructed
passing the appropriate value to the parametres.
Change-Id: Id57184707dedc6d54092f8a39fb82493c46dc804
Signed-off-by: Giacomo Gabrielli <[email protected]>
---
A src/base/allocators.hh
1 file changed, 201 insertions(+), 0 deletions(-)
diff --git a/src/base/allocators.hh b/src/base/allocators.hh
new file mode 100644
index 0000000..d057f2b
--- /dev/null
+++ b/src/base/allocators.hh
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2017 ARM Limited
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Rekai Gonzalez-Alberquilla
+ *
+ */
+
+#ifndef __BASE_ALLOCATORS_HH__
+#define __BASE_ALLOCATORS_HH__
+
+#include <memory>
+
+/** Allocator class with arguments.
+ * As the current implementation of the Stats does not allow to
copy-construct
+ * stats, objects with stats cannot be constructed. This imposes a
limitation
+ * to the use of stl containers to hold such objects. The way to work
around
+ * that is using a custom allocator that will construct each of the
allocated
+ * objects with the particulars parameters specified in the definition of
the
+ * allocator.
+ *
+ * E.g.: If we want to have an allocator for the LSQUnit that receives the
LQ
+ * and SQ sizes, so when building the O3 model LSQ, we can have the
LSQUnits
+ * be a std::vector<LSQUnit> instead of a LSQUnit*, we define:
+ * using LSQUnitAllocator = ArgAllocator<LSQUnit, uint32_t, uint32_t>
+ * std::vector<LSQUnit, LSQUnitAllocator> threads;
+ *
+ * And later, in the constructor we do:
+ * LSQ(LSQParams* params) :
+ * ..., threads(params->numThreads,
+ * LSQUnitAllocator(params->LQEntries,
params->SQEntries)),
+ * ...
+ * {}
+ *
+ * This way the LSQUnits are build in-place with the appropriate
parameters.
+ *
+ */
+template <typename T, typename ... Args>
+struct ArgAllocator;
+
+template <typename T>
+struct ArgAllocator<T> : std::allocator<T>
+{
+ /** Convenience alias to the parent class. */
+ using Base = std::allocator<T>;
+
+ /** Traits. */
+ /** @{ */
+ using value_type = T;
+ using pointer = T*;
+ using const_pointer = const T*;
+ /** @} */
+
+ /** Rebinding. */
+ template <typename U>
+ struct rebind { using other = ArgAllocator<U>; };
+
+ /** Use the default memory allocation/deallocation functions. */
+ /** @{ */
+ using Base::allocate;
+ using Base::deallocate;
+ /** @} */
+
+ /** Equality operator. */
+ bool operator==(const ArgAllocator& that) { return true; }
+
+ /** Inequality operator. */
+ bool operator!=(const ArgAllocator& that) { return false; }
+
+ /** Custom T constructor.
+ * Ignore whatever arguments we may get, and just call with the args
the
+ * allocator was constructed with. This is required because the stl
+ * implementation may be tempted to pass a T& in case we feel like
+ * copy-constructing.
+ */
+ template <typename ... Args>
+ void construct(T* p, Args&& ... aas) { helper(p); }
+
+ /** Utility function to pass the args to the constructor of T. */
+ template <typename ... Args>
+ void helper(T* p, Args ... args) { ::new ((void*)p) T(args...); }
+};
+
+template <typename T, typename A, typename ... As>
+struct ArgAllocator<T, A, As...> : ArgAllocator<T, As...>
+{
+ /** Convenience alias to the parent class. */
+ using Base = ArgAllocator<T, As...>;
+
+ /** Argument value. */
+ A _arg;
+
+ /** Traits. */
+ /** @{ */
+ using Base::value_type;
+ using Base::pointer;
+ using Base::const_pointer;
+ /** @} */
+
+ /** Rebinding. */
+ template <typename U>
+ struct rebind { using other = ArgAllocator<U, A, As...>; };
+
+ /** Use the base memory allocation/deallocation functions. */
+ /** @{ */
+ using Base::allocate;
+ using Base::deallocate;
+ /** @} */
+
+ /** Constructor.
+ * Store the first arg, and pass on the rest to the parent.
+ */
+ ArgAllocator(const typename A::value_type& arg,
+ const typename As::value_type ... args)
+ : Base(args...), _arg(arg) { }
+
+ /** Equality operator. */
+ bool operator==(const ArgAllocator& that) {
+ return _arg == that._arg && Base::operator==(that);
+ }
+
+ /** Inequality operator. */
+ bool operator!=(const ArgAllocator& that) {
+ return _arg != that._arg || Base::operator==(that);
+ }
+
+ /** Custom T constructor.
+ * Ignore whatever arguments we may get, and just call with the args
the
+ * allocator was constructed with. This is required because the stl
+ * implementation may be tempted to pass a T& in case we feel like
+ * copy-constructing.
+ */
+ template <typename ... Args>
+ void construct(T* p, Args&& ... aas) { helper(p); }
+
+ /** Utility function to pass the args to the constructor of T. */
+ template <typename ... Args>
+ void helper(T* p, Args ... args) {
+ Base::helper(p, args..., _arg.value());
+ }
+};
+
+/** To provide more generality, we use two wrappers for arguments:
FixedArg<T>
+ * and IndexedArg<T>. FixedArg<T> is constructed with a T value that will
be
+ * used in every call to the construct function. IndexedArg<T> is
constructed
+ * with an initial value. In each call to construct, the current value is
used
+ * and post-incremented, allowing the creation of objects with consecutive
ids.
+ */
+/** @{ */
+/** Fixed argument wrapper.
+ * This struct takes a fixed argument to be passed to each invocation of
the
+ * target type constructor performed by an ArgAllocator::construct
invocation
+ */
+template <typename T>
+struct FixedArg
+{
+ using value_type = T;
+ T _arg;
+ FixedArg(const T& arg) : _arg(arg) {}
+ T value() { return _arg; }
+};
+
+/** Fixed argument wrapper.
+ * This struct takes a an initial value for an argument to be passed to
each
+ * invocation of the target type constructor performed by an
+ * ArgAllocator::construct invocation, and that is incremented afterwards.
+ */
+template <typename T>
+struct IndexedArg
+{
+ using value_type = T;
+ T _arg;
+ IndexedArg(const T& arg) : _arg(arg) {}
+ T value() { return _arg++; }
+};
+/** @} */
+
+#endif /* __BASE_ALLOCATORS_HH__ */
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/13124
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: Id57184707dedc6d54092f8a39fb82493c46dc804
Gerrit-Change-Number: 13124
Gerrit-PatchSet: 1
Gerrit-Owner: Giacomo Gabrielli <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev