You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

398 lines
9.5 KiB
C++

2 years ago
/************************************************************************
*
* Copyright (C) 2003-2004
* Shenzhen SCADA Control Technology Co., Ltd.
* All rights reserved.
*
*
2 years ago
*
* : 2005/04/12
2 years ago
*
***********************************************************************/
/*#ifdef OS_LINUX
#include <sys/types.h>
#include <sys/time.h>
#endif*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <errno.h>
#include "time.h"
#include "list_entry.h"
#include "os_heap.h"
#if defined(_WIN32)
2 years ago
#include <winsock2.h>
#include <direct.h>
#include <process.h>
#endif
2 years ago
#ifdef _fclose
#undef _fclose
#endif
#define _fclose(_fp) do {if (_fp) {while (EOF == fclose((_fp)) && EINTR == errno);}} while(0)
/*!
*
2 years ago
*/
typedef enum {
eMalloc = 0, /* 使用malloc分配的内存块 */
eCalloc = 1 /* 使用calloc分配的内存块 */
2 years ago
} heap_type_t;
/*!
*
2 years ago
*
* \note
* 16
2 years ago
*/
typedef struct tag_heap_head_t {
/* 堆内存块附加头所在的链表的占位 */
2 years ago
list_entry_t anchor;
/*! 堆内存块分配发生的时间 */
2 years ago
struct timeval tv;
/*! 堆内存块类型 */
2 years ago
heap_type_t type;
/*! 堆内存块分配发生的源文件名NULL表示匿名源文件。 */
2 years ago
char * fl;
/*! 堆内存块分配发生的源代码行 */
2 years ago
int line;
/*! 堆内存块的尺寸(字节) */
2 years ago
size_t size;
} heap_list_t;
/* 边界对齐量 */
2 years ago
#define os_heap_alignment 16
#define os_heap_pad ((sizeof(heap_list_t) % os_heap_alignment) ? (os_heap_alignment - (sizeof(heap_list_t) % os_heap_alignment)) : 0)
/* 根据数据地址求os_heap块的起始地址 */
2 years ago
#define os_heap_start_addr(_data) ((void *)(((unsigned char *)(_data)) - sizeof(heap_list_t) - os_heap_pad))
/* 根据os_heap块的起始地址求数据地址 */
2 years ago
#define os_heap_data_addr(_start) ((void *)(((unsigned char *)(_start)) + sizeof(heap_list_t) + os_heap_pad))
/* 根据数据块的尺寸求os_heap块的尺寸 */
2 years ago
#define os_heap_mb_size(_size) (sizeof(heap_list_t) + os_heap_pad + (_size))
/*
*
2 years ago
*
* 1.
* 2. 线
* 3.
* 4. 访
2 years ago
*/
/* 堆内存块设施是否已经初始化 */
2 years ago
static int g_heap_initialized = 0;
/* 堆内存块双向链表头 */
2 years ago
static list_entry_t g_heap_head;
/*
* 使heap_malloc/heap_calloc
* 使
2 years ago
*/
static size_t g_heap_item_counter = 0;
/*
* 使heap_malloc/heap_calloc
* 使()
2 years ago
*/
static size_t g_heap_byte_counter = 0;
/* 初始化堆内存块设施 */
2 years ago
static void heap_intialize();
/*!
* \brief
2 years ago
*
* \param size
* \param file null
* NULL (anony)
* \param line
2 years ago
*
* \retutrn
*
* NULL
2 years ago
*
* \note
* 使heap_free
2 years ago
*
* ANSI C malloc
2 years ago
*/
void * heap_malloc (
size_t size,
const char * file,
int line )
{
// #ifdef DISABLE_OS_HEAP
return malloc(size);
/*#else /* #ifdef DISABLE_OS_HEAP */
/*
struct timeval tv;
char * fl = NULL;
void * mb = NULL;
heap_list_t * hl = NULL;
if (0 == size)
return NULL;
if (file) {
fl = (char *)malloc(strlen(file) + 4);
if (fl) strcpy (fl, file);
}
gettimeofday(&tv, NULL);
mb = malloc(os_heap_mb_size(size));
if (NULL == mb) {
if (fl) free (fl);
return mb;
} else {
memset (mb, 0, os_heap_mb_size(size));
}
hl = (heap_list_t *)mb;
hl->type = eMalloc;
hl->tv = tv;
hl->fl = fl;
hl->line = line;
hl->size = size;
if (!g_heap_initialized) {
heap_intialize();
g_heap_initialized = 1;
}
insert_tail_list (&g_heap_head, &(hl->anchor));
g_heap_item_counter++;
g_heap_byte_counter += hl->size;
return os_heap_data_addr(hl);
#endif *//* #ifdef DISABLE_OS_HEAP */
}
/*!
* \brief , 0.
2 years ago
*
* \param num
* \param elm_size ()
* \param file null
* NULL (anony)
* \param line
2 years ago
*
* \retutrn
*
* NULL
2 years ago
*
* \note
* 使heap_free
2 years ago
*
* ANSI C calloc calloc
* callocelm_size
*
2 years ago
*/
void * heap_calloc (
size_t num,
size_t elm_size,
const char * file,
int line )
{
//#ifdef DISABLE_OS_HEAP
return calloc(num, elm_size);
//#else /* #ifdef DISABLE_OS_HEAP */
/* struct timeval tv;
char * fl = NULL;
void * mb = NULL;
heap_list_t * hl = NULL;
if (0 == num * elm_size)
return NULL;
if (file) {
fl = (char *)malloc(strlen(file) + 4);
if (fl) strcpy (fl, file);
}
gettimeofday(&tv, NULL);
mb = malloc(os_heap_mb_size(elm_size * num));
if (NULL == mb) {
if (fl) free (fl);
return mb;
} else {
memset (mb, 0, os_heap_mb_size(elm_size * num));
}
hl = (heap_list_t *)mb;
hl->type = eCalloc;
hl->tv = tv;
hl->fl = fl;
hl->line = line;
hl->size = elm_size * num;
if (!g_heap_initialized) {
heap_intialize();
g_heap_initialized = 1;
}
insert_tail_list (&g_heap_head, &(hl->anchor));
g_heap_item_counter++;
g_heap_byte_counter += hl->size;
return os_heap_data_addr(hl);
#endif *//* #ifdef DISABLE_OS_HEAP */
}
/*!
* \brief
2 years ago
*
* \param memblock heap_alloc/heap_calloc
2 years ago
*
* \return
*
2 years ago
*/
void heap_free (void * mb)
{
#ifdef DISABLE_OS_HEAP
free (mb);
#else /* #ifdef DISABLE_OS_HEAP */
size_t sz = 0;
heap_list_t * hl = NULL;
if (NULL == mb)
return;
if (!g_heap_initialized) {
heap_intialize();
g_heap_initialized = 1;
return;
}
hl = (heap_list_t *)os_heap_start_addr(mb);
#if defined(WIN32) && (defined(DEBUG) || defined(_DEBUG))
if (IsBadReadPtr((void *)hl, sizeof(heap_list_t))) {
return;
}
if (IsBadReadPtr((void *)hl, os_heap_mb_size(hl->size))) {
return;
}
#endif
remove_entry_list (&(hl->anchor));
sz = hl->size;
if (hl->fl)
free ((void *)(hl->fl));
free ((void *)hl);
g_heap_item_counter--;
g_heap_byte_counter -= sz;
#endif /* #ifdef DISABLE_OS_HEAP */
}
/*!
* \brief
2 years ago
*
*
2 years ago
*
* \param fname fnameNULL
*
2 years ago
*
* \retval -1
* \retval 0
2 years ago
*
* \note
*
* :
* 使:
2 years ago
* ......
* i:
* : tv
* : malloc/calloc,
* : fl(line)
* : size
2 years ago
* ......
*/
int heap_report(const char * fname)
{
/* #ifndef DISABLE_OS_HEAP
int i = 0;
FILE * fp = NULL;
heap_list_t * hl = NULL;
list_entry_t * item = NULL;
list_entry_t * first = NULL;
list_entry_t * next = NULL;
char szdt[32];
if (fname) {
fp = fopen (fname, "a+t");
if (NULL == fp)
return -1;
} else
fp = stdout;
if (!g_heap_initialized) {
heap_intialize();
g_heap_initialized = 1;
if (fname) _fclose(fp);
return 0;
}
fprintf (fp, "\n"
"heap allocation summary...\n"
"time: %s\n"
"heap_item_counter: %u\n"
"heap_byte_counter: %u(bytes)\n",
cur_tm_string (szdt),
g_heap_item_counter,
g_heap_byte_counter);
first = &g_heap_head;
for ( next = first->flink; next != first; next = next->flink )
{
item = next;
hl = CONTAINING_RECORD ( item, heap_list_t, anchor );
fprintf (fp, " heap block %d:"
" times: %s"
" type: %s"
" size: %08u (bytes)"
" source: %s [%d]\n",
i++, timeval_string(&(hl->tv), szdt),
(eMalloc == hl->type ? "malloc" : "calloc"),
hl->size, (hl->fl ? hl->fl : "nony"), hl->line);
}
if (fname) _fclose(fp);
#endif*/
return 0;
}
static void heap_intialize()
{
Initialize_list_head (&g_heap_head);
}