sat_counter.hh revision 13962
113960Sodanrc@yahoo.com.br/* 213960Sodanrc@yahoo.com.br * Copyright (c) 2019 Inria 313960Sodanrc@yahoo.com.br * All rights reserved. 413960Sodanrc@yahoo.com.br * 513960Sodanrc@yahoo.com.br * The license below extends only to copyright in the software and shall 613960Sodanrc@yahoo.com.br * not be construed as granting a license to any other intellectual 713960Sodanrc@yahoo.com.br * property including but not limited to intellectual property relating 813960Sodanrc@yahoo.com.br * to a hardware implementation of the functionality of the software 913960Sodanrc@yahoo.com.br * licensed hereunder. You may use the software subject to the license 1013960Sodanrc@yahoo.com.br * terms below provided that you ensure that this notice is replicated 1113960Sodanrc@yahoo.com.br * unmodified and in its entirety in all distributions of the software, 1213960Sodanrc@yahoo.com.br * modified or unmodified, in source code or in binary form. 1313960Sodanrc@yahoo.com.br * 1413960Sodanrc@yahoo.com.br * Copyright (c) 2005-2006 The Regents of The University of Michigan 1513960Sodanrc@yahoo.com.br * All rights reserved. 1613960Sodanrc@yahoo.com.br * 1713960Sodanrc@yahoo.com.br * Redistribution and use in source and binary forms, with or without 1813960Sodanrc@yahoo.com.br * modification, are permitted provided that the following conditions are 1913960Sodanrc@yahoo.com.br * met: redistributions of source code must retain the above copyright 2013960Sodanrc@yahoo.com.br * notice, this list of conditions and the following disclaimer; 2113960Sodanrc@yahoo.com.br * redistributions in binary form must reproduce the above copyright 2213960Sodanrc@yahoo.com.br * notice, this list of conditions and the following disclaimer in the 2313960Sodanrc@yahoo.com.br * documentation and/or other materials provided with the distribution; 2413960Sodanrc@yahoo.com.br * neither the name of the copyright holders nor the names of its 2513960Sodanrc@yahoo.com.br * contributors may be used to endorse or promote products derived from 2613960Sodanrc@yahoo.com.br * this software without specific prior written permission. 2713960Sodanrc@yahoo.com.br * 2813960Sodanrc@yahoo.com.br * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2913960Sodanrc@yahoo.com.br * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3013960Sodanrc@yahoo.com.br * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3113960Sodanrc@yahoo.com.br * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3213960Sodanrc@yahoo.com.br * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3313960Sodanrc@yahoo.com.br * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3413960Sodanrc@yahoo.com.br * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3513960Sodanrc@yahoo.com.br * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3613960Sodanrc@yahoo.com.br * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3713960Sodanrc@yahoo.com.br * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3813960Sodanrc@yahoo.com.br * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3913960Sodanrc@yahoo.com.br * 4013960Sodanrc@yahoo.com.br * Authors: Kevin Lim 4113960Sodanrc@yahoo.com.br * Daniel Carvalho 4213960Sodanrc@yahoo.com.br */ 4313960Sodanrc@yahoo.com.br 4413960Sodanrc@yahoo.com.br#ifndef __BASE_SAT_COUNTER_HH__ 4513960Sodanrc@yahoo.com.br#define __BASE_SAT_COUNTER_HH__ 4613960Sodanrc@yahoo.com.br 4713960Sodanrc@yahoo.com.br#include <cstdint> 4813960Sodanrc@yahoo.com.br 4913960Sodanrc@yahoo.com.br#include "base/logging.hh" 5013960Sodanrc@yahoo.com.br#include "base/types.hh" 5113960Sodanrc@yahoo.com.br 5213960Sodanrc@yahoo.com.br/** 5313960Sodanrc@yahoo.com.br * Implements an n bit saturating counter and provides methods to 5413960Sodanrc@yahoo.com.br * increment, decrement, and read it. 5513960Sodanrc@yahoo.com.br */ 5613960Sodanrc@yahoo.com.brclass SatCounter 5713960Sodanrc@yahoo.com.br{ 5813960Sodanrc@yahoo.com.br public: 5913962Sodanrc@yahoo.com.br /** The default constructor should never be used. */ 6013962Sodanrc@yahoo.com.br SatCounter() = delete; 6113962Sodanrc@yahoo.com.br 6213960Sodanrc@yahoo.com.br /** 6313960Sodanrc@yahoo.com.br * Constructor for the counter. The explicit keyword is used to make 6413960Sodanrc@yahoo.com.br * sure the user does not assign a number to the counter thinking it 6513960Sodanrc@yahoo.com.br * will be used as a counter value when it is in fact used as the number 6613960Sodanrc@yahoo.com.br * of bits. 6713960Sodanrc@yahoo.com.br * 6813960Sodanrc@yahoo.com.br * @param bits How many bits the counter will have. 6913960Sodanrc@yahoo.com.br * @param initial_val Starting value for the counter. 7013960Sodanrc@yahoo.com.br */ 7113960Sodanrc@yahoo.com.br explicit SatCounter(unsigned bits, uint8_t initial_val = 0) 7213960Sodanrc@yahoo.com.br : initialVal(initial_val), maxVal((1 << bits) - 1), 7313960Sodanrc@yahoo.com.br counter(initial_val) 7413960Sodanrc@yahoo.com.br { 7513960Sodanrc@yahoo.com.br fatal_if(bits > 8*sizeof(uint8_t), 7613960Sodanrc@yahoo.com.br "Number of bits exceeds counter size"); 7713960Sodanrc@yahoo.com.br fatal_if(initial_val > maxVal, 7813960Sodanrc@yahoo.com.br "Saturating counter's Initial value exceeds max value."); 7913960Sodanrc@yahoo.com.br } 8013960Sodanrc@yahoo.com.br 8113962Sodanrc@yahoo.com.br /** Copy constructor. */ 8213962Sodanrc@yahoo.com.br SatCounter(const SatCounter& other) 8313962Sodanrc@yahoo.com.br : initialVal(other.initialVal), maxVal(other.maxVal), 8413962Sodanrc@yahoo.com.br counter(other.counter) 8513962Sodanrc@yahoo.com.br { 8613962Sodanrc@yahoo.com.br } 8713962Sodanrc@yahoo.com.br 8813962Sodanrc@yahoo.com.br /** Copy assignment. */ 8913962Sodanrc@yahoo.com.br SatCounter& operator=(const SatCounter& other) { 9013962Sodanrc@yahoo.com.br if (this != &other) { 9113962Sodanrc@yahoo.com.br SatCounter temp(other); 9213962Sodanrc@yahoo.com.br this->swap(temp); 9313962Sodanrc@yahoo.com.br } 9413962Sodanrc@yahoo.com.br return *this; 9513962Sodanrc@yahoo.com.br } 9613962Sodanrc@yahoo.com.br 9713962Sodanrc@yahoo.com.br /** Move constructor. */ 9813962Sodanrc@yahoo.com.br SatCounter(SatCounter&& other) 9913962Sodanrc@yahoo.com.br { 10013962Sodanrc@yahoo.com.br initialVal = other.initialVal; 10113962Sodanrc@yahoo.com.br maxVal = other.maxVal; 10213962Sodanrc@yahoo.com.br counter = other.counter; 10313962Sodanrc@yahoo.com.br SatCounter temp(0); 10413962Sodanrc@yahoo.com.br other.swap(temp); 10513962Sodanrc@yahoo.com.br } 10613962Sodanrc@yahoo.com.br 10713962Sodanrc@yahoo.com.br /** Move assignment. */ 10813962Sodanrc@yahoo.com.br SatCounter& operator=(SatCounter&& other) { 10913962Sodanrc@yahoo.com.br if (this != &other) { 11013962Sodanrc@yahoo.com.br initialVal = other.initialVal; 11113962Sodanrc@yahoo.com.br maxVal = other.maxVal; 11213962Sodanrc@yahoo.com.br counter = other.counter; 11313962Sodanrc@yahoo.com.br SatCounter temp(0); 11413962Sodanrc@yahoo.com.br other.swap(temp); 11513962Sodanrc@yahoo.com.br } 11613962Sodanrc@yahoo.com.br return *this; 11713962Sodanrc@yahoo.com.br } 11813962Sodanrc@yahoo.com.br 11913962Sodanrc@yahoo.com.br /** 12013962Sodanrc@yahoo.com.br * Swap the contents of every member of the class. Used for the default 12113962Sodanrc@yahoo.com.br * copy-assignment created by the compiler. 12213962Sodanrc@yahoo.com.br * 12313962Sodanrc@yahoo.com.br * @param other The other object to swap contents with. 12413962Sodanrc@yahoo.com.br */ 12513962Sodanrc@yahoo.com.br void 12613962Sodanrc@yahoo.com.br swap(SatCounter& other) 12713962Sodanrc@yahoo.com.br { 12813962Sodanrc@yahoo.com.br std::swap(initialVal, other.initialVal); 12913962Sodanrc@yahoo.com.br std::swap(maxVal, other.maxVal); 13013962Sodanrc@yahoo.com.br std::swap(counter, other.counter); 13113962Sodanrc@yahoo.com.br } 13213962Sodanrc@yahoo.com.br 13313960Sodanrc@yahoo.com.br /** Pre-increment operator. */ 13413960Sodanrc@yahoo.com.br SatCounter& 13513960Sodanrc@yahoo.com.br operator++() 13613960Sodanrc@yahoo.com.br { 13713960Sodanrc@yahoo.com.br if (counter < maxVal) { 13813960Sodanrc@yahoo.com.br ++counter; 13913960Sodanrc@yahoo.com.br } 14013960Sodanrc@yahoo.com.br return *this; 14113960Sodanrc@yahoo.com.br } 14213960Sodanrc@yahoo.com.br 14313960Sodanrc@yahoo.com.br /** Post-increment operator. */ 14413960Sodanrc@yahoo.com.br SatCounter 14513960Sodanrc@yahoo.com.br operator++(int) 14613960Sodanrc@yahoo.com.br { 14713960Sodanrc@yahoo.com.br SatCounter old_counter = *this; 14813960Sodanrc@yahoo.com.br ++*this; 14913960Sodanrc@yahoo.com.br return old_counter; 15013960Sodanrc@yahoo.com.br } 15113960Sodanrc@yahoo.com.br 15213960Sodanrc@yahoo.com.br /** Pre-decrement operator. */ 15313960Sodanrc@yahoo.com.br SatCounter& 15413960Sodanrc@yahoo.com.br operator--() 15513960Sodanrc@yahoo.com.br { 15613960Sodanrc@yahoo.com.br if (counter > 0) { 15713960Sodanrc@yahoo.com.br --counter; 15813960Sodanrc@yahoo.com.br } 15913960Sodanrc@yahoo.com.br return *this; 16013960Sodanrc@yahoo.com.br } 16113960Sodanrc@yahoo.com.br 16213960Sodanrc@yahoo.com.br /** Post-decrement operator. */ 16313960Sodanrc@yahoo.com.br SatCounter 16413960Sodanrc@yahoo.com.br operator--(int) 16513960Sodanrc@yahoo.com.br { 16613960Sodanrc@yahoo.com.br SatCounter old_counter = *this; 16713960Sodanrc@yahoo.com.br --*this; 16813960Sodanrc@yahoo.com.br return old_counter; 16913960Sodanrc@yahoo.com.br } 17013960Sodanrc@yahoo.com.br 17113962Sodanrc@yahoo.com.br /** Shift-right-assignment. */ 17213962Sodanrc@yahoo.com.br SatCounter& 17313962Sodanrc@yahoo.com.br operator>>=(const int& shift) 17413962Sodanrc@yahoo.com.br { 17513962Sodanrc@yahoo.com.br this->counter >>= shift; 17613962Sodanrc@yahoo.com.br return *this; 17713962Sodanrc@yahoo.com.br } 17813962Sodanrc@yahoo.com.br 17913962Sodanrc@yahoo.com.br /** Shift-left-assignment. */ 18013962Sodanrc@yahoo.com.br SatCounter& 18113962Sodanrc@yahoo.com.br operator<<=(const int& shift) 18213962Sodanrc@yahoo.com.br { 18313962Sodanrc@yahoo.com.br this->counter <<= shift; 18413962Sodanrc@yahoo.com.br if (this->counter > maxVal) { 18513962Sodanrc@yahoo.com.br this->counter = maxVal; 18613962Sodanrc@yahoo.com.br } 18713962Sodanrc@yahoo.com.br return *this; 18813962Sodanrc@yahoo.com.br } 18913962Sodanrc@yahoo.com.br 19013962Sodanrc@yahoo.com.br /** Add-assignment. */ 19113962Sodanrc@yahoo.com.br SatCounter& 19213962Sodanrc@yahoo.com.br operator+=(const int& value) 19313962Sodanrc@yahoo.com.br { 19413962Sodanrc@yahoo.com.br if (maxVal - this->counter >= value) { 19513962Sodanrc@yahoo.com.br this->counter += value; 19613962Sodanrc@yahoo.com.br } else { 19713962Sodanrc@yahoo.com.br this->counter = maxVal; 19813962Sodanrc@yahoo.com.br } 19913962Sodanrc@yahoo.com.br return *this; 20013962Sodanrc@yahoo.com.br } 20113962Sodanrc@yahoo.com.br 20213962Sodanrc@yahoo.com.br /** Subtract-assignment. */ 20313962Sodanrc@yahoo.com.br SatCounter& 20413962Sodanrc@yahoo.com.br operator-=(const int& value) 20513962Sodanrc@yahoo.com.br { 20613962Sodanrc@yahoo.com.br if (this->counter > value) { 20713962Sodanrc@yahoo.com.br this->counter -= value; 20813962Sodanrc@yahoo.com.br } else { 20913962Sodanrc@yahoo.com.br this->counter = 0; 21013962Sodanrc@yahoo.com.br } 21113962Sodanrc@yahoo.com.br return *this; 21213962Sodanrc@yahoo.com.br } 21313962Sodanrc@yahoo.com.br 21413960Sodanrc@yahoo.com.br /** 21513960Sodanrc@yahoo.com.br * Read the counter's value. 21613960Sodanrc@yahoo.com.br */ 21713960Sodanrc@yahoo.com.br operator uint8_t() const { return counter; } 21813960Sodanrc@yahoo.com.br 21913960Sodanrc@yahoo.com.br /** Reset the counter to its initial value. */ 22013960Sodanrc@yahoo.com.br void reset() { counter = initialVal; } 22113960Sodanrc@yahoo.com.br 22213962Sodanrc@yahoo.com.br /** 22313962Sodanrc@yahoo.com.br * Calculate saturation percentile of the current counter's value 22413962Sodanrc@yahoo.com.br * with regard to its maximum possible value. 22513962Sodanrc@yahoo.com.br * 22613962Sodanrc@yahoo.com.br * @return A value between 0.0 and 1.0 to indicate which percentile of 22713962Sodanrc@yahoo.com.br * the maximum value the current value is. 22813962Sodanrc@yahoo.com.br */ 22913962Sodanrc@yahoo.com.br double calcSaturation() const { return (double) counter / maxVal; } 23013962Sodanrc@yahoo.com.br 23113962Sodanrc@yahoo.com.br /** 23213962Sodanrc@yahoo.com.br * Whether the counter has achieved its maximum value or not. 23313962Sodanrc@yahoo.com.br * 23413962Sodanrc@yahoo.com.br * @return True if the counter saturated. 23513962Sodanrc@yahoo.com.br */ 23613962Sodanrc@yahoo.com.br bool isSaturated() const { return counter == maxVal; } 23713962Sodanrc@yahoo.com.br 23813960Sodanrc@yahoo.com.br private: 23913960Sodanrc@yahoo.com.br uint8_t initialVal; 24013960Sodanrc@yahoo.com.br uint8_t maxVal; 24113960Sodanrc@yahoo.com.br uint8_t counter; 24213960Sodanrc@yahoo.com.br}; 24313960Sodanrc@yahoo.com.br 24413960Sodanrc@yahoo.com.br#endif // __BASE_SAT_COUNTER_HH__ 245