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