⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memblk.cpp

📁 一OCR的相关资料。.希望对研究OCR的朋友有所帮助.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/********************************************************************** * File:        memblk.c  (Formerly memblock.c) * 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. * **********************************************************************/#include          "mfcpch.h"     //precompiled headers#include          <stdlib.h>#include          <string.h>#include          "stderr.h"#include          "memryerr.h"#include          "hashfn.h"#include          "tprintf.h"#include          "memry.h"#include          "memblk.h"#ifdef __UNIX__#include          <signal.h>#endifclass UWREC{  public:    unsigned cur_frsize;         //frame size    unsigned cursp;              //stack    unsigned currls;             //pc space    unsigned currlo;             //pc offset    unsigned curdp;              //data pointer    unsigned toprp;              //rp    unsigned topmrp;             //mrp    unsigned topsr0;             //sr0    unsigned topsr4;             //sr4    unsigned r3;                 //gr3    unsigned cur_r19;            //gr19};MEMUNION *free_block = NULL;     //head of freelist#define EXTERNEXTERN MEM_ALLOCATOR big_mem;EXTERN MEM_ALLOCATOR main_mem;                                 //heads of freelistsEXTERN MEMUNION *free_structs[MAX_STRUCTS];                                 //number issuedEXTERN INT32 structs_in_use[MAX_STRUCTS];                                 //number issuedEXTERN INT32 blocks_in_use[MAX_STRUCTS];                                 //head of block listsEXTERN MEMUNION *struct_blocks[MAX_STRUCTS];EXTERN const char *owner_names[MAX_STRUCTS][MAX_CLASSES];EXTERN INT32 owner_counts[MAX_STRUCTS][MAX_CLASSES];                                 //no of namesEXTERN INT16 name_counts[MAX_STRUCTS];EXTERN INT32 free_struct_blocks; //no of free blocksEXTERN INT_VAR (mem_mallocdepth, 0, "Malloc stack depth to trace");EXTERN INT_VAR (mem_mallocbits, 8, "Log 2 of hash table size");EXTERN INT_VAR (mem_freedepth, 0, "Free stack dpeth to trace");EXTERN INT_VAR (mem_freebits, 8, "Log 2 of hash table size");EXTERN INT_VAR (mem_countbuckets, 16, "No of buckets for histogram");EXTERN INT_VAR (mem_checkfreq, 0, "Calls to alloc_mem between owner counts");/********************************************************************** * MEM_ALLOCATOR::MEM_ALLOCATOR * * Constructor for a memory allocator. **********************************************************************/voidMEM_ALLOCATOR::init (            //initializevoid *(*ext_malloc) (INT32),     //external sourcevoid (*ext_free) (void *),       //external freeINT32 firstsize,                 //size of first blockINT32 lastsize,                  //size of last blockINT32 maxchunk                   //biggest request) {  blockcount = 0;  malloc_serial = 0;  topblock = NULL;  currblock = NULL;  callers = NULL;  malloc = ext_malloc;  free = ext_free;  maxsize = lastsize;  biggestblock = maxchunk;  totalmem = 0;  memsize = firstsize;  malloc_div_ratio = 1;  malloc_minor_serial = 0;  malloc_auto_count = 0;  call_bits = 0;  entries = 0;}/********************************************************************** * MEM_ALLOCATOR::hash_caller * * Generate a hash code for a caller, setup the tables if necessary. **********************************************************************/UINT16 MEM_ALLOCATOR::hash_caller(            //get hash code                                  void *addr  //return address                                 ) {  INT32 index;                   //index to table  INT32 initial_hash;            //initial index  if (callers == NULL)    init_callers();  //setup table                                 //get hash code  initial_hash = hash (call_bits, &addr, sizeof (addr));  if (initial_hash == 0)    initial_hash = 1;  index = initial_hash;  if (callers[index].caller != NULL && callers[index].caller != addr) {    do {      index++;      if (index >= entries)        index = 1;    }    while (callers[index].caller != NULL      && callers[index].caller != addr && index != initial_hash);    if (index == initial_hash)      index = 0;  }  if (callers[index].caller == NULL) {    if (index != 0)      callers[index].caller = addr;    if (callers[index].free_list == NULL)                                 //setup free table      callers[index].init_freeers ();  }  return (UINT16) index;}/********************************************************************** * MALLOC_CALL::count_freeer * * Generate a hash code for a freeer, setup the tables if necessary. * Then count the call. **********************************************************************/void MALLOC_CALL::count_freeer(            //count calls to free                               void *addr  //return address                              ) {  INT32 entries;                 //entries in table  INT32 index;                   //index to table  INT32 initial_hash;            //initial index  if (free_list == NULL)    init_freeers();  //setup table  entries = 1 << free_bits;                                 //get hash code  initial_hash = hash (free_bits, &addr, sizeof (addr));  if (initial_hash == 0)    initial_hash = 1;  index = initial_hash;  if (free_list[index].freeer != NULL && free_list[index].freeer != addr) {    do {      index++;      if (index >= entries)        index = 1;    }    while (free_list[index].freeer != NULL      && free_list[index].freeer != addr && index != initial_hash);    if (index == initial_hash)      index = 0;  }  if (free_list[index].freeer == NULL && index != 0) {    free_list[index].freeer = addr;  }  free_list[index].count++;      //count them}/********************************************************************** * MEM_ALLOCATOR::init_callers * * Initialize the callers hash table. **********************************************************************/void MEM_ALLOCATOR::init_callers() {  //setup hash table  INT32 depth = mem_mallocdepth;  mem_mallocdepth.set_value (0); //can't register it  call_bits = mem_mallocbits;  entries = 1 << call_bits;                                 //make an array  callers = new MALLOC_CALL[entries];  mem_mallocdepth.set_value (depth);}/********************************************************************** * MALLOC_CALL::init_freeers * * Initialize the freeers hash table. **********************************************************************/void MALLOC_CALL::init_freeers() {  //setup hash table  INT32 entries;                 //entries in table  INT32 depth = mem_mallocdepth;  mem_mallocdepth.set_value (0); //can't register it  free_bits = mem_freebits;  entries = 1 << free_bits;                                 //make an array  free_list = new FREE_CALL[entries];  mem_mallocdepth.set_value (depth);}/********************************************************************** * MEM_ALLOCATOR::reduce_counts * * Divide all ages by 2 to get a log use of counts. **********************************************************************/void MEM_ALLOCATOR::reduce_counts() {  //divide by 2  MEMBLOCK *block;               //current block  MEMUNION *chunk;               //current chunk  INT32 chunksize;               //size of chunk  INT32 blockindex;              //index of block  check_mem ("Reducing counts", JUSTCHECKS);  for (blockindex = 0; blockindex < blockcount; blockindex++) {                                 //current block    block = &memblocks[blockindex];                                 //scan all chunks    for (chunk = block->blockstart; chunk != block->blockend; chunk += chunksize) {      chunksize = chunk->size;   //size of chunk      if (chunksize < 0)        chunksize = -chunksize;  //absolute size      chunk->age /= 2;           //divide ages    }  }}/********************************************************************** * MEM_ALLOCATOR::display_counts * * Send counts of outstanding blocks to stderr. **********************************************************************/void MEM_ALLOCATOR::display_counts() {  //count up  MEMBLOCK *block;               //current block  MEMUNION *chunk;               //current chunk  INT32 chunksize;               //size of chunk  INT32 blockindex;              //index of block  INT32 buckets;                 //required buckets  INT32 bucketsize;              //no in each bucket  INT32 callindex;               //index to callers  INT32 freeindex;               //index to freeers  INT32 freeentries;             //table size  INT32 totalchunks;             //total chunk counts  INT32 totalspace;              //total mem space  INT32 totalpchunks;            //permanent chunks  INT32 totalpspace;             //permanent space  INT32 totalfrees;              //total free calls  if (callers == NULL)    return;                      //can't do anything  check_mem ("Displaying counts", JUSTCHECKS);  buckets = mem_countbuckets;  bucketsize = (malloc_serial - 1) / buckets + 1;  tprintf ("\nEach bucket covers %g counts.\n",    (double) bucketsize * malloc_div_ratio);  for (callindex = 0; callindex < entries; callindex++) {    if (callers[callindex].free_list != NULL) {      callers[callindex].counts =        (INT32 *) malloc (buckets * 4 * sizeof (INT32));      memset (callers[callindex].counts, 0,        (size_t) (buckets * 4 * sizeof (INT32)));    }  }  for (blockindex = 0; blockindex < blockcount; blockindex++) {                                 //current block    block = &memblocks[blockindex];                                 //scan all chunks    for (chunk = block->blockstart; chunk != block->topchunk; chunk += chunksize) {      chunksize = chunk->size;   //size of chunk      if (chunksize < 0) {        chunksize = -chunksize;  //absolute size        callindex = chunk->owner;        if (callers[callindex].counts != NULL) {          callers[callindex].counts[chunk->age / bucketsize * 4]++;          callers[callindex].counts[chunk->age / bucketsize * 4 +            1] += chunksize;        }      }    }                                 //scan all chunks    for (; chunk != block->blockend; chunk += chunksize) {      chunksize = chunk->size;   //size of chunk      if (chunksize < 0) {        chunksize = -chunksize;  //absolute size        callindex = chunk->owner;        if (callers[callindex].counts != NULL) {          callers[callindex].counts[chunk->age / bucketsize * 4 +            2]++;          callers[callindex].counts[chunk->age / bucketsize * 4 +            3] += chunksize;        }      }    }  }  for (callindex = 0; callindex < entries; callindex++) {    if (callers[callindex].counts != NULL) {      for (totalspace = 0, totalchunks = 0, totalpspace =        0, totalpchunks = 0, freeindex = 0; freeindex < buckets;      freeindex++) {        totalchunks += callers[callindex].counts[freeindex * 4];        totalspace += callers[callindex].counts[freeindex * 4 + 1];        totalpchunks += callers[callindex].counts[freeindex * 4 + 2];        totalpspace += callers[callindex].counts[freeindex * 4 + 3];      }      freeentries = 1 << callers[callindex].free_bits;      for (totalfrees = 0, freeindex = 0; freeindex < freeentries;        freeindex++)      totalfrees += callers[callindex].free_list[freeindex].count;      if (totalspace != 0 || totalfrees != 0) {        tprintf ("alloc_mem at %d : total held=%d(%d), frees=%d.\n",          callers[callindex].caller,          totalchunks, totalspace * sizeof (MEMUNION),          totalfrees);      }      if (totalspace > 0) {        for (freeindex = 0; freeindex < buckets; freeindex++) {          tprintf ("%d(%d) ",            callers[callindex].counts[freeindex * 4],            callers[callindex].counts[freeindex * 4 +            1] * sizeof (MEMUNION));        }        tprintf ("\n");      }      if (totalfrees != 0) {        tprintf ("Calls to free : ");        for (freeindex = 0; freeindex < freeentries; freeindex++) {          if (callers[callindex].free_list[freeindex].count != 0)            tprintf ("%d : %d ",              callers[callindex].free_list[freeindex].freeer,              callers[callindex].free_list[freeindex].count);        }        tprintf ("\n");      }      if (totalpspace != 0) {        tprintf ("alloc_mem_p at %d : total held=%d(%d).\n",          callers[callindex].caller,          totalpchunks, totalpspace * sizeof (MEMUNION));        for (freeindex = 0; freeindex < buckets; freeindex++) {          tprintf ("%d(%d) ",            callers[callindex].counts[freeindex * 4 + 2],            callers[callindex].counts[freeindex * 4 +            3] * sizeof (MEMUNION));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -