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

📄 mem.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Perform a malloc, doing memory filling and overrun detection as necessary. */static inline void *mem_get(isc_mem_t *ctx, size_t size) {	char *ret;#if ISC_MEM_CHECKOVERRUN	size += 1;#endif	ret = (ctx->memalloc)(ctx->arg, size);	if (ret == NULL)		ctx->memalloc_failures++;	#if ISC_MEM_FILL	if (ret != NULL)		memset(ret, 0xbe, size); /* Mnemonic for "beef". */#else#  if ISC_MEM_CHECKOVERRUN	if (ret != NULL)		ret[size-1] = 0xbe;#  endif#endif	return (ret);}/* * Perform a free, doing memory filling and overrun detection as necessary. */static inline voidmem_put(isc_mem_t *ctx, void *mem, size_t size) {#if ISC_MEM_CHECKOVERRUN	INSIST(((unsigned char *)mem)[size] == 0xbe);#endif#if ISC_MEM_FILL	memset(mem, 0xde, size); /* Mnemonic for "dead". */#else	UNUSED(size);#endif	(ctx->memfree)(ctx->arg, mem);}/* * Update internal counters after a memory get. */static inline voidmem_getstats(isc_mem_t *ctx, size_t size) {	ctx->total += size;	ctx->inuse += size;	if (size > ctx->max_size) {		ctx->stats[ctx->max_size].gets++;		ctx->stats[ctx->max_size].totalgets++;	} else {		ctx->stats[size].gets++;		ctx->stats[size].totalgets++;	}}/* * Update internal counters after a memory put. */static inline voidmem_putstats(isc_mem_t *ctx, void *ptr, size_t size) {	UNUSED(ptr);	INSIST(ctx->inuse >= size);	ctx->inuse -= size;	if (size > ctx->max_size) {		INSIST(ctx->stats[ctx->max_size].gets > 0U);		ctx->stats[ctx->max_size].gets--;	} else {		INSIST(ctx->stats[size].gets > 0U);		ctx->stats[size].gets--;	}}#endif /* ISC_MEM_USE_INTERNAL_MALLOC *//* * Private. */static void *default_memalloc(void *arg, size_t size) {	UNUSED(arg);	if (size == 0U)		size = 1;	return (malloc(size));}static voiddefault_memfree(void *arg, void *ptr) {	UNUSED(arg);	free(ptr);}/* * Public. */isc_result_tisc_mem_createx(size_t init_max_size, size_t target_size,		isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,		isc_mem_t **ctxp){	isc_mem_t *ctx;	isc_result_t result;	REQUIRE(ctxp != NULL && *ctxp == NULL);	REQUIRE(memalloc != NULL);	REQUIRE(memfree != NULL);	INSIST((ALIGNMENT_SIZE & (ALIGNMENT_SIZE - 1)) == 0);#if !ISC_MEM_USE_INTERNAL_MALLOC	UNUSED(target_size);#endif	ctx = (memalloc)(arg, sizeof(*ctx));	if (ctx == NULL)		return (ISC_R_NOMEMORY);	if (init_max_size == 0U)		ctx->max_size = DEF_MAX_SIZE;	else		ctx->max_size = init_max_size;	ctx->references = 1;	ctx->quota = 0;	ctx->total = 0;	ctx->inuse = 0;	ctx->maxinuse = 0;	ctx->hi_water = 0;	ctx->lo_water = 0;	ctx->hi_called = ISC_FALSE;	ctx->water = NULL;	ctx->water_arg = NULL;	ctx->magic = MEM_MAGIC;	isc_ondestroy_init(&ctx->ondestroy);	ctx->memalloc = memalloc;	ctx->memfree = memfree;	ctx->arg = arg;	ctx->stats = NULL;	ctx->checkfree = ISC_TRUE;#if ISC_MEM_TRACKLINES	ctx->debuglist = NULL;#endif	ISC_LIST_INIT(ctx->pools);#if ISC_MEM_USE_INTERNAL_MALLOC	ctx->freelists = NULL;#endif /* ISC_MEM_USE_INTERNAL_MALLOC */	ctx->stats = (memalloc)(arg,				(ctx->max_size+1) * sizeof(struct stats));	if (ctx->stats == NULL) {		result = ISC_R_NOMEMORY;		goto error;	}	memset(ctx->stats, 0, (ctx->max_size + 1) * sizeof(struct stats));#if ISC_MEM_USE_INTERNAL_MALLOC	if (target_size == 0)		ctx->mem_target = DEF_MEM_TARGET;	else		ctx->mem_target = target_size;	ctx->freelists = (memalloc)(arg, ctx->max_size * sizeof(element *));	if (ctx->freelists == NULL) {		result = ISC_R_NOMEMORY;		goto error;	}	memset(ctx->freelists, 0,	       ctx->max_size * sizeof(element *));	ctx->basic_blocks = NULL;	ctx->basic_table = NULL;	ctx->basic_table_count = 0;	ctx->basic_table_size = 0;	ctx->lowest = NULL;	ctx->highest = NULL;#endif /* ISC_MEM_USE_INTERNAL_MALLOC */	if (isc_mutex_init(&ctx->lock) != ISC_R_SUCCESS) {		UNEXPECTED_ERROR(__FILE__, __LINE__,				 "isc_mutex_init() %s",				 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,						ISC_MSG_FAILED, "failed"));		result = ISC_R_UNEXPECTED;		goto error;	}#if ISC_MEM_TRACKLINES	if ((isc_mem_debugging & ISC_MEM_DEBUGRECORD) != 0) {		unsigned int i;		ctx->debuglist = (memalloc)(arg,				      (ctx->max_size+1) * sizeof(debuglist_t));		if (ctx->debuglist == NULL) {			result = ISC_R_NOMEMORY;			goto error;		}		for (i = 0; i <= ctx->max_size; i++)			ISC_LIST_INIT(ctx->debuglist[i]);	}#endif	ctx->memalloc_failures = 0;	*ctxp = ctx;	return (ISC_R_SUCCESS);  error:	if (ctx) {		if (ctx->stats)			(memfree)(arg, ctx->stats);#if ISC_MEM_USE_INTERNAL_MALLOC		if (ctx->freelists)			(memfree)(arg, ctx->freelists);#endif /* ISC_MEM_USE_INTERNAL_MALLOC */#if ISC_MEM_TRACKLINES		if (ctx->debuglist)			(ctx->memfree)(ctx->arg, ctx->debuglist);#endif /* ISC_MEM_TRACKLINES */		(memfree)(arg, ctx);	}	return (result);}isc_result_tisc_mem_create(size_t init_max_size, size_t target_size,	       isc_mem_t **ctxp){	return (isc_mem_createx(init_max_size, target_size,				default_memalloc, default_memfree, NULL,				ctxp));}static voiddestroy(isc_mem_t *ctx) {	unsigned int i;	isc_ondestroy_t ondest;	ctx->magic = 0;#if ISC_MEM_USE_INTERNAL_MALLOC	INSIST(ISC_LIST_EMPTY(ctx->pools));#endif /* ISC_MEM_USE_INTERNAL_MALLOC */#if ISC_MEM_TRACKLINES	if (ctx->debuglist != NULL) {		if (ctx->checkfree) {			for (i = 0; i <= ctx->max_size; i++) {				if (!ISC_LIST_EMPTY(ctx->debuglist[i]))					print_active(ctx, stderr);				INSIST(ISC_LIST_EMPTY(ctx->debuglist[i]));			}		} else {			debuglink_t *dl;			for (i = 0; i <= ctx->max_size; i++)				for (dl = ISC_LIST_HEAD(ctx->debuglist[i]);				     dl != NULL;				     dl = ISC_LIST_HEAD(ctx->debuglist[i])) {					ISC_LIST_UNLINK(ctx->debuglist[i],						 	dl, link);					free(dl);				}		}		(ctx->memfree)(ctx->arg, ctx->debuglist);	}#endif	INSIST(ctx->references == 0);	if (ctx->checkfree) {		for (i = 0; i <= ctx->max_size; i++) {#if ISC_MEM_TRACKLINES			if (ctx->stats[i].gets != 0U)				print_active(ctx, stderr);#endif			INSIST(ctx->stats[i].gets == 0U);		}	}	(ctx->memfree)(ctx->arg, ctx->stats);#if ISC_MEM_USE_INTERNAL_MALLOC	for (i = 0; i < ctx->basic_table_count; i++)		(ctx->memfree)(ctx->arg, ctx->basic_table[i]);	(ctx->memfree)(ctx->arg, ctx->freelists);	(ctx->memfree)(ctx->arg, ctx->basic_table);#endif /* ISC_MEM_USE_INTERNAL_MALLOC */	ondest = ctx->ondestroy;	DESTROYLOCK(&ctx->lock);	(ctx->memfree)(ctx->arg, ctx);	isc_ondestroy_notify(&ondest, ctx);}voidisc_mem_attach(isc_mem_t *source, isc_mem_t **targetp) {	REQUIRE(VALID_CONTEXT(source));	REQUIRE(targetp != NULL && *targetp == NULL);	LOCK(&source->lock);	source->references++;	UNLOCK(&source->lock);	*targetp = source;}voidisc_mem_detach(isc_mem_t **ctxp) {	isc_mem_t *ctx;	isc_boolean_t want_destroy = ISC_FALSE;	REQUIRE(ctxp != NULL);	ctx = *ctxp;	REQUIRE(VALID_CONTEXT(ctx));	LOCK(&ctx->lock);	INSIST(ctx->references > 0);	ctx->references--;	if (ctx->references == 0)		want_destroy = ISC_TRUE;	UNLOCK(&ctx->lock);	if (want_destroy)		destroy(ctx);	*ctxp = NULL;}/* * isc_mem_putanddetach() is the equivalent of: * * mctx = NULL; * isc_mem_attach(ptr->mctx, &mctx); * isc_mem_detach(&ptr->mctx); * isc_mem_put(mctx, ptr, sizeof(*ptr); * isc_mem_detach(&mctx); */voidisc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {	isc_mem_t *ctx;	isc_boolean_t want_destroy = ISC_FALSE;	REQUIRE(ctxp != NULL);	ctx = *ctxp;	REQUIRE(VALID_CONTEXT(ctx));	REQUIRE(ptr != NULL);	/*	 * Must be before mem_putunlocked() as ctxp is usually within	 * [ptr..ptr+size).	 */	*ctxp = NULL;#if ISC_MEM_USE_INTERNAL_MALLOC	LOCK(&ctx->lock);	mem_putunlocked(ctx, ptr, size);#else /* ISC_MEM_USE_INTERNAL_MALLOC */	mem_put(ctx, ptr, size);	LOCK(&ctx->lock);	mem_putstats(ctx, ptr, size);#endif /* ISC_MEM_USE_INTERNAL_MALLOC */	DELETE_TRACE(ctx, ptr, size, file, line);	INSIST(ctx->references > 0);	ctx->references--;	if (ctx->references == 0)		want_destroy = ISC_TRUE;	UNLOCK(&ctx->lock);	if (want_destroy)		destroy(ctx);}voidisc_mem_destroy(isc_mem_t **ctxp) {	isc_mem_t *ctx;	/*	 * This routine provides legacy support for callers who use mctxs	 * without attaching/detaching.	 */	REQUIRE(ctxp != NULL);	ctx = *ctxp;	REQUIRE(VALID_CONTEXT(ctx));	LOCK(&ctx->lock);#if ISC_MEM_TRACKLINES	if (ctx->references != 1)		print_active(ctx, stderr);#endif	REQUIRE(ctx->references == 1);	ctx->references--;	UNLOCK(&ctx->lock);	destroy(ctx);	*ctxp = NULL;}isc_result_tisc_mem_ondestroy(isc_mem_t *ctx, isc_task_t *task, isc_event_t **event) {	isc_result_t res;	LOCK(&ctx->lock);	res = isc_ondestroy_register(&ctx->ondestroy, task, event);	UNLOCK(&ctx->lock);	return (res);}void *isc__mem_get(isc_mem_t *ctx, size_t size FLARG) {	void *ptr;	isc_boolean_t call_water = ISC_FALSE;	REQUIRE(VALID_CONTEXT(ctx));#if ISC_MEM_USE_INTERNAL_MALLOC	LOCK(&ctx->lock);	ptr = mem_getunlocked(ctx, size);#else /* ISC_MEM_USE_INTERNAL_MALLOC */	ptr = mem_get(ctx, size);	LOCK(&ctx->lock);	if (ptr != NULL)		mem_getstats(ctx, size);#endif /* ISC_MEM_USE_INTERNAL_MALLOC */	ADD_TRACE(ctx, ptr, size, file, line);	if (ctx->hi_water != 0U && !ctx->hi_called &&	    ctx->inuse > ctx->hi_water) {		ctx->hi_called = ISC_TRUE;		call_water = ISC_TRUE;	}	if (ctx->inuse > ctx->maxinuse) {		ctx->maxinuse = ctx->inuse;		if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water &&		    (isc_mem_debugging & ISC_MEM_DEBUGUSAGE) != 0)			fprintf(stderr, "maxinuse = %lu\n",				(unsigned long)ctx->inuse);	}	UNLOCK(&ctx->lock);	if (call_water)		(ctx->water)(ctx->water_arg, ISC_MEM_HIWATER);	return (ptr);}voidisc__mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG){	isc_boolean_t call_water = ISC_FALSE;	REQUIRE(VALID_CONTEXT(ctx));	REQUIRE(ptr != NULL);#if ISC_MEM_USE_INTERNAL_MALLOC	LOCK(&ctx->lock);	mem_putunlocked(ctx, ptr, size);#else /* ISC_MEM_USE_INTERNAL_MALLOC */	mem_put(ctx, ptr, size);	LOCK(&ctx->lock);	mem_putstats(ctx, ptr, size);#endif /* ISC_MEM_USE_INTERNAL_MALLOC */	DELETE_TRACE(ctx, ptr, size, file, line);	/*	 * The check against ctx->lo_water == 0 is for the condition	 * when the context was pushed over hi_water but then had	 * isc_mem_setwater() called with 0 for hi_water and lo_water.	 */	if (ctx->hi_called && 	    (ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) {		ctx->hi_called = ISC_FALSE;		if (ctx->water != NULL)			call_water = ISC_TRUE;	}	UNLOCK(&ctx->lock);	if (call_water)		(ctx->water)(ctx->water_arg, ISC_MEM_LOWATER);}#if ISC_MEM_TRACKLINESstatic voidprint_active(isc_mem_t *mctx, FILE *out) {	if (mctx->debuglist != NULL) {		debuglink_t *dl;		unsigned int i, j;		const char *format;		isc_boolean_t found;		fprintf(out, isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,					    ISC_MSG_DUMPALLOC,					    "Dump of all outstanding "					    "memory allocations:\n"));		found = ISC_FALSE;		format = isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,				        ISC_MSG_PTRFILELINE,					"\tptr %p size %u file %s line %u\n");		for (i = 0; i <= mctx->max_size; i++) {			dl = ISC_LIST_HEAD(mctx->debuglist[i]);						if (dl != NULL)				found = ISC_TRUE;			while (dl != NULL) {				for (j = 0; j < DEBUGLIST_COUNT; j++)					if (dl->ptr[j] != NULL)						fprintf(out, format,							dl->ptr[j],							dl->size[j],							dl->file[j],							dl->line[j]);				dl = ISC_LIST_NEXT(dl, link);			}		}		if (!found)			fprintf(out, isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,						    ISC_MSG_NONE, "\tNone.\n"));	}}#endif/* * Print the stats[] on the stream "out" with suitable formatting. */voidisc_mem_stats(isc_mem_t *ctx, FILE *out) {	size_t i;	const struct stats *s;	const isc_mempool_t *pool;	REQUIRE(VALID_CONTEXT(ctx));	LOCK(&ctx->lock);	for (i = 0; i <= ctx->max_size; i++) {		s = &ctx->stats[i];		if (s->totalgets == 0U && s->gets == 0U)			continue;		fprintf(out, "%s%5lu: %11lu gets, %11lu rem",			(i == ctx->max_size) ? ">=" : "  ",			(unsigned long) i, s->totalgets, s->gets);#if ISC_MEM_USE_INTERNAL_MALLOC		if (s->blocks != 0 || s->freefrags != 0)			fprintf(out, " (%lu bl, %lu ff)",				s->blocks, s->freefrags);#endif /* ISC_MEM_USE_INTERNAL_MALLOC */		fputc('\n', out);	}	/*	 * Note that since a pool can be locked now, these stats might be	 * somewhat off if the pool is in active use at the time the stats	 * are dumped.  The link fields are protected by the isc_mem_t's	 * lock, however, so walking this list and extracting integers from	 * stats fields is always safe.	 */	pool = ISC_LIST_HEAD(ctx->pools);	if (pool != NULL) {		fprintf(out, isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,					    ISC_MSG_POOLSTATS,					    "[Pool statistics]\n"));		fprintf(out, "%15s %10s %10s %10s %10s %10s %10s %10s %1s\n",			isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,				       ISC_MSG_POOLNAME, "name"),			isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,				       ISC_MSG_POOLSIZE, "size"),			isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,				       ISC_MSG_POOLMAXALLOC, "maxalloc"),			isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,				       ISC_MSG_POOLALLOCATED, "allocated"),			isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,				       ISC_MSG_POOLFREECOUNT, "freecount"),			isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,				       ISC_MSG_POOLFREEMAX, "freemax"),			isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM,

⌨️ 快捷键说明

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