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

📄 alloc.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* alloc.c   Functions supporting memory allocation for the object management   protocol... *//* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1999-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * *   Internet Systems Consortium, Inc. *   950 Charter Street *   Redwood City, CA 94063 *   <info@isc.org> *   http://www.isc.org/ * * This software has been written for Internet Systems Consortium * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc. * To learn more about Internet Systems Consortium, see * ``http://www.isc.org/''.  To learn more about Vixie Enterprises, * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see * ``http://www.nominum.com''. */#include <omapip/omapip_p.h>#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \		defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)struct dmalloc_preamble *dmalloc_list;unsigned long dmalloc_outstanding;unsigned long dmalloc_longterm;unsigned long dmalloc_generation;unsigned long dmalloc_cutoff_generation;#endif#if defined (DEBUG_RC_HISTORY)struct rc_history_entry rc_history [RC_HISTORY_MAX];int rc_history_index;int rc_history_count;#endif#if defined (DEBUG_RC_HISTORY)static void print_rc_hist_entry (int);#endifVOIDPTR dmalloc (size, file, line)	unsigned size;	const char *file;	int line;{	unsigned char *foo = malloc (size + DMDSIZE);	int i;	VOIDPTR *bar;#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \		defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)	struct dmalloc_preamble *dp;#endif	if (!foo)		return (VOIDPTR)0;	bar = (VOIDPTR)(foo + DMDOFFSET);	memset (bar, 0, size);#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \		defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)	dp = (struct dmalloc_preamble *)foo;	dp -> prev = dmalloc_list;	if (dmalloc_list)		dmalloc_list -> next = dp;	dmalloc_list = dp;	dp -> next = (struct dmalloc_preamble *)0;	dp -> size = size;	dp -> file = file;	dp -> line = line;	dp -> generation = dmalloc_generation++;	dmalloc_outstanding += size;	for (i = 0; i < DMLFSIZE; i++)		dp -> low_fence [i] =			(((unsigned long)			  (&dp -> low_fence [i])) % 143) + 113;	for (i = DMDOFFSET; i < DMDSIZE; i++)		foo [i + size] =			(((unsigned long)			  (&foo [i + size])) % 143) + 113;#if defined (DEBUG_MALLOC_POOL_EXHAUSTIVELY)	/* Check _every_ entry in the pool!   Very expensive. */	for (dp = dmalloc_list; dp; dp = dp -> prev) {		for (i = 0; i < DMLFSIZE; i++) {			if (dp -> low_fence [i] !=				(((unsigned long)				  (&dp -> low_fence [i])) % 143) + 113)			{				log_error ("malloc fence modified: %s(%d)",					   dp -> file, dp -> line);				abort ();			}		}		foo = (unsigned char *)dp;		for (i = DMDOFFSET; i < DMDSIZE; i++) {			if (foo [i + dp -> size] !=				(((unsigned long)				  (&foo [i + dp -> size])) % 143) + 113) {				log_error ("malloc fence modified: %s(%d)",					   dp -> file, dp -> line);				abort ();			}		}	}#endif#endif#ifdef DEBUG_REFCNT_DMALLOC_FREE	rc_register (file, line, 0, foo + DMDOFFSET, 1, 0, RC_MALLOC);#endif	return bar;}void dfree (ptr, file, line)	VOIDPTR ptr;	const char *file;	int line;{	if (!ptr) {		log_error ("dfree %s(%d): free on null pointer.", file, line);		return;	}#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \		defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)	{		unsigned char *bar = ptr;		struct dmalloc_preamble *dp, *cur;		int i;		bar -= DMDOFFSET;		cur = (struct dmalloc_preamble *)bar;		for (dp = dmalloc_list; dp; dp = dp -> prev)			if (dp == cur)				break;		if (!dp) {			log_error ("%s(%d): freeing unknown memory: %lx",				   file, line, (unsigned long)cur);			abort ();		}		if (dp -> prev)			dp -> prev -> next = dp -> next;		if (dp -> next)			dp -> next -> prev = dp -> prev;		if (dp == dmalloc_list)			dmalloc_list = dp -> prev;		if (dp -> generation >= dmalloc_cutoff_generation)			dmalloc_outstanding -= dp -> size;		else			dmalloc_longterm -= dp -> size;		for (i = 0; i < DMLFSIZE; i++) {			if (dp -> low_fence [i] !=				(((unsigned long)				  (&dp -> low_fence [i])) % 143) + 113)			{				log_error ("malloc fence modified: %s(%d)",					   dp -> file, dp -> line);				abort ();			}		}		for (i = DMDOFFSET; i < DMDSIZE; i++) {			if (bar [i + dp -> size] !=				(((unsigned long)				  (&bar [i + dp -> size])) % 143) + 113) {				log_error ("malloc fence modified: %s(%d)",					   dp -> file, dp -> line);				abort ();			}		}		ptr = bar;	}#endif#ifdef DEBUG_REFCNT_DMALLOC_FREE	rc_register (file, line,		     0, (unsigned char *)ptr + DMDOFFSET, 0, 1, RC_MALLOC);#endif	free (ptr);}#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \		defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)/* For allocation functions that keep their own free lists, we want to   account for the reuse of the memory. */void dmalloc_reuse (foo, file, line, justref)	VOIDPTR foo;	const char *file;	int line;	int justref;{	struct dmalloc_preamble *dp;	/* Get the pointer to the dmalloc header. */	dp = foo;	dp--;	/* If we just allocated this and are now referencing it, this	   function would almost be a no-op, except that it would	   increment the generation count needlessly.  So just return	   in this case. */	if (dp -> generation == dmalloc_generation)		return;	/* If this is longterm data, and we just made reference to it,	   don't put it on the short-term list or change its name -	   we don't need to know about this. */	if (dp -> generation < dmalloc_cutoff_generation && justref)		return;	/* Take it out of the place in the allocated list where it was. */	if (dp -> prev)		dp -> prev -> next = dp -> next;	if (dp -> next)		dp -> next -> prev = dp -> prev;	if (dp == dmalloc_list)		dmalloc_list = dp -> prev;	/* Account for its removal. */	if (dp -> generation >= dmalloc_cutoff_generation)		dmalloc_outstanding -= dp -> size;	else		dmalloc_longterm -= dp -> size;	/* Now put it at the head of the list. */	dp -> prev = dmalloc_list;	if (dmalloc_list)		dmalloc_list -> next = dp;	dmalloc_list = dp;	dp -> next = (struct dmalloc_preamble *)0;	/* Change the reference location information. */	dp -> file = file;	dp -> line = line;	/* Increment the generation. */	dp -> generation = dmalloc_generation++;	/* Account for it. */	dmalloc_outstanding += dp -> size;}void dmalloc_dump_outstanding (){	static unsigned long dmalloc_cutoff_point;	struct dmalloc_preamble *dp;	unsigned char *foo;	int i;	if (!dmalloc_cutoff_point)		dmalloc_cutoff_point = dmalloc_cutoff_generation;	for (dp = dmalloc_list; dp; dp = dp -> prev) {		if (dp -> generation <= dmalloc_cutoff_point)			break;#if defined (DEBUG_MALLOC_POOL)		for (i = 0; i < DMLFSIZE; i++) {			if (dp -> low_fence [i] !=				(((unsigned long)				  (&dp -> low_fence [i])) % 143) + 113)			{				log_error ("malloc fence modified: %s(%d)",					   dp -> file, dp -> line);				abort ();			}		}		foo = (unsigned char *)dp;		for (i = DMDOFFSET; i < DMDSIZE; i++) {			if (foo [i + dp -> size] !=				(((unsigned long)				  (&foo [i + dp -> size])) % 143) + 113) {				log_error ("malloc fence modified: %s(%d)",					   dp -> file, dp -> line);				abort ();			}		}#endif#if defined (DEBUG_MEMORY_LEAKAGE) || \		defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)		/* Don't count data that's actually on a free list                   somewhere. */		if (dp -> file) {#if defined (DEBUG_RC_HISTORY)			int i, count, inhistory = 0, noted = 0;			/* If we have the info, see if this is actually			   new garbage. */			if (rc_history_count < RC_HISTORY_MAX) {			    count = rc_history_count;			} else			    count = RC_HISTORY_MAX;			i = rc_history_index - 1;			if (i < 0)				i += RC_HISTORY_MAX;			do {			    if (rc_history [i].addr == dp + 1) {				inhistory = 1;				if (!noted) {				    log_info ("  %s(%d): %d", dp -> file,					      dp -> line, dp -> size);				    noted = 1;				}				print_rc_hist_entry (i);				if (!rc_history [i].refcnt)				    break;			    }			    if (--i < 0)				i = RC_HISTORY_MAX - 1;			} while (count--);			if (!inhistory)#endif				log_info ("  %s(%d): %d",					  dp -> file, dp -> line, dp -> size);		}#endif	}	if (dmalloc_list)		dmalloc_cutoff_point = dmalloc_list -> generation;}#endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */#if defined (DEBUG_RC_HISTORY)static void print_rc_hist_entry (int i){	log_info ("   referenced by %s(%d)[%lx]: addr = %lx  refcnt = %x",		  rc_history [i].file, rc_history [i].line,		  (unsigned long)rc_history [i].reference,		  (unsigned long)rc_history [i].addr,		  rc_history [i].refcnt);}void dump_rc_history (void *addr){	int i;	i = rc_history_index;	if (!rc_history [i].file)		i = 0;	else if (rc_history_count < RC_HISTORY_MAX) {		i -= rc_history_count;		if (i < 0)			i += RC_HISTORY_MAX;	}	rc_history_count = 0;			while (rc_history [i].file) {		if (!addr || addr == rc_history [i].addr)			print_rc_hist_entry (i);		++i;		if (i == RC_HISTORY_MAX)			i = 0;		if (i == rc_history_index)			break;	}}void rc_history_next (int d){#if defined (RC_HISTORY_COMPRESSION)	int i, j = 0, m, n = 0;	void *ap, *rp;	/* If we are decreasing the reference count, try to find the	   entry where the reference was made and eliminate it; then	   we can also eliminate this reference. */	if (d) {	    m = rc_history_index - 1000;	    if (m < -1)		m = -1;	    ap = rc_history [rc_history_index].addr;	    rp = rc_history [rc_history_index].reference;	    for (i = rc_history_index - 1; i > m; i--) {		if (rc_history [i].addr == ap) {		    if (rc_history [i].reference == rp) {			if (n > 10) {			    for (n = i; n <= rc_history_index; n++)				    print_rc_hist_entry (n);			    n = 11;			}			memmove (&rc_history [i],				 &rc_history [i + 1],				 (unsigned)((rc_history_index - i) *					    sizeof (struct rc_history_entry)));			--rc_history_count;			--rc_history_index;			for (j = i; j < rc_history_count; j++) {			    if (rc_history [j].addr == ap)				--rc_history [j].refcnt;			}			if (n > 10) {			    for (n = i; n <= rc_history_index; n++)				    print_rc_hist_entry (n);			    n = 11;			    exit (0);			}			return;		    }		}	    }	}#endif	if (++rc_history_index == RC_HISTORY_MAX)		rc_history_index = 0;	++rc_history_count;}#endif#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \		defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)struct caller {	struct dmalloc_preamble *dp;	int count;};static int dmalloc_find_entry (struct dmalloc_preamble *dp,			       struct caller *array,			       int min, int max){	int middle;	int cmp;	middle = (min + max) / 2;	if (middle == min)		return middle;	if (array [middle].dp -> file == dp -> file) {		if (array [middle].dp -> line == dp -> line)			return middle;		else if (array [middle].dp -> line < dp -> line)			return dmalloc_find_entry (dp, array, middle, max);		else			return dmalloc_find_entry (dp, array, 0, middle);	} else if (array [middle].dp -> file < dp -> file)		return dmalloc_find_entry (dp, array, middle, max);	else		return dmalloc_find_entry (dp, array, 0, middle);}void omapi_print_dmalloc_usage_by_caller (){	struct dmalloc_preamble *dp;	unsigned char *foo;	int ccur, cmax, i, j;	struct caller cp [1024];	cmax = 1024;	ccur = 0;	memset (cp, 0, sizeof cp);	for (dp = dmalloc_list; dp; dp = dp -> prev) {		i = dmalloc_find_entry (dp, cp, 0, ccur);		if ((i == ccur ||		     cp [i].dp -> file != dp -> file ||		     cp [i].dp -> line != dp -> line) &&		    ccur == cmax) {			log_error ("no space for memory usage summary.");			return;		}		if (i == ccur) {			cp [ccur++].dp = dp;			cp [i].count = 1;		} else if (cp [i].dp -> file < dp -> file ||			   (cp [i].dp -> file == dp -> file &&			    cp [i].dp -> line < dp -> line)) {			if (i + 1 != ccur)				memmove (cp + i + 2, cp + i + 1,					 (ccur - i) * sizeof *cp);			cp [i + 1].dp = dp;			cp [i + 1].count = 1;			ccur++;		} else if (cp [i].dp -> file != dp -> file ||			   cp [i].dp -> line != dp -> line) {			memmove (cp + i + 1,				 cp + i, (ccur - i) * sizeof *cp);			cp [i].dp = dp;			cp [i].count = 1;			ccur++;		} else			cp [i].count++;#if 0		printf ("%d\t%s:%d\n", i, dp -> file, dp -> line);		dump_rc_history (dp + 1);#endif	}	for (i = 0; i < ccur; i++) {		printf ("%d\t%s:%d\t%d\n", i,			cp [i].dp -> file, cp [i].dp -> line, cp [i].count);		dump_rc_history (cp [i].dp + 1);	}}#endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */isc_result_t omapi_object_allocate (omapi_object_t **o,				    omapi_object_type_t *type,				    size_t size,				    const char *file, int line){	size_t tsize;	omapi_object_t *foo;	isc_result_t status;	if (type -> allocator) {		foo = (omapi_object_t *)0;		status = (*type -> allocator) (&foo, file, line);		tsize = type -> size;	} else		status = ISC_R_NOMEMORY;	if (status == ISC_R_NOMEMORY) {		if (type -> sizer)			tsize = (*type -> sizer) (size);		else			tsize = type -> size;				/* Sanity check. */		if (tsize < sizeof (omapi_object_t))			return ISC_R_INVALIDARG;				foo = dmalloc (tsize, file, line);		if (!foo)			return ISC_R_NOMEMORY;	}	status = omapi_object_initialize (foo, type, size, tsize, file, line);	if (status != ISC_R_SUCCESS) {		if (type -> freer)			(*type -> freer) (foo, file, line);		else			dfree (foo, file, line);		return status;	}	return omapi_object_reference (o, foo, file, line);}isc_result_t omapi_object_initialize (omapi_object_t *o,				      omapi_object_type_t *type,				      size_t usize, size_t psize,				      const char *file, int line){	memset (o, 0, psize);	o -> type = type;	if (type -> initialize)		(*type -> initialize) (o, file, line);	return ISC_R_SUCCESS;}isc_result_t omapi_object_reference (omapi_object_t **r,				     omapi_object_t *h,				     const char *file, int line){	if (!h || !r)		return ISC_R_INVALIDARG;	if (*r) {#if defined (POINTER_DEBUG)		log_error ("%s(%d): reference store into non-null pointer!",			   file, line);		abort ();#else		return ISC_R_INVALIDARG;#endif	}	*r = h;	h -> refcnt++;	rc_register (file, line, r, h, h -> refcnt, 0, h -> type -> rc_flag);

⌨️ 快捷键说明

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