/////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 1997, Microsoft Corp. All rights reserved. // // FILE // // MemPool.h // // SYNOPSIS // // This file describes the class memory_pool. // // MODIFICATION HISTORY // // 08/04/1997 Original version. // 11/12/1997 Added the clear() method. // Added code to clobber freed chunks in debug builds. // 01/08/1998 SunDown changes. // 04/10/1998 Got rid of the wrapper around InterlockedExchangePointer // since it was causing some inefficient code to be generated. // 08/06/1998 Support pluggable allocators. // /////////////////////////////////////////////////////////////////////////////// #ifndef _MEMPOOL_H_ #define _MEMPOOL_H_ #include #include class crt_allocator { public: static void* allocate(size_t nbyte) throw () { return malloc(nbyte); } static void deallocate(void* p) throw () { free(p); } }; class task_allocator { public: static void* allocate(size_t nbyte) throw () { return CoTaskMemAlloc((ULONG)nbyte); } static void deallocate(void* p) throw () { CoTaskMemFree(p); } }; class virtual_allocator { public: static void* allocate(size_t nbyte) throw () { return VirtualAlloc(NULL, (DWORD)nbyte, MEM_COMMIT, PAGE_READWRITE); } static void deallocate(void* p) throw () { VirtualFree(p, 0, MEM_RELEASE); } }; /////////////////////////////////////////////////////////////////////////////// // // CLASS // // memory_pool // // DESCRIPTION // // Implements a reusable pool of memory chunks of size 'Size'. // /////////////////////////////////////////////////////////////////////////////// template < size_t Size, class Allocator > class memory_pool : Guardable, NonCopyable { public: memory_pool() throw () : pool(NULL) { } ~memory_pool() throw () { clear(); } void clear() throw () { Lock(); // Get the linked list from the pool ... void* p = pool; pool = NULL; Unlock(); // ... and iterate through deleting each node. while (p) { void* next = *((void**)p); Allocator::deallocate(p); p = next; } } void* allocate() throw () { Lock(); void* p = pool; // Are there any chunks in the pool? if (p) { pool = *(void**)p; Unlock(); return p; } Unlock(); // The pool is empty, so call the new operator directly. return Allocator::allocate(Size); } void deallocate(void* p) throw() { if (p) { #ifdef DEBUG memset(p, 0xA3, Size); #endif Lock(); *((void**)p) = pool; pool = p; Unlock(); } } protected: void* pool; }; #endif // _MEMPOOL_H_