162 lines
2.9 KiB
C
162 lines
2.9 KiB
C
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// 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 <guard.h>
|
||
|
#include <nocopy.h>
|
||
|
|
||
|
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_
|