chunk_generator.hh revision 5731:453f320129a1
12686Sksewell@umich.edu/* 22100SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan 35254Sksewell@umich.edu * All rights reserved. 45254Sksewell@umich.edu * 55254Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without 65254Sksewell@umich.edu * modification, are permitted provided that the following conditions are 75254Sksewell@umich.edu * met: redistributions of source code must retain the above copyright 85254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer; 95254Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright 105254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the 115254Sksewell@umich.edu * documentation and/or other materials provided with the distribution; 125254Sksewell@umich.edu * neither the name of the copyright holders nor the names of its 135254Sksewell@umich.edu * contributors may be used to endorse or promote products derived from 145254Sksewell@umich.edu * this software without specific prior written permission. 155254Sksewell@umich.edu * 165254Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175254Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185254Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195254Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205254Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215254Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225254Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235254Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245254Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255254Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265254Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275254Sksewell@umich.edu * 285254Sksewell@umich.edu * Authors: Steve Reinhardt 295254Sksewell@umich.edu */ 305254Sksewell@umich.edu 315254Sksewell@umich.edu#ifndef __BASE__CHUNK_GENERATOR_HH__ 322706Sksewell@umich.edu#define __BASE__CHUNK_GENERATOR_HH__ 332022SN/A 342022SN/A/** 352043SN/A * @file 362024SN/A * Declaration and inline definition of ChunkGenerator object. 372024SN/A */ 382043SN/A 392686Sksewell@umich.edu#include <algorithm> 404661Sksewell@umich.edu#include "base/intmath.hh" 412022SN/A#include "arch/isa_traits.hh" // for Addr 422083SN/A 432686Sksewell@umich.edu/** 442101SN/A * This class takes an arbitrary memory region (address/length pair) 452043SN/A * and generates a series of appropriately (e.g. block- or page-) 462043SN/A * aligned chunks covering the same region. 472101SN/A * 482101SN/A * Example usage: 496384Sgblack@eecs.umich.edu 506384Sgblack@eecs.umich.edu\code 516384Sgblack@eecs.umich.edu for (ChunkGenerator gen(addr, size, chunkSize); !gen.done(); gen.next()) { 526384Sgblack@eecs.umich.edu doSomethingChunky(gen.addr(), gen.size()); 536384Sgblack@eecs.umich.edu } 546384Sgblack@eecs.umich.edu\endcode 552101SN/A */ 562101SN/Aclass ChunkGenerator 572101SN/A{ 582046SN/A private: 592686Sksewell@umich.edu /** The starting address of the current chunk. */ 602686Sksewell@umich.edu Addr curAddr; 612686Sksewell@umich.edu /** The starting address of the next chunk (after the current one). */ 622470SN/A Addr nextAddr; 632686Sksewell@umich.edu /** The size of the current chunk (in bytes). */ 644661Sksewell@umich.edu int curSize; 655222Sksewell@umich.edu /** The number of bytes remaining in the region after the current chunk. */ 665222Sksewell@umich.edu int sizeLeft; 672686Sksewell@umich.edu /** The start address so we can calculate offset in writing block. */ 6813389Sgabeblack@google.com const Addr startAddr; 692470SN/A /** The maximum chunk size, e.g., the cache block size or page size. */ 702241SN/A const int chunkSize; 712101SN/A 722495SN/A public: 732495SN/A /** 7413389Sgabeblack@google.com * Constructor. 752101SN/A * @param _startAddr The starting address of the region. 766384Sgblack@eecs.umich.edu * @param totalSize The total size of the region. 776384Sgblack@eecs.umich.edu * @param _chunkSize The size/alignment of chunks into which 786384Sgblack@eecs.umich.edu * the region should be decomposed. 7913389Sgabeblack@google.com */ 806384Sgblack@eecs.umich.edu ChunkGenerator(Addr _startAddr, int totalSize, int _chunkSize) 812495SN/A : startAddr(_startAddr), chunkSize(_chunkSize) 822101SN/A { 832101SN/A // chunkSize must be a power of two 842495SN/A assert(chunkSize == 0 || isPowerOf2(chunkSize)); 852495SN/A assert(totalSize >= 0); 862495SN/A 872495SN/A // set up initial chunk. 882495SN/A curAddr = startAddr; 892495SN/A 902495SN/A if (chunkSize == 0) //Special Case, if we see 0, assume no chuncking 912495SN/A { 922495SN/A nextAddr = startAddr + totalSize; 932495SN/A } 942495SN/A else 952495SN/A { 962495SN/A // nextAddr should be *next* chunk start 972101SN/A nextAddr = roundUp(startAddr, chunkSize); 9813389Sgabeblack@google.com if (curAddr == nextAddr) { 992101SN/A // ... even if startAddr is already chunk-aligned 1002101SN/A nextAddr += chunkSize; 10113389Sgabeblack@google.com } 1022101SN/A } 1036384Sgblack@eecs.umich.edu 1046384Sgblack@eecs.umich.edu // how many bytes are left between curAddr and the end of this chunk? 1056384Sgblack@eecs.umich.edu int left_in_chunk = nextAddr - curAddr; 10613389Sgabeblack@google.com curSize = std::min(totalSize, left_in_chunk); 1076384Sgblack@eecs.umich.edu sizeLeft = totalSize - curSize; 1082101SN/A } 1092101SN/A 1102495SN/A /** Return starting address of current chunk. */ 1112495SN/A Addr addr() { return curAddr; } 1122495SN/A /** Return size in bytes of current chunk. */ 1132495SN/A int size() { return curSize; } 1142495SN/A 1156384Sgblack@eecs.umich.edu /** Number of bytes we have already chunked up. */ 1166384Sgblack@eecs.umich.edu int complete() { return curAddr - startAddr; } 1176384Sgblack@eecs.umich.edu /** 1186384Sgblack@eecs.umich.edu * Are we done? That is, did the last call to next() advance 1196384Sgblack@eecs.umich.edu * past the end of the region? 1202495SN/A * @return True if yes, false if more to go. 1216384Sgblack@eecs.umich.edu */ 1222495SN/A bool done() { return (curSize == 0); } 1232495SN/A 1242043SN/A /** 1252043SN/A * Advance generator to next chunk. 1262025SN/A * @return True if successful, false if unsuccessful 1272043SN/A * (because we were at the last chunk). 1282686Sksewell@umich.edu */ 1292686Sksewell@umich.edu bool next() 1302123SN/A { 1312101SN/A if (sizeLeft == 0) { 1326376Sgblack@eecs.umich.edu curSize = 0; 1336376Sgblack@eecs.umich.edu return false; 1346376Sgblack@eecs.umich.edu } 1357792Sgblack@eecs.umich.edu 1366376Sgblack@eecs.umich.edu curAddr = nextAddr; 1376376Sgblack@eecs.umich.edu curSize = std::min(sizeLeft, chunkSize); 1386376Sgblack@eecs.umich.edu sizeLeft -= curSize; 1396376Sgblack@eecs.umich.edu nextAddr += curSize; 1406376Sgblack@eecs.umich.edu return true; 1416376Sgblack@eecs.umich.edu } 1426376Sgblack@eecs.umich.edu}; 1437792Sgblack@eecs.umich.edu 1446376Sgblack@eecs.umich.edu#endif // __BASE__CHUNK_GENERATOR_HH__ 1456376Sgblack@eecs.umich.edu