Daniel Carvalho has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/17996
Change subject: base: Add Shift, Constructors and assignments to SatCounter
......................................................................
base: Add Shift, Constructors and assignments to SatCounter
Add shift-assignment operators, copy and move constructor
and assignments to SatCounter, so that it they can be used
by the prefetchers.
Change-Id: I61d0cb28c8375b9d2774a39011e4a0aa6fe9ccb7
Signed-off-by: Daniel <[email protected]>
---
M src/base/sat_counter.hh
M src/base/sat_counter.test.cc
2 files changed, 162 insertions(+), 0 deletions(-)
diff --git a/src/base/sat_counter.hh b/src/base/sat_counter.hh
index 342a338..c20e3f4 100644
--- a/src/base/sat_counter.hh
+++ b/src/base/sat_counter.hh
@@ -75,6 +75,58 @@
"Saturating counter's Initial value exceeds max value.");
}
+ /** Copy constructor. */
+ SatCounter(const SatCounter& other)
+ : initialVal(other.initialVal), maxVal(other.maxVal),
+ counter(other.counter)
+ {
+ }
+
+ /** Copy assignment. */
+ SatCounter& operator=(const SatCounter& other) {
+ if (this != &other) {
+ SatCounter temp(other);
+ this->swap(temp);
+ }
+ return *this;
+ }
+
+ /** Move constructor. */
+ SatCounter(SatCounter&& other)
+ {
+ initialVal = other.initialVal;
+ maxVal = other.maxVal;
+ counter = other.counter;
+ SatCounter temp(0);
+ other.swap(temp);
+ }
+
+ /** Move assignment. */
+ SatCounter& operator=(SatCounter&& other) {
+ if (this != &other) {
+ initialVal = other.initialVal;
+ maxVal = other.maxVal;
+ counter = other.counter;
+ SatCounter temp(0);
+ other.swap(temp);
+ }
+ return *this;
+ }
+
+ /**
+ * Swap the contents of every member of the class. Used for the default
+ * copy-assignment created by the compiler.
+ *
+ * @param other The other object to swap contents with.
+ */
+ void
+ swap(SatCounter& other)
+ {
+ std::swap(initialVal, other.initialVal);
+ std::swap(maxVal, other.maxVal);
+ std::swap(counter, other.counter);
+ }
+
/** Pre-increment operator. */
SatCounter&
operator++()
@@ -113,6 +165,25 @@
return old_counter;
}
+ /** Shift-right-assignment. */
+ SatCounter&
+ operator>>=(const int& shift)
+ {
+ this->counter >>= shift;
+ return *this;
+ }
+
+ /** Shift-left-assignment. */
+ SatCounter&
+ operator<<=(const int& shift)
+ {
+ this->counter <<= shift;
+ if (this->counter > maxVal) {
+ this->counter = maxVal;
+ }
+ return *this;
+ }
+
/**
* Read the counter's value.
*/
@@ -125,6 +196,12 @@
uint8_t initialVal;
uint8_t maxVal;
uint8_t counter;
+
+ /** The default constructor should not be used. */
+ SatCounter()
+ : SatCounter(0)
+ {
+ }
};
#endif // __BASE_SAT_COUNTER_HH__
diff --git a/src/base/sat_counter.test.cc b/src/base/sat_counter.test.cc
index efc79e0..472add7 100644
--- a/src/base/sat_counter.test.cc
+++ b/src/base/sat_counter.test.cc
@@ -30,6 +30,8 @@
#include <gtest/gtest.h>
+#include <utility>
+
#include "base/sat_counter.hh"
/**
@@ -102,6 +104,34 @@
}
/**
+ * Test shift operators.
+ */
+TEST(SatCounterTest, Shift)
+{
+ const unsigned bits = 3;
+ const unsigned max_value = (1 << bits) - 1;
+ const unsigned initial_value = 1;
+ SatCounter counter(bits, initial_value);
+ int value = initial_value;
+
+ // Test random shifts
+ counter <<= 2;
+ value <<= 2;
+ ASSERT_EQ(counter, value);
+ counter >>= 1;
+ value >>= 1;
+ ASSERT_EQ(counter, value);
+
+ // Test saturation
+ counter <<= bits;
+ ASSERT_EQ(counter, max_value);
+
+ // Test zeroing
+ counter >>= bits;
+ ASSERT_EQ(counter, 0);
+}
+
+/**
* Test both pre and post operators.
*/
TEST(SatCounterTest, PrePostOperators)
@@ -129,3 +159,58 @@
ASSERT_EQ(counter_pre, 0);
ASSERT_EQ(counter_post, 0);
}
+
+/**
+ * Test copy and move for both constructor and assignment.
+ */
+TEST(SatCounterTest, CopyMove)
+{
+ const unsigned bits = 3;
+ const unsigned max_value = (1 << bits) - 1;
+ const unsigned initial_value = 1;
+ SatCounter counter(bits, initial_value);
+ SatCounter deep_copy(1);
+ SatCounter counter_copy(2);
+
+ // Increase counter value so that we can check if the inner counter is
+ // being copied
+ counter++;
+
+ // Copy counter using both the copy constructor and the copy assignment
+ SatCounter counter_copy_constructor(counter);
+ deep_copy = counter_copy = counter;
+ ASSERT_EQ(counter_copy_constructor, initial_value + 1);
+ ASSERT_EQ(counter_copy, initial_value + 1);
+ ASSERT_EQ(deep_copy, initial_value + 1);
+
+ // Make sure max value is the same for all of them, and that modifying
+ // the copies does not modify the original
+ for (int i = 0; i < 2*max_value; i++) {
+ counter_copy_constructor++;
+ counter_copy++;
+ deep_copy++;
+ }
+ ASSERT_EQ(counter, initial_value + 1);
+ ASSERT_EQ(counter_copy_constructor, max_value);
+ ASSERT_EQ(counter_copy, max_value);
+ ASSERT_EQ(deep_copy, max_value);
+
+ // Make sure initial value is the same for all of them
+ counter_copy_constructor.reset();
+ counter_copy.reset();
+ deep_copy.reset();
+ ASSERT_EQ(counter_copy_constructor, initial_value);
+ ASSERT_EQ(counter_copy, initial_value);
+ ASSERT_EQ(deep_copy, initial_value);
+
+ // Now check move
+ SatCounter counter_move_constructor(std::move(counter));
+ ASSERT_EQ(counter, 0);
+ ASSERT_EQ(counter_move_constructor, initial_value + 1);
+
+ SatCounter counter_move(bits);
+ counter_move = std::move(counter_move_constructor);
+ ASSERT_EQ(counter_move_constructor, 0);
+ ASSERT_EQ(counter_move, initial_value + 1);
+}
+
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/17996
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: I61d0cb28c8375b9d2774a39011e4a0aa6fe9ccb7
Gerrit-Change-Number: 17996
Gerrit-PatchSet: 1
Gerrit-Owner: Daniel Carvalho <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev