windows-nt/Source/XPSP1/NT/net/ias/services/inc/mempool.h

162 lines
2.9 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
///////////////////////////////////////////////////////////////////////////////
//
// 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_