From d0ae3caca5828675335d3b19ab5dd987e7369b23 Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Wed, 14 Jul 2004 16:21:44 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r1857, which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/tb/; revision=1858 --- sc4pd/headers/lang/PowerOfTwoAllocPool.h | 154 +++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100755 sc4pd/headers/lang/PowerOfTwoAllocPool.h (limited to 'sc4pd/headers/lang/PowerOfTwoAllocPool.h') diff --git a/sc4pd/headers/lang/PowerOfTwoAllocPool.h b/sc4pd/headers/lang/PowerOfTwoAllocPool.h new file mode 100755 index 0000000..8dde18f --- /dev/null +++ b/sc4pd/headers/lang/PowerOfTwoAllocPool.h @@ -0,0 +1,154 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// Implements a power of two size class allocator. +// There is no consolidation of free space. Once a chunk is allocated it +// remains at that size from then on whether free or allocated. +// It uses AdvancingAllocPool as its parent allocator. +// It is very fast. This is used to allocate Unit output buffers. + +#ifndef _PowerOfTwoAllocPool_ +#define _PowerOfTwoAllocPool_ + +#include +#include +#include "clz.h" +#include "AdvancingAllocPool.h" +#include "SC_AllocPool.h" +void post(const char *fmt, ...); +void postbuf(const char *fmt, ...); + +template +class PowerOfTwoAllocPool +{ +public: + PowerOfTwoAllocPool(::AllocPool *inPool, + size_t initSize = 64*1024, + size_t growSize = 64*1024 + ) + { + mLargeObjPool = inPool; + mNumLargeObjects = 0; + mNumAlloc = 0; + mNumFree = 0; + size_t tooBigSize = (sizeof(Hdr) + (sizeof(Elem) << (LargeObjSizeClass-1))) + 1; + mSmallObjPool.Init(inPool, initSize, growSize, tooBigSize); + Init(); + assert(SanityCheck()); + } + ~PowerOfTwoAllocPool() + { + assert(SanityCheck()); + assert(mNumLargeObjects == 0); // you have to free the big ones yourself + mSmallObjPool.FreeAll(); + } + + Obj* Alloc(int32 inNumElems) + { + //mNumAlloc++; + assert(SanityCheck()); + int sizeclass = LOG2CEIL(inNumElems); + if (sizeclass >= LargeObjSizeClass) { + mNumLargeObjects++; + size_t size = sizeof(Hdr) + (sizeof(Elem) * inNumElems); + return (Obj*)mLargeObjPool->Alloc(size); + } + + // get from free list + Obj* obj = mFreeLists[sizeclass]; + if (obj != NULL) { + // set free list to next element. + mFreeLists[sizeclass] = *(Obj**)obj; + } else { + // have to allocate it + size_t size = mSizes[sizeclass]; + obj = (Obj*)mSmallObjPool.Alloc(size); + if (!obj) throw runtime_error("PowerOfTwoAllocPool out of memory"); + } + //obj->mMagic = 'magk'; + assert(SanityCheck()); + return obj; + } + void Free(Obj* inObjPtr) + { + //mNumFree++; + assert(SanityCheck()); + if (inObjPtr == 0) return; /* free(0) has no effect */ + /*if (inObjPtr->mMagic != 'magk') { + postbuf("bad object\n"); + throw runtime_error("bad object"); + }*/ + int sizeclass = inObjPtr->SizeClass(); + if (sizeclass >= LargeObjSizeClass) { + mLargeObjPool->Free(inObjPtr); + mNumLargeObjects--; + } else { + Obj* nextfree = mFreeLists[sizeclass]; + mFreeLists[sizeclass] = inObjPtr; + *(Obj**)inObjPtr = nextfree; + } + assert(SanityCheck()); + } + void FreeAll() + { + assert(mNumLargeObjects == 0); // you have to free the big ones yourself + mSmallObjPool.FreeAll(); + Init(); + } + + bool SanityCheck() + { + //postbuf("PowerOfTwoAllocPool::SanityCheck %d %d\n", mNumAlloc, mNumFree); + mLargeObjPool->DoCheckPool(); + mSmallObjPool.SanityCheck(); + for (int i=0; i=1000) { + post("linked loop??\n"); + throw runtime_error("linked loop??\n"); + return false; + } + obj = *(Obj**)obj; + } + } + return true; + } +private: + void Init() + { + for (int i=0; i Date: Thu, 19 Jun 2008 13:50:58 +0000 Subject: removed the svn:executable bit for code, patches and text svn path=/trunk/externals/tb/; revision=10048 --- sc4pd/headers/lang/PowerOfTwoAllocPool.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 sc4pd/headers/lang/PowerOfTwoAllocPool.h (limited to 'sc4pd/headers/lang/PowerOfTwoAllocPool.h') diff --git a/sc4pd/headers/lang/PowerOfTwoAllocPool.h b/sc4pd/headers/lang/PowerOfTwoAllocPool.h old mode 100755 new mode 100644 -- cgit v1.2.1