|
|
/*===================================================================
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
|