blob: 24f3f6b44b28a9484eef50aa04f54f60dea4f826 [file] [log] [blame]
/**********************************************************************
* File: memblk.h (Formerly memblock.h)
* Description: Enhanced instrumented memory allocator implemented as a class.
* Author: Ray Smith
* Created: Tue Jan 21 17:13:39 GMT 1992
*
* (C) Copyright 1992, Hewlett-Packard Ltd.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** http://www.apache.org/licenses/LICENSE-2.0
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*
**********************************************************************/
#ifndef MEMBLK_H
#define MEMBLK_H
#include "varable.h"
#define MAXBLOCKS 16 /*max allowed to grab */
#define MAX_STRUCTS 20 //no of units maintained
#define MAX_CLASSES 24 //max classes of each size
#define MAX_FREE_S_BLOCKS 10 //max free list before all freed
#define STRUCT_BLOCK_SIZE 2521
#define MAX_CHUNK 262144 //max single chunk
#define FIRSTSIZE 16384 //size of first block
#define LASTSIZE 262144 //biggest size to use
#define BIGSIZE 2100000 //size of big blocks
#define MAX_BIGCHUNK 20000000 //max chunk of big mem
//#define TESTING_BIGSTUFF //define for big tests
//#define COUNTING_CLASS_STRUCTURES
class MEMUNION
{
public:
union
{
MEMUNION *ptr; //next chunk
inT32 size; //chunk size
};
uinT16 owner; //owner of chunk
uinT16 age; //age of chunk
};
class MEMBLOCK
{
public:
MEMUNION * blockstart; /*start of block */
MEMUNION *blockend; /*end of block */
MEMUNION *freechunk; /*next free chunk */
MEMUNION *topchunk; /*top free chunk */
MEMBLOCK *next; /*next block in chain */
inT32 upperspace; /*space above freechunk */
inT32 lowerspace; /*space below freechunk */
MEMUNION *find_chunk( //find free chunk
inT32 count); //size required
};
class FREE_CALL
{
public:
void *freeer; //return addr
inT32 count; //no of frees
FREE_CALL() { //constructor
freeer = NULL;
count = 0;
}
};
class MALLOC_CALL
{
public:
void *caller; //return addr
FREE_CALL *free_list; //freeer counts
inT32 *counts; //no of blocks
inT32 free_bits; //bits in free table
MALLOC_CALL() { //constructor
caller = NULL;
free_list = NULL;
counts = NULL;
free_bits = 0;
}
void count_freeer( //check a structure
void *addr); //return address
void init_freeers(); //check a structure
};
class MEM_ALLOCATOR
{
public:
inT16 blockcount; //blocks in use
uinT16 malloc_serial; //serial allocation
MEMBLOCK *topblock; //block for permanents
MEMBLOCK *currblock; //current block
MALLOC_CALL *callers; //hash table of callers
void *(*malloc) (inT32); //external allocator
void (*free) (void *); //external free
inT32 maxsize; //biggest block
inT32 biggestblock; //biggest chunk
inT32 totalmem; //total free memory
inT32 memsize; //current block size
uinT32 malloc_div_ratio; //scaling of malloc_serial
uinT32 malloc_minor_serial; //scaling counter
uinT32 malloc_auto_count; //counts auto checks
inT32 call_bits; //size of table
inT32 entries; //size of table
//all memory blocks
MEMBLOCK memblocks[MAXBLOCKS];
void init ( //initialize
void *(*ext_malloc) (inT32),//external source
void (*ext_free) (void *), //external free
inT32 firstsize, //size of first block
inT32 lastsize, //size of last block
inT32 maxchunk); //biggest request
void *alloc( //allocator
inT32 size, //size of chunk
void *caller); //ptr to caller
void *alloc_p( //allocator
inT32 size, //size of chunk
void *caller); //ptr to caller
void dealloc( //deallocator
void *ptr, //mem to free
void *caller); //ptr to caller
void check( //check chunks
const char *string, //message
inT8 level); //amount of checks
void reduce_counts(); //divide by 2
void display_counts(); //count up
MEMBLOCK *new_block( //get new big block
inT32 minsize); //minimum size
uinT16 hash_caller( //check a structure
void *addr); //return address
private:
void init_callers(); //check a structure
void set_owner( //set owner & date
MEMUNION *chunkstart, //chunk to set
void *caller); //ptr to caller
};
extern MEM_ALLOCATOR big_mem;
extern MEM_ALLOCATOR main_mem;
//heads of freelists
extern MEMUNION *free_structs[MAX_STRUCTS];
//number issued
extern inT32 structs_in_use[MAX_STRUCTS];
//number issued
extern inT32 blocks_in_use[MAX_STRUCTS];
//head of block lists
extern MEMUNION *struct_blocks[MAX_STRUCTS];
extern inT32 owner_counts[MAX_STRUCTS][MAX_CLASSES];
extern INT_VAR_H (mem_mallocdepth, 0, "Malloc stack depth to trace");
extern INT_VAR_H (mem_mallocbits, 8, "Log 2 of hash table size");
extern INT_VAR_H (mem_freedepth, 0, "Free stack dpeth to trace");
extern INT_VAR_H (mem_freebits, 8, "Log 2 of hash table size");
extern INT_VAR_H (mem_countbuckets, 16, "No of buckets for histogram");
extern INT_VAR_H (mem_checkfreq, 0,
"Calls to alloc_mem between owner counts");
void *trace_caller( //trace stack
inT32 depth //depth to trace
);
inT32 identify_struct_owner( //get table index
inT32 struct_count, //cell size
const char *name //name of type
);
void check_struct( //check a structure
inT8 level, //print control
inT32 count //no of bytes
);
void check_structs( //count in use on structs
inT8 level //print control
);
void *new_struct_block(); //allocate memory
void old_struct_block( //free a structure block
MEMUNION *deadblock //block to free
);
#endif