Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

197 lines
6.0 KiB

/*===================================================================
Microsoft Denali
Microsoft Confidential.
Copyright 1996 Microsoft Corporation. All Rights Reserved.
Component: Per-Class Memory Management
File: Memcls.h
Owner: dmitryr
This file contains #defines to access ATQ memory cache on per
class basis
===================================================================*/
#ifndef MEMCLS_H
#define MEMCLS_H
// ATQ memory cache
#include <acache.hxx>
// To resolve Assert()
#include "debug.h"
// Prototypes
HRESULT InitMemCls();
HRESULT UnInitMemCls();
/*===================================================================
M A C R O S to make a class use ACACHE allocator
===================================================================*/
/*===================================================================
I n s t r u c t i o n s
To add a class named CFoo to the per-class basis follow these
four simple steps:
1) Inside the class definition include ACACHE_INCLASS_DEFINITIONS():
class CFoo
{
...
ACACHE_INCLASS_DEFINITIONS() // <-add this line
};
2) In a source file add the ACACHE_CODE macro outside
any function body:
ACACHE_CODE(CFoo) // <-add this line
3) In a DLL initialization routine add ACACHE_INIT macro:
ACACHE_INIT(CFoo, 13, hr) // <-add this line
where 13 is the threshold. Use the desired number instead.
4) In a DLL uninitialization routine add ACACHE_UNINIT macro:
ACACHE_UNINIT(CFoo) // <-add this line
===================================================================*/
/*
The following macro should be used inside class definition to
enable per-class caching.
The second operator new is needed in case memchk.h [#define]'s new
to this expanded form.
*/
#define ACACHE_INCLASS_DEFINITIONS() \
public: \
static void * operator new(size_t); \
static void * operator new(size_t, const char *, int); \
static void operator delete(void *); \
static ALLOC_CACHE_HANDLER *sm_pach;
/*
The following macro should be used once per class in a source
file outside of any functions. The argument is the class name.
*/
#define ACACHE_CODE(C) \
ALLOC_CACHE_HANDLER *C::sm_pach; \
void *C::operator new(size_t s) \
{ Assert(s == sizeof(C)); Assert(sm_pach); \
return sm_pach->Alloc(); } \
void *C::operator new(size_t s, const char *, int) \
{ Assert(s == sizeof(C)); Assert(sm_pach); \
return sm_pach->Alloc(); } \
void C::operator delete(void *pv) \
{ Assert(pv); if (sm_pach) sm_pach->Free(pv); }
/*
The following macro should be used once per class in the
DLL initialization routine.
Arguments: class name, cache size, HRESULT var name
*/
#define ACACHE_INIT(C, T, hr) \
{ if (SUCCEEDED(hr)) { Assert(!C::sm_pach); \
ALLOC_CACHE_CONFIGURATION acc = { 1, T, sizeof(C) }; \
C::sm_pach = new ALLOC_CACHE_HANDLER("ASP:" #C, &acc); \
hr = C::sm_pach ? S_OK : E_OUTOFMEMORY; } }
#define ACACHE_INIT_EX(C, T, F, hr) \
{ if (SUCCEEDED(hr)) { Assert(!C::sm_pach); \
ALLOC_CACHE_CONFIGURATION acc = { 1, T, sizeof(C) }; \
C::sm_pach = new ALLOC_CACHE_HANDLER("ASP:" #C, &acc, F); \
hr = C::sm_pach ? S_OK : E_OUTOFMEMORY; } }
/*
The following macro should be used once per class in the
DLL uninitialization routine. The argument is the class name.
*/
#define ACACHE_UNINIT(C) \
{ if (C::sm_pach) { delete C::sm_pach; C::sm_pach = NULL; } }
/*===================================================================
M A C R O S to create a fixes size allocator
===================================================================*/
/*===================================================================
I n s t r u c t i o n s
To add a fixed size allocator for 1K buffers named Foo
to the code follow these simple steps:
1) In a header file include extern definition
ACACHE_FSA_EXTERN(Foo)
2) In a source file the actual definition outside
any function body:
ACACHE_FSA_DEFINITION(Foo)
3) In a DLL initialization routine add INIT macro:
ACACHE_FSA_INIT(Foo, 1024, 13, hr)
where 1024 is the size and 13 is the threshold.
Use the desired numbers instead.
4) In a DLL uninitialization routine add UNINIT macro:
ACACHE_FSA_UNINIT(CFoo)
5) To allocate, do:
void *pv = ACACHE_FSA_ALLOC(Foo)
6) To free, do:
ACACHE_FSA_FREE(Foo, pv)
===================================================================*/
#define ACACHE_FSA_EXTERN(C) \
extern ALLOC_CACHE_HANDLER *g_pach##C;
#define ACACHE_FSA_DEFINITION(C) \
ALLOC_CACHE_HANDLER *g_pach##C = NULL;
#define ACACHE_FSA_INIT(C, S, T, hr) \
{ if (SUCCEEDED(hr)) { Assert(!g_pach##C); \
ALLOC_CACHE_CONFIGURATION acc = { 1, T, S }; \
g_pach##C = new ALLOC_CACHE_HANDLER("ASP:" #C, &acc); \
hr = g_pach##C ? S_OK : E_OUTOFMEMORY; } }
#define ACACHE_FSA_UNINIT(C) \
{ if (g_pach##C) { delete g_pach##C; g_pach##C = NULL; } }
#define ACACHE_FSA_ALLOC(C) \
( g_pach##C ? g_pach##C->Alloc() : NULL )
#define ACACHE_FSA_FREE(C, pv) \
{ Assert(pv); if (g_pach##C) g_pach##C->Free(pv); }
#endif // MEMCLS_H