mem.c

来自「非常好的dns解析软件」· C语言 代码 · 共 1,955 行 · 第 1/3 页

C
1,955
字号
	if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {		MCTXLOCK(ctx, &ctx->lock);		si = isc__mem_allocateunlocked(ctx, size);	} else {		si = isc__mem_allocateunlocked(ctx, size);		MCTXLOCK(ctx, &ctx->lock);		if (si != NULL)			mem_getstats(ctx, si[-1].u.size);	}#if ISC_MEM_TRACKLINES	ADD_TRACE(ctx, si, si[-1].u.size, file, line);#endif	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);	}	MCTXUNLOCK(ctx, &ctx->lock);	if (call_water)		(ctx->water)(ctx->water_arg, ISC_MEM_HIWATER);	return (si);}voidisc__mem_free(isc_mem_t *ctx, void *ptr FLARG) {	size_info *si;	size_t size;	isc_boolean_t call_water= ISC_FALSE;	REQUIRE(VALID_CONTEXT(ctx));	REQUIRE(ptr != NULL);	if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) {		si = &(((size_info *)ptr)[-2]);		REQUIRE(si->u.ctx == ctx);		size = si[1].u.size;	} else {		si = &(((size_info *)ptr)[-1]);		size = si->u.size;	}	if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {		MCTXLOCK(ctx, &ctx->lock);		mem_putunlocked(ctx, si, size);	} else {		mem_put(ctx, si, size);		MCTXLOCK(ctx, &ctx->lock);		mem_putstats(ctx, si, size);	}	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;	}	MCTXUNLOCK(ctx, &ctx->lock);	if (call_water)		(ctx->water)(ctx->water_arg, ISC_MEM_LOWATER);}/* * Other useful things. */char *isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {	size_t len;	char *ns;	REQUIRE(VALID_CONTEXT(mctx));	REQUIRE(s != NULL);	len = strlen(s);	ns = isc__mem_allocate(mctx, len + 1 FLARG_PASS);	if (ns != NULL)		strncpy(ns, s, len + 1);	return (ns);}voidisc_mem_setdestroycheck(isc_mem_t *ctx, isc_boolean_t flag) {	REQUIRE(VALID_CONTEXT(ctx));	MCTXLOCK(ctx, &ctx->lock);	ctx->checkfree = flag;	MCTXUNLOCK(ctx, &ctx->lock);}/* * Quotas */voidisc_mem_setquota(isc_mem_t *ctx, size_t quota) {	REQUIRE(VALID_CONTEXT(ctx));	MCTXLOCK(ctx, &ctx->lock);	ctx->quota = quota;	MCTXUNLOCK(ctx, &ctx->lock);}size_tisc_mem_getquota(isc_mem_t *ctx) {	size_t quota;	REQUIRE(VALID_CONTEXT(ctx));	MCTXLOCK(ctx, &ctx->lock);	quota = ctx->quota;	MCTXUNLOCK(ctx, &ctx->lock);	return (quota);}size_tisc_mem_inuse(isc_mem_t *ctx) {	size_t inuse;	REQUIRE(VALID_CONTEXT(ctx));	MCTXLOCK(ctx, &ctx->lock);	inuse = ctx->inuse;	MCTXUNLOCK(ctx, &ctx->lock);	return (inuse);}voidisc_mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg,                 size_t hiwater, size_t lowater){	isc_boolean_t callwater = ISC_FALSE;	isc_mem_water_t oldwater;	void *oldwater_arg;	REQUIRE(VALID_CONTEXT(ctx));	REQUIRE(hiwater >= lowater);	MCTXLOCK(ctx, &ctx->lock);	oldwater = ctx->water;	oldwater_arg = ctx->water_arg;	if (water == NULL) {		callwater = ctx->hi_called;		ctx->water = NULL;		ctx->water_arg = NULL;		ctx->hi_water = 0;		ctx->lo_water = 0;		ctx->hi_called = ISC_FALSE;	} else {		if (ctx->hi_called &&		    (ctx->water != water || ctx->water_arg != water_arg ||		     ctx->inuse < lowater || lowater == 0U))			callwater = ISC_TRUE;		ctx->water = water;		ctx->water_arg = water_arg;		ctx->hi_water = hiwater;		ctx->lo_water = lowater;		ctx->hi_called = ISC_FALSE;	}	MCTXUNLOCK(ctx, &ctx->lock);		if (callwater && oldwater != NULL)		(oldwater)(oldwater_arg, ISC_MEM_LOWATER);}/* * Memory pool stuff */isc_result_tisc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp) {	isc_mempool_t *mpctx;	REQUIRE(VALID_CONTEXT(mctx));	REQUIRE(size > 0U);	REQUIRE(mpctxp != NULL && *mpctxp == NULL);	/*	 * Allocate space for this pool, initialize values, and if all works	 * well, attach to the memory context.	 */	mpctx = isc_mem_get(mctx, sizeof(isc_mempool_t));	if (mpctx == NULL)		return (ISC_R_NOMEMORY);	mpctx->magic = MEMPOOL_MAGIC;	mpctx->lock = NULL;	mpctx->mctx = mctx;	mpctx->size = size;	mpctx->maxalloc = UINT_MAX;	mpctx->allocated = 0;	mpctx->freecount = 0;	mpctx->freemax = 1;	mpctx->fillcount = 1;	mpctx->gets = 0;#if ISC_MEMPOOL_NAMES	mpctx->name[0] = 0;#endif	mpctx->items = NULL;	*mpctxp = mpctx;	MCTXLOCK(mctx, &mctx->lock);	ISC_LIST_INITANDAPPEND(mctx->pools, mpctx, link);	MCTXUNLOCK(mctx, &mctx->lock);	return (ISC_R_SUCCESS);}voidisc_mempool_setname(isc_mempool_t *mpctx, const char *name) {	REQUIRE(name != NULL);#if ISC_MEMPOOL_NAMES	if (mpctx->lock != NULL)		LOCK(mpctx->lock);	strncpy(mpctx->name, name, sizeof(mpctx->name) - 1);	mpctx->name[sizeof(mpctx->name) - 1] = '\0';	if (mpctx->lock != NULL)		UNLOCK(mpctx->lock);#else	UNUSED(mpctx);	UNUSED(name);#endif}voidisc_mempool_destroy(isc_mempool_t **mpctxp) {	isc_mempool_t *mpctx;	isc_mem_t *mctx;	isc_mutex_t *lock;	element *item;	REQUIRE(mpctxp != NULL);	mpctx = *mpctxp;	REQUIRE(VALID_MEMPOOL(mpctx));#if ISC_MEMPOOL_NAMES	if (mpctx->allocated > 0)		UNEXPECTED_ERROR(__FILE__, __LINE__,				 "isc_mempool_destroy(): mempool %s "				 "leaked memory",				 mpctx->name);#endif	REQUIRE(mpctx->allocated == 0);	mctx = mpctx->mctx;	lock = mpctx->lock;	if (lock != NULL)		LOCK(lock);	/*	 * Return any items on the free list	 */	MCTXLOCK(mctx, &mctx->lock);	while (mpctx->items != NULL) {		INSIST(mpctx->freecount > 0);		mpctx->freecount--;		item = mpctx->items;		mpctx->items = item->next;		if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {			mem_putunlocked(mctx, item, mpctx->size);		} else {			mem_put(mctx, item, mpctx->size);			mem_putstats(mctx, item, mpctx->size);		}	}	MCTXUNLOCK(mctx, &mctx->lock);	/*	 * Remove our linked list entry from the memory context.	 */	MCTXLOCK(mctx, &mctx->lock);	ISC_LIST_UNLINK(mctx->pools, mpctx, link);	MCTXUNLOCK(mctx, &mctx->lock);	mpctx->magic = 0;	isc_mem_put(mpctx->mctx, mpctx, sizeof(isc_mempool_t));	if (lock != NULL)		UNLOCK(lock);	*mpctxp = NULL;}voidisc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock) {	REQUIRE(VALID_MEMPOOL(mpctx));	REQUIRE(mpctx->lock == NULL);	REQUIRE(lock != NULL);	mpctx->lock = lock;}void *isc__mempool_get(isc_mempool_t *mpctx FLARG) {	element *item;	isc_mem_t *mctx;	unsigned int i;	REQUIRE(VALID_MEMPOOL(mpctx));	mctx = mpctx->mctx;	if (mpctx->lock != NULL)		LOCK(mpctx->lock);	/*	 * Don't let the caller go over quota	 */	if (mpctx->allocated >= mpctx->maxalloc) {		item = NULL;		goto out;	}	/*	 * if we have a free list item, return the first here	 */	item = mpctx->items;	if (item != NULL) {		mpctx->items = item->next;		INSIST(mpctx->freecount > 0);		mpctx->freecount--;		mpctx->gets++;		mpctx->allocated++;		goto out;	}	/*	 * We need to dip into the well.  Lock the memory context here and	 * fill up our free list.	 */	MCTXLOCK(mctx, &mctx->lock);	for (i = 0; i < mpctx->fillcount; i++) {		if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {			item = mem_getunlocked(mctx, mpctx->size);		} else {			item = mem_get(mctx, mpctx->size);			if (item != NULL)				mem_getstats(mctx, mpctx->size);		}		if (item == NULL)			break;		item->next = mpctx->items;		mpctx->items = item;		mpctx->freecount++;	}	MCTXUNLOCK(mctx, &mctx->lock);	/*	 * If we didn't get any items, return NULL.	 */	item = mpctx->items;	if (item == NULL)		goto out;	mpctx->items = item->next;	mpctx->freecount--;	mpctx->gets++;	mpctx->allocated++; out:	if (mpctx->lock != NULL)		UNLOCK(mpctx->lock);#if ISC_MEM_TRACKLINES	if (item != NULL) {		MCTXLOCK(mctx, &mctx->lock);		ADD_TRACE(mctx, item, mpctx->size, file, line);		MCTXUNLOCK(mctx, &mctx->lock);	}#endif /* ISC_MEM_TRACKLINES */	return (item);}voidisc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {	isc_mem_t *mctx;	element *item;	REQUIRE(VALID_MEMPOOL(mpctx));	REQUIRE(mem != NULL);	mctx = mpctx->mctx;	if (mpctx->lock != NULL)		LOCK(mpctx->lock);	INSIST(mpctx->allocated > 0);	mpctx->allocated--;#if ISC_MEM_TRACKLINES	MCTXLOCK(mctx, &mctx->lock);	DELETE_TRACE(mctx, mem, mpctx->size, file, line);	MCTXUNLOCK(mctx, &mctx->lock);#endif /* ISC_MEM_TRACKLINES */	/*	 * If our free list is full, return this to the mctx directly.	 */	if (mpctx->freecount >= mpctx->freemax) {		if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {			MCTXLOCK(mctx, &mctx->lock);			mem_putunlocked(mctx, mem, mpctx->size);			MCTXUNLOCK(mctx, &mctx->lock);		} else {			mem_put(mctx, mem, mpctx->size);			MCTXLOCK(mctx, &mctx->lock);			mem_putstats(mctx, mem, mpctx->size);			MCTXUNLOCK(mctx, &mctx->lock);		}		if (mpctx->lock != NULL)			UNLOCK(mpctx->lock);		return;	}	/*	 * Otherwise, attach it to our free list and bump the counter.	 */	mpctx->freecount++;	item = (element *)mem;	item->next = mpctx->items;	mpctx->items = item;	if (mpctx->lock != NULL)		UNLOCK(mpctx->lock);}/* * Quotas */voidisc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit) {	REQUIRE(VALID_MEMPOOL(mpctx));	if (mpctx->lock != NULL)		LOCK(mpctx->lock);	mpctx->freemax = limit;	if (mpctx->lock != NULL)		UNLOCK(mpctx->lock);}unsigned intisc_mempool_getfreemax(isc_mempool_t *mpctx) {	unsigned int freemax;	REQUIRE(VALID_MEMPOOL(mpctx));	if (mpctx->lock != NULL)		LOCK(mpctx->lock);	freemax = mpctx->freemax;	if (mpctx->lock != NULL)		UNLOCK(mpctx->lock);	return (freemax);}unsigned intisc_mempool_getfreecount(isc_mempool_t *mpctx) {	unsigned int freecount;	REQUIRE(VALID_MEMPOOL(mpctx));	if (mpctx->lock != NULL)		LOCK(mpctx->lock);	freecount = mpctx->freecount;	if (mpctx->lock != NULL)		UNLOCK(mpctx->lock);	return (freecount);}voidisc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit) {	REQUIRE(limit > 0);	REQUIRE(VALID_MEMPOOL(mpctx));	if (mpctx->lock != NULL)		LOCK(mpctx->lock);	mpctx->maxalloc = limit;	if (mpctx->lock != NULL)		UNLOCK(mpctx->lock);}unsigned intisc_mempool_getmaxalloc(isc_mempool_t *mpctx) {	unsigned int maxalloc;	REQUIRE(VALID_MEMPOOL(mpctx));	if (mpctx->lock != NULL)		LOCK(mpctx->lock);	maxalloc = mpctx->maxalloc;	if (mpctx->lock != NULL)		UNLOCK(mpctx->lock);	return (maxalloc);}unsigned intisc_mempool_getallocated(isc_mempool_t *mpctx) {	unsigned int allocated;	REQUIRE(VALID_MEMPOOL(mpctx));	if (mpctx->lock != NULL)		LOCK(mpctx->lock);	allocated = mpctx->allocated;	if (mpctx->lock != NULL)		UNLOCK(mpctx->lock);	return (allocated);}voidisc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit) {	REQUIRE(limit > 0);	REQUIRE(VALID_MEMPOOL(mpctx));	if (mpctx->lock != NULL)		LOCK(mpctx->lock);	mpctx->fillcount = limit;	if (mpctx->lock != NULL)		UNLOCK(mpctx->lock);}unsigned intisc_mempool_getfillcount(isc_mempool_t *mpctx) {	unsigned int fillcount;	REQUIRE(VALID_MEMPOOL(mpctx));	if (mpctx->lock != NULL)		LOCK(mpctx->lock);	fillcount = mpctx->fillcount;	if (mpctx->lock != NULL)		UNLOCK(mpctx->lock);	return (fillcount);}voidisc_mem_printactive(isc_mem_t *ctx, FILE *file) {	REQUIRE(VALID_CONTEXT(ctx));	REQUIRE(file != NULL);#if !ISC_MEM_TRACKLINES	UNUSED(ctx);	UNUSED(file);#else	print_active(ctx, file);#endif}voidisc_mem_printallactive(FILE *file) {#if !ISC_MEM_TRACKLINES	UNUSED(file);#else	isc_mem_t *ctx;	RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);	LOCK(&lock);	for (ctx = ISC_LIST_HEAD(contexts);	     ctx != NULL;	     ctx = ISC_LIST_NEXT(ctx, link)) {		fprintf(file, "context: %p\n", ctx);		print_active(ctx, file);	}	UNLOCK(&lock);#endif}void    isc_mem_checkdestroyed(FILE *file) {	RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);	LOCK(&lock);	if (!ISC_LIST_EMPTY(contexts))  {#if ISC_MEM_TRACKLINES		isc_mem_t *ctx;		for (ctx = ISC_LIST_HEAD(contexts);		     ctx != NULL;		     ctx = ISC_LIST_NEXT(ctx, link)) {			fprintf(file, "context: %p\n", ctx);			print_active(ctx, file);		}		fflush(file);#endif		INSIST(1);	}	UNLOCK(&lock);}

⌨️ 快捷键说明

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