base: Fix CircularQueue when diffing iterators

This patch is fixing CircularQueue iterators' subtraction, in particular
the behaviour when head and tail round multiple times.

Change-Id: Ie79ac8accd30a10cf039cf4def87675b01375d6b
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Gabor Dozsa <gabor.dozsa@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/17188
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
Giacomo Travaglini
2019-03-08 16:01:20 +00:00
parent 487ea069be
commit bbcbde7a92
2 changed files with 38 additions and 4 deletions

View File

@@ -106,10 +106,19 @@ class CircularQueue : private std::vector<T>
static uint32_t
moduloSub(uint32_t op1, uint32_t op2, uint32_t size)
{
int ret = (uint32_t)(op1 - op2) % size;
int32_t ret = sub(op1, op2, size);
return ret >= 0 ? ret : ret + size;
}
static int32_t
sub(uint32_t op1, uint32_t op2, uint32_t size)
{
if (op1 > op2)
return (op1 - op2) % size;
else
return -((op2 - op1) % size);
}
void increase(uint32_t& v, size_t delta = 1)
{
v = moduloAdd(v, delta, _capacity);
@@ -355,10 +364,10 @@ class CircularQueue : private std::vector<T>
difference_type operator-(const iterator& that)
{
/* If a is already at the end, we can safely return 0. */
auto ret = _cq->moduloSub(this->_idx, that._idx);
auto ret = _cq->sub(this->_idx, that._idx, _cq->capacity());
if (ret == 0 && this->_round != that._round) {
ret += this->_round * _cq->capacity();
if (this->_round != that._round) {
ret += ((this->_round - that._round) * _cq->capacity());
}
return ret;
}