87 lines
3.9 KiB
C
87 lines
3.9 KiB
C
/****************************************************************
|
|
* *
|
|
* Copyright 2003, 2010 Fidelity Information Services, Inc *
|
|
* *
|
|
* This source code contains the intellectual property *
|
|
* of its copyright holder(s), and is made available *
|
|
* under a license. If you do not know the terms of *
|
|
* the license, please stop and do not read further. *
|
|
* *
|
|
****************************************************************/
|
|
|
|
#ifndef GTM_MALLOC_H__included
|
|
#define GTM_MALLOC_H__included
|
|
|
|
#define GTM_MEMORY_RESERVE_DEFAULT 64 /* 64K reserve "backpocket-cache" released on out-of-memory error */
|
|
|
|
typedef GTM64_ONLY(gtm_uint8) NON_GTM64_ONLY(unsigned int) gtm_msize_t;
|
|
|
|
/* Each allocated block has the following structure. The actual address
|
|
returned to the user for 'malloc' and supplied by the user for 'free'
|
|
is actually the storage beginning at the 'userStorage.userStart' area.
|
|
This holds true even for storage that is truely malloc'd. Note that true
|
|
allocated length is kept even in the pro header.
|
|
*/
|
|
typedef struct storElemStruct
|
|
{ /* While the following chars and short are not the best for performance, they enable us
|
|
to keep the header size to 8 bytes in a pro build. This is important since our minimum
|
|
allocation size is 16 bytes leaving 8 bytes for data. Also I have not researched what
|
|
they are, there are a bunch of 8 byte allocates in GT.M that if we were to go to a 16
|
|
byte header would make the minimum block size 32 bytes thus doubling the storage
|
|
requirements for these small blocks. SE 03/2002 [Note 16 byte header is the norm in 64 bit]
|
|
*/
|
|
signed char queueIndex; /* Index into TwoTable for this size of element */
|
|
unsigned char state; /* State of this block */
|
|
unsigned short extHdrOffset; /* For MAXTWO sized elements: offset to the
|
|
header that describes the extent */
|
|
GTM64_ONLY(char filler[4];) /* Explicit filler to align the length - may be repurposed */
|
|
gtm_msize_t realLen; /* Real (total) length of allocation */
|
|
#ifdef DEBUG
|
|
struct storElemStruct *fPtr; /* Next storage element on free/allocated queue */
|
|
struct storElemStruct *bPtr; /* Previous storage element on free/allocated queue */
|
|
unsigned char *allocatedBy; /* Who allocated storage */
|
|
gtm_msize_t allocLen; /* Requested length of allocation */
|
|
gtm_msize_t smTn; /* Storage management transaction number allocated at */
|
|
unsigned char headMarker[GTM64_ONLY(8)NON_GTM64_ONLY(4)]; /* Header that should not be modified during usage */
|
|
union
|
|
{
|
|
struct storElemStruct *deferFreeNext; /* Pointer to next deferred free block */
|
|
unsigned char userStart; /* First byte of user useable storage */
|
|
} userStorage;
|
|
#else
|
|
union /* In production mode, the links are used only when element is free */
|
|
{
|
|
struct storElemStruct *deferFreeNext; /* Pointer to next deferred free block */
|
|
struct /* Free block information */
|
|
{
|
|
struct storElemStruct *fPtr; /* Next storage element on free queue */
|
|
struct storElemStruct *bPtr; /* Previous storage element on free queue */
|
|
} links;
|
|
unsigned char userStart; /* First byte of user useable storage */
|
|
} userStorage;
|
|
#endif
|
|
} storElem;
|
|
|
|
size_t gtm_bestfitsize(size_t);
|
|
void verifyFreeStorage(void);
|
|
void verifyAllocatedStorage(void);
|
|
void raise_gtmmemory_error(void);
|
|
void printMallocInfo(void);
|
|
void printMallocDump(void);
|
|
|
|
/* When verifying the storage chains, check the allocated chain first in case overruns for allocated storage
|
|
* have damaged the free chains. This way we find the culprit rather than the symptom. Of course, in the case
|
|
* where free'd storage is continued to be used, this method breaks down but it is hoped the chosen way finds
|
|
* the greater number of issues rather than their symptoms.
|
|
*/
|
|
#define VERIFY_STORAGE_CHAINS \
|
|
{ \
|
|
GBLREF uint4 gtmDebugLevel; \
|
|
if (GDL_SmAllocVerf & gtmDebugLevel) \
|
|
verifyAllocatedStorage(); \
|
|
if (GDL_SmFreeVerf & gtmDebugLevel) \
|
|
verifyFreeStorage(); \
|
|
}
|
|
|
|
#endif /* GTM_MALLOC_H__included */
|