📄 processheap.cpp
字号:
///-*-C++-*-////////////////////////////////////////////////////////////////////// Hoard: A Fast, Scalable, and Memory-Efficient Allocator// for Shared-Memory Multiprocessors// Contact author: Emery Berger, http://www.cs.utexas.edu/users/emery//// Copyright (c) 1998-2000, The University of Texas at Austin.//// This library is free software; you can redistribute it and/or modify// it under the terms of the GNU Library General Public License as// published by the Free Software Foundation, http://www.fsf.org.//// This library is distributed in the hope that it will be useful, but// WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Library General Public License for more details.////////////////////////////////////////////////////////////////////////////////#include <string.h>#include <stdio.h>#include "config.h"#if USE_PRIVATE_HEAPS#include "privateheap.h"#define HEAPTYPE privateHeap#else#define HEAPTYPE threadHeap#include "threadheap.h"#endif#include "processheap.h"processHeap::processHeap (void) : _buffer (NULL), _bufferCount (0)#if HEAP_FRAG_STATS , _currentAllocated (0), _currentRequested (0), _maxAllocated (0), _inUseAtMaxAllocated (0), _maxRequested (0)#endif{ int i; // The process heap is heap 0. setIndex (0); for (i = 0; i < MAX_HEAPS; i++) { // Set every thread's process heap to this one. theap[i].setpHeap (this); // Set every thread heap's index. theap[i].setIndex (i + 1); }#if HEAP_LOG for (i = 0; i < MAX_HEAPS + 1; i++) { char fname[255]; sprintf (fname, "log%d", i); unlink (fname); _log[i].open (fname); }#endif#if HEAP_FRAG_STATS hoardLockInit (_statsLock);#endif hoardLockInit (_bufferLock);}// Print out statistics information.void processHeap::stats (void) {#if HEAP_STATS int umax = 0; int amax = 0; for (int j = 0; j < MAX_HEAPS; j++) { for (int i = 0; i < SIZE_CLASSES; i++) { amax += theap[j].maxAllocated(i) * sizeFromClass (i); umax += theap[j].maxInUse(i) * sizeFromClass (i); } } printf ("Amax <= %d, Umax <= %d\n", amax, umax);#if HEAP_FRAG_STATS amax = getMaxAllocated(); umax = getMaxRequested(); printf ("Maximum allocated = %d\nMaximum in use = %d\nIn use at max allocated = %d\n", amax, umax, getInUseAtMaxAllocated()); printf ("Still in use = %d\n", _currentRequested); printf ("Fragmentation (3) = %f\n", (float) amax / (float) getInUseAtMaxAllocated()); printf ("Fragmentation (4) = %f\n", (float) amax / (float) umax);#endif#endif // HEAP_STATS#if HEAP_LOG printf ("closing logs.\n"); fflush (stdout); for (int i = 0; i < MAX_HEAPS + 1; i++) { _log[i].close(); }#endif}#if HEAP_FRAG_STATSvoid processHeap::setAllocated (int requestedSize, int actualSize){ hoardLock (_statsLock); _currentRequested += requestedSize; _currentAllocated += actualSize; if (_currentRequested > _maxRequested) { _maxRequested = _currentRequested; } if (_currentAllocated > _maxAllocated) { _maxAllocated = _currentAllocated; _inUseAtMaxAllocated = _currentRequested; } hoardUnlock (_statsLock);}void processHeap::setDeallocated (int requestedSize, int actualSize){ hoardLock (_statsLock); _currentRequested -= requestedSize; _currentAllocated -= actualSize; hoardUnlock (_statsLock);}#endif// free (ptr, pheap):// inputs: a pointer to an object allocated by malloc().// side effects: returns the block to the object's superblock;// updates the thread heap's statistics;// may release the superblock to the process heap.void processHeap::free (void * ptr){ // Return if ptr is 0. // This is the behavior prescribed by the standard. if (ptr == 0) { return; } // Find the block and superblock corresponding to this ptr. block * b = (block *) ptr - 1; assert (b->isValid()); // Check to see if this block came from a memalign() call. if (((unsigned long) b->getNext() & 1) == 1) { // It did. Set the block to the actual block header. b = (block *) ((unsigned long) b->getNext() & ~1); assert (b->isValid()); } b->markFree(); superblock * sb = b->getSuperblock(); assert (sb); assert (sb->isValid()); const int sizeclass = sb->getBlockSizeClass(); // // Return the block to the superblock, // find the heap that owns this superblock // and update its statistics. // hoardHeap * owner; // By acquiring the up lock on the superblock, // we prevent it from moving to the global heap. // This eventually pins it down in one heap, // so this loop is guaranteed to terminate. // (It should generally take no more than two iterations.) sb->upLock(); while (1) { owner = sb->getOwner(); owner->lock(); if (owner == sb->getOwner()) { break; } else { owner->unlock(); } // Suspend to allow ownership to quiesce. hoardYield(); }#if HEAP_LOG MemoryRequest m; m.free (ptr); getLog (owner->getIndex()).append(m);#endif#if HEAP_FRAG_STATS setDeallocated (b->getRequestedSize(), 0);#endif int sbUnmapped = owner->freeBlock (b, sb, sizeclass, this); owner->unlock(); if (!sbUnmapped) { sb->upUnlock(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -