1 ///-*-C++-*-////////////////////////////////////////////////////////////////// 2 // 3 // Hoard: A Fast, Scalable, and Memory-Efficient Allocator 4 // for Shared-Memory Multiprocessors 5 // Contact author: Emery Berger, http://www.cs.utexas.edu/users/emery 6 // 7 // Copyright (c) 1998-2000, The University of Texas at Austin. 8 // 9 // This library is free software; you can redistribute it and/or modify 10 // it under the terms of the GNU Library General Public License as 11 // published by the Free Software Foundation, http://www.fsf.org. 12 // 13 // This library is distributed in the hope that it will be useful, but 14 // WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 // Library General Public License for more details. 17 // 18 ////////////////////////////////////////////////////////////////////////////// 19 20 //#include <limits.h> 21 #include <string.h> 22 23 #include "config.h" 24 25 #include "heap.h" 26 #include "threadheap.h" 27 #include "processheap.h" 28 29 using namespace BPrivate; 30 31 32 threadHeap::threadHeap(void) 33 :_pHeap(0) 34 { 35 } 36 37 38 // malloc (sz): 39 // inputs: the size of the object to be allocated. 40 // returns: a pointer to an object of the appropriate size. 41 // side effects: allocates a block from a superblock; 42 // may call sbrk() (via makeSuperblock). 43 44 void * 45 threadHeap::malloc(const size_t size) 46 { 47 #if MAX_INTERNAL_FRAGMENTATION == 2 48 if (size > 1063315264UL) { 49 debug_printf("malloc() of %lu bytes asked\n", size); 50 return NULL; 51 } 52 #endif 53 54 const int sizeclass = sizeClass(size); 55 block *b = NULL; 56 57 lock(); 58 59 // Look for a free block. 60 // We usually have memory locally so we first look for space in the 61 // superblock list. 62 63 superblock *sb = findAvailableSuperblock(sizeclass, b, _pHeap); 64 if (sb == NULL) { 65 // We don't have memory locally. 66 // Try to get more from the process heap. 67 68 assert(_pHeap); 69 sb = _pHeap->acquire((int)sizeclass, this); 70 71 // If we didn't get any memory from the process heap, 72 // we'll have to allocate our own superblock. 73 if (sb == NULL) { 74 sb = superblock::makeSuperblock(sizeclass, _pHeap); 75 if (sb == NULL) { 76 // We're out of memory! 77 unlock(); 78 return NULL; 79 } 80 #if HEAP_LOG 81 // Record the memory allocation. 82 MemoryRequest m; 83 m.allocate((int)sb->getNumBlocks() * 84 (int)sizeFromClass(sb->getBlockSizeClass())); 85 _pHeap->getLog(getIndex()).append(m); 86 #endif 87 #if HEAP_FRAG_STATS 88 _pHeap->setAllocated(0, 89 sb->getNumBlocks() * sizeFromClass(sb->getBlockSizeClass())); 90 #endif 91 } 92 // Get a block from the superblock. 93 b = sb->getBlock(); 94 assert(b != NULL); 95 96 // Insert the superblock into our list. 97 insertSuperblock(sizeclass, sb, _pHeap); 98 } 99 100 assert(b != NULL); 101 assert(b->isValid()); 102 assert(sb->isValid()); 103 104 b->markAllocated(); 105 106 #if HEAP_LOG 107 MemoryRequest m; 108 m.malloc((void *)(b + 1), align(size)); 109 _pHeap->getLog(getIndex()).append(m); 110 #endif 111 #if HEAP_FRAG_STATS 112 b->setRequestedSize(align(size)); 113 _pHeap->setAllocated(align(size), 0); 114 #endif 115 116 unlock(); 117 118 // Skip past the block header and return the pointer. 119 return (void *)(b + 1); 120 } 121