chunk_generator.hh revision 2565
11897Sstever@eecs.umich.edu/* 23077Sstever@eecs.umich.edu * Copyright (c) 2001-2005 The Regents of The University of Michigan 31897Sstever@eecs.umich.edu * All rights reserved. 41897Sstever@eecs.umich.edu * 51897Sstever@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 61897Sstever@eecs.umich.edu * modification, are permitted provided that the following conditions are 71897Sstever@eecs.umich.edu * met: redistributions of source code must retain the above copyright 81897Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 91897Sstever@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 101897Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 111897Sstever@eecs.umich.edu * documentation and/or other materials provided with the distribution; 121897Sstever@eecs.umich.edu * neither the name of the copyright holders nor the names of its 131897Sstever@eecs.umich.edu * contributors may be used to endorse or promote products derived from 141897Sstever@eecs.umich.edu * this software without specific prior written permission. 151897Sstever@eecs.umich.edu * 161897Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171897Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181897Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191897Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201897Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211897Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221897Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231897Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241897Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251897Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261897Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271897Sstever@eecs.umich.edu */ 281897Sstever@eecs.umich.edu 291897Sstever@eecs.umich.edu#ifndef __BASE__CHUNK_GENERATOR_HH__ 301897Sstever@eecs.umich.edu#define __BASE__CHUNK_GENERATOR_HH__ 311897Sstever@eecs.umich.edu 321897Sstever@eecs.umich.edu/** 331897Sstever@eecs.umich.edu * @file 341897Sstever@eecs.umich.edu * Declaration and inline definition of ChunkGenerator object. 351897Sstever@eecs.umich.edu */ 361897Sstever@eecs.umich.edu 371897Sstever@eecs.umich.edu#include <algorithm> 381897Sstever@eecs.umich.edu#include "base/intmath.hh" 391897Sstever@eecs.umich.edu#include "arch/isa_traits.hh" // for Addr 401897Sstever@eecs.umich.edu 411897Sstever@eecs.umich.edu/** 423077Sstever@eecs.umich.edu * This class takes an arbitrary memory region (address/length pair) 433099Sstever@eecs.umich.edu * and generates a series of appropriately (e.g. block- or page-) 443099Sstever@eecs.umich.edu * aligned chunks covering the same region. 451897Sstever@eecs.umich.edu * 463709Sstever@eecs.umich.edu * Example usage: 473099Sstever@eecs.umich.edu 483099Sstever@eecs.umich.edu\code 491897Sstever@eecs.umich.edu for (ChunkGenerator gen(addr, size, chunkSize); !gen.done(); gen.next()) { 503099Sstever@eecs.umich.edu doSomethingChunky(gen.addr(), gen.size()); 511897Sstever@eecs.umich.edu } 521897Sstever@eecs.umich.edu\endcode 531897Sstever@eecs.umich.edu */ 541897Sstever@eecs.umich.educlass ChunkGenerator 551897Sstever@eecs.umich.edu{ 561897Sstever@eecs.umich.edu private: 571897Sstever@eecs.umich.edu /** The starting address of the current chunk. */ 581897Sstever@eecs.umich.edu Addr curAddr; 591897Sstever@eecs.umich.edu /** The starting address of the next chunk (after the current one). */ 601897Sstever@eecs.umich.edu Addr nextAddr; 611897Sstever@eecs.umich.edu /** The size of the current chunk (in bytes). */ 621897Sstever@eecs.umich.edu int curSize; 631897Sstever@eecs.umich.edu /** The number of bytes remaining in the region after the current chunk. */ 641897Sstever@eecs.umich.edu int sizeLeft; 651897Sstever@eecs.umich.edu /** The start address so we can calculate offset in writing block. */ 661897Sstever@eecs.umich.edu const Addr startAddr; 671897Sstever@eecs.umich.edu /** The maximum chunk size, e.g., the cache block size or page size. */ 681897Sstever@eecs.umich.edu const int chunkSize; 691897Sstever@eecs.umich.edu 701897Sstever@eecs.umich.edu public: 711897Sstever@eecs.umich.edu /** 721897Sstever@eecs.umich.edu * Constructor. 731897Sstever@eecs.umich.edu * @param startAddr The starting address of the region. 741897Sstever@eecs.umich.edu * @param totalSize The total size of the region. 751897Sstever@eecs.umich.edu * @param _chunkSize The size/alignment of chunks into which 761897Sstever@eecs.umich.edu * the region should be decomposed. 771897Sstever@eecs.umich.edu */ 781897Sstever@eecs.umich.edu ChunkGenerator(Addr _startAddr, int totalSize, int _chunkSize) 791897Sstever@eecs.umich.edu : startAddr(_startAddr), chunkSize(_chunkSize) 801897Sstever@eecs.umich.edu { 813077Sstever@eecs.umich.edu // chunkSize must be a power of two 823077Sstever@eecs.umich.edu assert(chunkSize == 0 || isPowerOf2(chunkSize)); 833077Sstever@eecs.umich.edu 843077Sstever@eecs.umich.edu // set up initial chunk. 853077Sstever@eecs.umich.edu curAddr = startAddr; 863077Sstever@eecs.umich.edu 873077Sstever@eecs.umich.edu if (chunkSize == 0) //Special Case, if we see 0, assume no chuncking 883077Sstever@eecs.umich.edu { 893077Sstever@eecs.umich.edu nextAddr = startAddr + totalSize; 901897Sstever@eecs.umich.edu } 911897Sstever@eecs.umich.edu else 921897Sstever@eecs.umich.edu { 931897Sstever@eecs.umich.edu // nextAddr should be *next* chunk start 941897Sstever@eecs.umich.edu nextAddr = roundUp(startAddr, chunkSize); 951897Sstever@eecs.umich.edu if (curAddr == nextAddr) { 961897Sstever@eecs.umich.edu // ... even if startAddr is already chunk-aligned 971897Sstever@eecs.umich.edu nextAddr += chunkSize; 98 } 99 } 100 101 // how many bytes are left between curAddr and the end of this chunk? 102 int left_in_chunk = nextAddr - curAddr; 103 curSize = std::min(totalSize, left_in_chunk); 104 sizeLeft = totalSize - curSize; 105 } 106 107 /** Return starting address of current chunk. */ 108 Addr addr() { return curAddr; } 109 /** Return size in bytes of current chunk. */ 110 int size() { return curSize; } 111 112 /** Number of bytes we have already chunked up. */ 113 int complete() { return curAddr - startAddr; } 114 /** 115 * Are we done? That is, did the last call to next() advance 116 * past the end of the region? 117 * @return True if yes, false if more to go. 118 */ 119 bool done() { return (curSize == 0); } 120 121 /** 122 * Advance generator to next chunk. 123 * @return True if successful, false if unsuccessful 124 * (because we were at the last chunk). 125 */ 126 bool next() 127 { 128 if (sizeLeft == 0) { 129 curSize = 0; 130 return false; 131 } 132 133 curAddr = nextAddr; 134 curSize = std::min(sizeLeft, chunkSize); 135 sizeLeft -= curSize; 136 nextAddr += curSize; 137 return true; 138 } 139}; 140 141#endif // __BASE__CHUNK_GENERATOR_HH__ 142