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

📄 aug_alloc.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
字号:
/* * $Id: aug_alloc.c,v 1.1.10.3 2005/07/20 17:26:16 andrei Exp $ * * POSTGRES module, portions of this code were templated using * the mysql module, thus it's similarity. * * * Copyright (C) 2003 August.Net Services, LLC * * This file is part of ser, a free SIP server. * * ser is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * * For a license to use the ser software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: *    info@iptel.org * * ser is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License  * along with this program; if not, write to the Free Software  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * --- * * History * ------- * 2003-04-06 initial code written (Greg Fausak/Andy Fullford) * *//*** ________________________________________________________________________******                      $RCSfile: aug_alloc.c,v $**                     $Revision: 1.1.10.3 $****             Last change $Date: 2005/07/20 17:26:16 $**           Last change $Author: andrei $**                        $State: Exp $**                       $Locker:  $****               Original author: Andrew Fullford****           Copyright (C) August Associates  1995**** ________________________________________________________________________*/#include "aug_std.h"#include <stdlib.h>#include <stdio.h>#include <string.h>typedef double MemAlign;typedef augUInt32 MemMagic;typedef union MemHead MemHead;typedef struct MemOpt MemOpt;typedef struct MemDestructor MemDestructor;	/* not yet implemented *//***  One of these MemHead structs is allocated at the head of**  each alloc, plus an extra magic number at the end area.**  This gives an allocation overhead of:****	malloc_overhead + sizeof MemHead + sizeof MemMagic****  "Notes" entry for the man page: the allocation overhead is way**  too high.  (On a 32bit machine and assuming a malloc overhead**  of 8 bytes, the total will be 8 + 32 + 4 = 44 bytes).*/struct MemHeadStruct{	MemHead *parent, *sibling, *child;	MemOpt *options;	char *end;	char *file;	augUInt32 line;	MemMagic magic;};/***  Attempt to guarantee alignment.*/union MemHead{	struct MemHeadStruct m;	MemAlign align[1];};/***  MemOpt holds optional features.  The only current example**  is the memory destructor state.*/struct MemOpt{	MemMagic magic;	MemDestructor *destructor_list;};/***  These magic numbers are used to validate headers, force memory**  to a known state, etc.*/#define MEM_MAGIC_BOUND	0xC0EDBABE#define MEM_MAGIC_FILL	0xDEADC0DEstatic int mem_bad(MemHead *mem, char *where, char *file, int line){	aug_abort(file, line, "Corrupted memory in %s", where);	return 0;}/***  Calculate the MemHead address given an aug_alloc() pointer.*/#define MEM_CROWN(alloc) ((MemHead *)(((char *)alloc) - sizeof (MemHead)))#define MEM_DECAPITATE(mem) ((void *)(((char *)mem) + sizeof (MemHead)))static MemMagic mem_magic = MEM_MAGIC_BOUND;#define MEM_TAIL(p) (memcmp((p)->m.end,(char*)&mem_magic,sizeof mem_magic)==0)#define MEM_CHECK(p,w) ((p) && \			((p)->m.magic != MEM_MAGIC_BOUND || !MEM_TAIL(p)) && \			mem_bad((p),(w),file,line))/*  Initialize stats structure with estimated overhead */static augAllocStats mem_stats = {sizeof (MemHead) + sizeof (MemMagic) + 8, 0};static augNoMemFunc *mem_nomem_func = 0;static void mem_nomem(size_t size, char *func, char *file, int line){	static augBool active = augFALSE;	char *module;	if(!func)		func = "unknown function";	if(active)		fprintf(stderr, "\r\n\nPANIC: nomem bounce\r\n\n");	else	{		active = augTRUE;		if(mem_nomem_func)			(*mem_nomem_func)(size, func, file, line);	}	fprintf(stderr, "\r\n\n");	module = aug_module();	if(module && *module)		fprintf(stderr, "FATAL in %s: ", module);	else		fprintf(stderr, "FATAL: ");	fprintf(stderr, "%s failure allocating %lu bytes ", func, 			(unsigned long)size);	if(file && *file)		fprintf(stderr, "from +%d %s \r\n", line, file);	else		fprintf(stderr, "(unknown location) \r\n");	fprintf(stderr, "              Current allocations: %10lu \r\n",		(mem_stats.alloc_ops - mem_stats.free_ops));	fprintf(stderr, "                Total allocations: %10lu \r\n",		mem_stats.alloc_ops);	fprintf(stderr, "              Total reallocations: %10lu \r\n",		mem_stats.realloc_ops);	fprintf(stderr, "                      Total frees: %10lu \r\n",		mem_stats.free_ops);	fprintf(stderr, "Estimated total heap use (KBytes): %10lu \r\n",		(mem_stats.current_bytes_allocated +		(mem_stats.alloc_ops - mem_stats.free_ops) *		mem_stats.estimated_overhead_per_alloc + 512)/1024);	fprintf(stderr, "\n");			aug_exit(augEXIT_NOMEM);}static void *mem_alloc(size_t size, void *parent, char *file, int line){	MemHead *mem, *par;	DABNAME("mem_alloc");	if(parent)	{		par = MEM_CROWN(parent);		MEM_CHECK(par, "parent");		MEM_CHECK(par->m.child, "sibling");		MEM_CHECK(par->m.sibling, "uncle");	}	else		par = 0;	mem_stats.current_bytes_allocated += size;	mem_stats.alloc_ops++;	/*  Adjust for overhead  */	size += sizeof (MemHead);	mem = malloc(size + sizeof (MemMagic));	if(!mem)		mem_nomem(size, "aug_alloc", file, line);	if(DABLEVEL(DAB_STD))	{		unsigned long *p;		p = (unsigned long *)mem;		while((char *)p <= (char *)mem + size)			*p++ = MEM_MAGIC_FILL;	}	mem->m.magic = MEM_MAGIC_BOUND;	mem->m.file = file;	mem->m.line = line;	mem->m.end = (char *)mem + size;	mem->m.options = 0;	mem->m.child = 0;	mem->m.parent = par;	if(par)	{		if((mem->m.sibling = par->m.child))			mem->m.sibling->m.parent = mem;		par->m.child = mem;	}	else		mem->m.sibling = 0;	memcpy(mem->m.end, (char *)&mem_magic, sizeof mem_magic);	return MEM_DECAPITATE(mem);}static void mem_free(MemHead *mem){	size_t size;	DABNAME("mem_free");	while(mem)	{		MemHead *next = mem->m.sibling;		if(mem->m.child)			mem_free(mem->m.child);		size = (char *)mem->m.end - (char *)mem;		size -= sizeof (MemHead) + sizeof (MemMagic);		mem_stats.current_bytes_allocated -= size;		mem_stats.free_ops++;		if(DABLEVEL(DAB_STD))		{			unsigned long *p = (unsigned long *)(mem+1);			while((char *)p <= mem->m.end)				*p++ = MEM_MAGIC_FILL;			p = (unsigned long *)mem;			while(p < (unsigned long *)(mem+1))				*p++ = MEM_MAGIC_FILL;		}		free(mem);		mem = next;	}}static augBool mem_find(MemHead *mem, MemHead *p){	while(mem)	{		MemHead *next;		if(mem == p)			return augTRUE;		next = mem->m.sibling;		if(mem->m.child)			if(mem_find(mem->m.child, p))				return augTRUE;		mem = next;	}	return augFALSE;}augExport augNoMemFunc *aug_set_nomem_func(augNoMemFunc *new_func){	augNoMemFunc *old = mem_nomem_func;	DABNAME("aug_set_nomem_func");	mem_nomem_func = new_func;	DABTRACE("New nomem func %08lx, previous %08lx",		(unsigned long)mem_nomem_func, (unsigned long)old);	return old;}augExport augAllocStats *aug_alloc_stats(void){	return &mem_stats;}augExport void *aug_alloc_loc(size_t size, void *parent, char *file, int line){	void *alloc;	DABNAME("aug_alloc");	DAB("size %lu, parent %08lx [+%d %s]",		(unsigned long)size, (unsigned long)parent, line, file);	alloc = mem_alloc(size, parent, file, line);	DABL(80)("size %lu with header, caller mem at %08lx",		MEM_CROWN(alloc)->m.end - (char *)MEM_CROWN(alloc),		(unsigned long)alloc);	return alloc;}augExport void *aug_realloc_loc(size_t size, void *prev, char *file, int line){	void *alloc;	size_t prev_size;	MemHead *mem, *par, *kid, *sib, *new;	DABNAME("aug_realloc");	if(!prev)		aug_abort(file, line, "Attempt to realloc a NULL pointer");	mem = MEM_CROWN(prev);	MEM_CHECK(mem, "previous alloc");	par = mem->m.parent;	MEM_CHECK(par, "realloc parent");	kid = mem->m.child;	MEM_CHECK(kid, "realloc child");	sib = mem->m.sibling;	MEM_CHECK(sib, "realloc sibling");	prev_size = (mem->m.end - (char *)mem) - sizeof (MemHead);	DAB("prior size %lu, new %lu [+%d %s]",				(unsigned long)prev_size, (unsigned long)size,				line, file);	DABL(80)("prior mem %08lx", (unsigned long)mem);	mem_stats.current_bytes_allocated += size - prev_size;	mem_stats.realloc_ops++;	size += sizeof (MemHead);	new = realloc(mem, size + sizeof (MemMagic));	if(!new)		mem_nomem(size, "aug_realloc", file, line);	new->m.end = (char *)new + size;	memcpy(new->m.end, (char *)&mem_magic, sizeof mem_magic);	if(par)	{		if(par->m.sibling == mem)			par->m.sibling = new;		else			par->m.child = new;	}	if(kid)		kid->m.parent = new;	if(sib)		sib->m.parent = new;	alloc = MEM_DECAPITATE(new);	DABL(80)("size %lu with header, caller mem at %08lx",			new->m.end - (char *)new, (unsigned long)alloc);	return alloc;}augExport void aug_free_loc(const void *alloc, char *file, int line){	MemHead *mem, *par;	DABNAME("aug_free");	if(!alloc)		aug_abort(file, line, "Attempt to free a NULL pointer");	DAB("Freeing %08lx [+%d %s]", (unsigned long)alloc, line, file);	mem = MEM_CROWN(alloc);	MEM_CHECK(mem, "alloc to free");	par = mem->m.parent;	MEM_CHECK(par, "parent in free");	if(par)	{		if(par->m.sibling == mem)			par->m.sibling = mem->m.sibling;		else			par->m.child = mem->m.sibling;	}	if(mem->m.sibling)	{		mem->m.sibling->m.parent = par;		mem->m.sibling = 0;	}	mem_free(mem);}augExport void aug_foster_loc(void *alloc, void *parent, char *file, int line){	MemHead *mem, *fpar, *ppar, *sib;	DABNAME("aug_foster");	DAB("Foster %08lx to %08lx [+%d %s]",						alloc, parent, line, file);	if(!alloc)		aug_abort(file, line, "Attempt to foster a NULL pointer");	mem = MEM_CROWN(alloc);	MEM_CHECK(mem, "alloc to foster");	if(parent)	{		fpar = MEM_CROWN(parent);		MEM_CHECK(fpar, "foster parent");	}	else		fpar = 0;	ppar = mem->m.parent; MEM_CHECK(ppar, "prior parent");	sib = mem->m.sibling; MEM_CHECK(ppar, "sibling in foster");	if(fpar == ppar)	{		DABTRACE("No change in parent (%08lx)", (unsigned long)fpar);		return;	}	if(mem == fpar)		aug_abort(file, line, "Attempt to adopt self");	/*	**  Check for incest - isnew parent actually our child?	*/	if(mem_find(mem->m.child, fpar))		aug_abort(file, line, "Attempt to adopt a parent");	/*	**  Leave home.	*/	if(!ppar)	{		DABBULK("Leaving orphanage");		if(mem->m.sibling)			mem->m.sibling->m.parent = 0;	}	else if(ppar->m.sibling == mem)	{		DABBULK("Older child");		ppar->m.sibling = mem->m.sibling;		if(ppar->m.sibling)			ppar->m.sibling->m.parent = ppar;	}	else	{		DABBULK("Youngest child");		ppar->m.child = mem->m.sibling;		if(ppar->m.child)			ppar->m.child->m.parent = ppar;	}	/*	**  Find new home.	*/	mem->m.parent = fpar;	if(fpar)	{		mem->m.sibling = fpar->m.child;		fpar->m.child = mem;		if(mem->m.sibling)			mem->m.sibling->m.parent = mem;	}	else		mem->m.sibling = 0;}augExport char *aug_strdup_loc(const char *str, void *parent, char *file,								int line){	char *new;	size_t size;	DABNAME("aug_strdup");	if(!str)		aug_abort(file, line, "Attempt to duplicate a NULL string");	size = strlen(str)+1;	DAB("string length %lu [+%d %s]", (unsigned long)size, line, file);	new = mem_alloc(size, parent, file, line);	DABL(80)("size %lu with header, caller mem at %08lx",		MEM_CROWN(new)->m.end - (char *)MEM_CROWN(new),		(unsigned long)new);	strcpy(new, str);	return new;}augExport char **aug_vecdup_loc(char **vec, void *parent, char *file, int line){	char **nv, **v, *c;	size_t size;	int vsize;	DABNAME("aug_vecdup");	if(!vec)		aug_abort(file, line, "Attempt to duplicate a NULL vector");	size = 0;	for(v = vec; *v; v++)		size += strlen(*v) + 1;	vsize = v - vec;	DABL(80)("%d elements, total string size %d", vsize, size);	vsize++;	nv = (char **)mem_alloc(vsize * sizeof *v + size, parent, file, line);	c = (char *)(nv + vsize);	for(v = nv; *vec; v++, vec++)	{		strcpy(c, *vec);		*v = c;		c += strlen(c) + 1;	}	*v = 0;	return nv;}#ifdef TESTstatic void nomem(size_t size, char *func, char *file, int line){	fprintf(stderr, "\nNOMEM on %lu bytes via %s, called from %s line %d\n",		(unsigned long)size, func, file, line);	/*	**  Normally would exit from here, but might as well test the	**  default trap.	*/	return;}main(int argc, char **argv){	int i;	void *par;	char *mem, *m, **v;	aug_setmodule(argv[0]);	printf("<MemHead size %lu> should equal <struct MemHead %lu>\n",		sizeof (MemHead), sizeof (struct MemHead));	par = aug_alloc(20, 0);	for(i = 0; i < 20; i++)	{		if(i == 10)			mem = aug_strdup("Hello, world\n", par);		else			(void)aug_alloc(3000, par);	}	mem = aug_realloc(10000, mem);	for(i = 0; i < 20; i++)	{		if(i == 10)			m = aug_strdup("Hello, world\n", mem);		else			(void)aug_alloc(3000, par);	}	v = aug_vecdup(argv, par);	printf("Program args:");	while(*v)	{		printf(" %s", *v++);		fflush(stdout);	}	printf("\n");	aug_foster(m, par);	if(argc > 1)	{		printf("Checking anti-incest test ... this should abort\n");		aug_foster(par, mem);	}	for(i = 0; i < 20; i++)	{		if(i == 10)			m = aug_strdup("Hello, world\n", mem);		else			(void)aug_alloc(3000, mem);	}	mem = aug_realloc(10000, mem);	aug_foster(m, par);	aug_free(mem);	printf("If you can read this, the test completed ok\n");	printf("Now testing NOMEM func - this should abort after a while ... ");	fflush(stdout);	aug_set_nomem_func(nomem);	while(m = aug_alloc(128*1024, par))		continue;	/* Should never get to here */	aug_free(par);	aug_exit(augEXIT_YES);}#endif

⌨️ 快捷键说明

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