1 ///-*-C++-*-////////////////////////////////////////////////////////////////// 2 // 3 // The Hoard Multiprocessor Memory Allocator 4 // Contact author: Emery Berger, http://www.cs.utexas.edu/users/emery 5 // 6 // Copyright (c) 1998-2000, The University of Texas at Austin. 7 // 8 // This library is free software; you can redistribute it and/or modify 9 // it under the terms of the GNU Library General Public License as 10 // published by the Free Software Foundation, http://www.fsf.org. 11 // 12 // This library is distributed in the hope that it will be useful, but 13 // WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 // Library General Public License for more details. 16 // 17 ////////////////////////////////////////////////////////////////////////////// 18 19 /* 20 superblock.cpp 21 ------------------------------------------------------------------------ 22 The superblock class controls a number of blocks (which are 23 allocatable units of memory). 24 ------------------------------------------------------------------------ 25 Emery Berger | <http://www.cs.utexas.edu/users/emery> 26 Department of Computer Sciences | <http://www.cs.utexas.edu> 27 University of Texas at Austin | <http://www.utexas.edu> 28 ======================================================================== 29 */ 30 31 #include <string.h> 32 33 #include "arch-specific.h" 34 #include "config.h" 35 #include "heap.h" 36 #include "processheap.h" 37 #include "superblock.h" 38 39 using namespace BPrivate; 40 41 42 superblock::superblock(int numBlocks, // The number of blocks in the sb. 43 int szclass, // The size class of the blocks. 44 hoardHeap * o) // The heap that "owns" this sb. 45 : 46 #if HEAP_DEBUG 47 _magic(SUPERBLOCK_MAGIC), 48 #endif 49 _sizeClass(szclass), 50 _numBlocks(numBlocks), 51 _numAvailable(0), 52 _fullness(0), _freeList(NULL), _owner(o), _next(NULL), _prev(NULL) 53 { 54 assert(_numBlocks >= 1); 55 56 // Determine the size of each block. 57 const int blksize = hoardHeap::align(sizeof(block) 58 + hoardHeap::sizeFromClass(_sizeClass)); 59 60 // Make sure this size is in fact aligned. 61 assert((blksize & hoardHeap::ALIGNMENT_MASK) == 0); 62 63 // Set the first block to just past this superblock header. 64 block *b = (block *) hoardHeap::align((unsigned long)(this + 1)); 65 66 // Initialize all the blocks, 67 // and insert the block pointers into the linked list. 68 for (int i = 0; i < _numBlocks; i++) { 69 // Make sure the block is on a double-word boundary. 70 assert(((unsigned long)b & hoardHeap::ALIGNMENT_MASK) == 0); 71 new(b) block(this); 72 assert(b->getSuperblock() == this); 73 b->setNext(_freeList); 74 _freeList = b; 75 b = (block *)((char *)b + blksize); 76 } 77 78 _numAvailable = _numBlocks; 79 computeFullness(); 80 assert((unsigned long)b <= hoardHeap::align(sizeof(superblock) + blksize * _numBlocks) 81 + (unsigned long)this); 82 83 hoardLockInit(_upLock, "hoard superblock"); 84 } 85 86 87 superblock * 88 superblock::makeSuperblock(int sizeclass, processHeap *pHeap) 89 { 90 // We need to get more memory. 91 92 char *buf; 93 int numBlocks = hoardHeap::numBlocks(sizeclass); 94 95 // Compute how much memory we need. 96 unsigned long moreMemory; 97 if (numBlocks > 1) { 98 moreMemory = hoardHeap::SUPERBLOCK_SIZE; 99 assert(moreMemory >= hoardHeap::align(sizeof(superblock) 100 + (hoardHeap::align(sizeof(block) 101 + hoardHeap::sizeFromClass(sizeclass))) * numBlocks)); 102 103 // Get some memory from the process heap. 104 buf = (char *)pHeap->getSuperblockBuffer(); 105 } else { 106 // One object. 107 assert(numBlocks == 1); 108 109 size_t blksize = hoardHeap::align(sizeof(block) 110 + hoardHeap::sizeFromClass(sizeclass)); 111 moreMemory = hoardHeap::align(sizeof(superblock) + blksize); 112 113 // Get space from the system. 114 buf = (char *)hoardSbrk(moreMemory); 115 } 116 117 // Make sure that we actually got the memory. 118 if (buf == NULL) 119 return 0; 120 121 buf = (char *)hoardHeap::align((unsigned long)buf); 122 123 // Make sure this buffer is double-word aligned. 124 assert(buf == (char *)hoardHeap::align((unsigned long)buf)); 125 assert((((unsigned long)buf) & hoardHeap::ALIGNMENT_MASK) == 0); 126 127 // Instantiate the new superblock in the buffer. 128 return new(buf) superblock(numBlocks, sizeclass, NULL); 129 } 130