///-*-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.////////////////////////////////////////////////////////////////////////////////#ifndef _THREADHEAP_H_#define _THREADHEAP_H_#include "config.h"#include <string.h>#include "heap.h"namespace BPrivate {class processHeap; // forward declaration//// We use one threadHeap for each thread (processor).//class threadHeap : public hoardHeap {public:threadHeap(void);// Memory allocation routines.void *malloc(const size_t sz);inline void *memalign(size_t alignment, size_t sz);// Find out how large an allocated object is.inline static size_t objectSize(void *ptr);// Set our process heap.inline void setpHeap(processHeap *p);private:// Prevent copying and assignment.threadHeap(const threadHeap &);const threadHeap &operator=(const threadHeap &);// Our process heap.processHeap *_pHeap;// We insert a cache pad here to avoid false sharing (the// processHeap holds an array of threadHeaps, and we don't want// these to share any cache lines).double _pad[CACHE_LINE / sizeof(double)];};void *threadHeap::memalign(size_t alignment, size_t size){// Calculate the amount of space we need// to satisfy the alignment requirements.size_t newSize;// If the alignment is less than the required alignment,// just call malloc.if (alignment <= ALIGNMENT)return this->malloc(size);if (alignment < sizeof(block))alignment = sizeof(block);// Alignment must be a power of two!assert((alignment & (alignment - 1)) == 0);// Leave enough room to align the block within the malloced space.newSize = size + sizeof(block) + alignment;// Now malloc the space up with a little extra (we'll put the block// pointer in right behind the allocated space).void *ptr = this->malloc(newSize);if ((((unsigned long) ptr) & -((long) alignment)) == 0) {// ptr is already aligned, so return it.assert(((unsigned long) ptr % alignment) == 0);return ptr;} else {// Align ptr.char *newptr = (char *)(((unsigned long)ptr + alignment - 1) & -((long)alignment));// If there's not enough room for the block header, skip to the// next aligned space within the block..if ((unsigned long)newptr - (unsigned long)ptr < sizeof(block))newptr += alignment;assert(((unsigned long)newptr % alignment) == 0);// Copy the block from the start of the allocated memory.block *b = ((block *)ptr - 1);assert(b->isValid());assert(b->getSuperblock()->isValid());// Make sure there's enough room for the block header.assert(((unsigned long)newptr - (unsigned long)ptr) >=sizeof(block));block *p = ((block *)newptr - 1);// Make sure there's enough room allocated for size bytes.assert(((unsigned long)p - sizeof(block)) >= (unsigned long)b);if (p != b) {assert((unsigned long)newptr > (unsigned long)ptr);// Copy the block header.*p = *b;assert(p->isValid());assert(p->getSuperblock()->isValid());// Set the next pointer to point to b with the 1 bit set.// When this block is freed, it will be treated specially.p->setNext((block *)((unsigned long)b | 1));} elseassert(ptr != newptr);assert(((unsigned long)ptr + newSize) >=((unsigned long)newptr + size));return newptr;}}size_tthreadHeap::objectSize(void *ptr){// Find the superblock pointer.block *b = ((block *)ptr - 1);assert(b->isValid());superblock *sb = b->getSuperblock();assert(sb);// Return the size.return sizeFromClass(sb->getBlockSizeClass());}void threadHeap::setpHeap(processHeap *p){_pHeap = p;}} // namespace BPrivate#endif // _THREADHEAP_H_