📄 mem.c
字号:
ISC_MSG_POOLFILLCOUNT, "fillcount"), isc_msgcat_get(isc_msgcat, ISC_MSGSET_MEM, ISC_MSG_POOLGETS, "gets"), "L"); } while (pool != NULL) { fprintf(out, "%15s %10lu %10u %10u %10u %10u %10u %10u %s\n", pool->name, (unsigned long) pool->size, pool->maxalloc, pool->allocated, pool->freecount, pool->freemax, pool->fillcount, pool->gets, (pool->lock == NULL ? "N" : "Y")); pool = ISC_LIST_NEXT(pool, link); }#if ISC_MEM_TRACKLINES print_active(ctx, out);#endif UNLOCK(&ctx->lock);}/* * Replacements for malloc() and free() -- they implicitly remember the * size of the object allocated (with some additional overhead). */static void *isc__mem_allocateunlocked(isc_mem_t *ctx, size_t size) { size_info *si; size += ALIGNMENT_SIZE;#if ISC_MEM_USE_INTERNAL_MALLOC si = mem_getunlocked(ctx, size);#else /* ISC_MEM_USE_INTERNAL_MALLOC */ si = mem_get(ctx, size);#endif /* ISC_MEM_USE_INTERNAL_MALLOC */ if (si == NULL) return (NULL); si->u.size = size; return (&si[1]);}void *isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) { size_info *si; REQUIRE(VALID_CONTEXT(ctx));#if ISC_MEM_USE_INTERNAL_MALLOC LOCK(&ctx->lock); si = isc__mem_allocateunlocked(ctx, size);#else /* ISC_MEM_USE_INTERNAL_MALLOC */ si = isc__mem_allocateunlocked(ctx, size); LOCK(&ctx->lock); if (si != NULL) mem_getstats(ctx, si[-1].u.size);#endif /* ISC_MEM_USE_INTERNAL_MALLOC */#if ISC_MEM_TRACKLINES ADD_TRACE(ctx, si, si[-1].u.size, file, line);#endif UNLOCK(&ctx->lock); return (si);}voidisc__mem_free(isc_mem_t *ctx, void *ptr FLARG) { size_info *si; size_t size; REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(ptr != NULL); si = &(((size_info *)ptr)[-1]); size = si->u.size;#if ISC_MEM_USE_INTERNAL_MALLOC LOCK(&ctx->lock); mem_putunlocked(ctx, si, size);#else /* ISC_MEM_USE_INTERNAL_MALLOC */ mem_put(ctx, si, size); LOCK(&ctx->lock); mem_putstats(ctx, si, size);#endif /* ISC_MEM_USE_INTERNAL_MALLOC */ DELETE_TRACE(ctx, ptr, size, file, line); UNLOCK(&ctx->lock);}/* * 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)); LOCK(&ctx->lock); ctx->checkfree = flag; UNLOCK(&ctx->lock);}/* * Quotas */voidisc_mem_setquota(isc_mem_t *ctx, size_t quota) { REQUIRE(VALID_CONTEXT(ctx)); LOCK(&ctx->lock); ctx->quota = quota; UNLOCK(&ctx->lock);}size_tisc_mem_getquota(isc_mem_t *ctx) { size_t quota; REQUIRE(VALID_CONTEXT(ctx)); LOCK(&ctx->lock); quota = ctx->quota; UNLOCK(&ctx->lock); return (quota);}size_tisc_mem_inuse(isc_mem_t *ctx) { size_t inuse; REQUIRE(VALID_CONTEXT(ctx)); LOCK(&ctx->lock); inuse = ctx->inuse; UNLOCK(&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){ REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(hiwater >= lowater); LOCK(&ctx->lock); if (water == NULL) { ctx->water = NULL; ctx->water_arg = NULL; ctx->hi_water = 0; ctx->lo_water = 0; ctx->hi_called = ISC_FALSE; } else { ctx->water = water; ctx->water_arg = water_arg; ctx->hi_water = hiwater; ctx->lo_water = lowater; ctx->hi_called = ISC_FALSE; } UNLOCK(&ctx->lock);}/* * 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; LOCK(&mctx->lock); ISC_LIST_INITANDAPPEND(mctx->pools, mpctx, link); UNLOCK(&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 */ LOCK(&mctx->lock); while (mpctx->items != NULL) { INSIST(mpctx->freecount > 0); mpctx->freecount--; item = mpctx->items; mpctx->items = item->next;#if ISC_MEM_USE_INTERNAL_MALLOC mem_putunlocked(mctx, item, mpctx->size);#else /* ISC_MEM_USE_INTERNAL_MALLOC */ mem_put(mctx, item, mpctx->size); mem_putstats(mctx, item, mpctx->size);#endif /* ISC_MEM_USE_INTERNAL_MALLOC */ } UNLOCK(&mctx->lock); /* * Remove our linked list entry from the memory context. */ LOCK(&mctx->lock); ISC_LIST_UNLINK(mctx->pools, mpctx, link); UNLOCK(&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. */ LOCK(&mctx->lock); for (i = 0; i < mpctx->fillcount; i++) {#if ISC_MEM_USE_INTERNAL_MALLOC item = mem_getunlocked(mctx, mpctx->size);#else /* ISC_MEM_USE_INTERNAL_MALLOC */ item = mem_get(mctx, mpctx->size); if (item != NULL) mem_getstats(mctx, mpctx->size);#endif /* ISC_MEM_USE_INTERNAL_MALLOC */ if (item == NULL) break; item->next = mpctx->items; mpctx->items = item; mpctx->freecount++; } UNLOCK(&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) { LOCK(&mctx->lock); ADD_TRACE(mctx, item, mpctx->size, file, line); UNLOCK(&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 LOCK(&mctx->lock); DELETE_TRACE(mctx, mem, mpctx->size, file, line); UNLOCK(&mctx->lock);#endif /* ISC_MEM_TRACKLINES */ /* * If our free list is full, return this to the mctx directly. */ if (mpctx->freecount >= mpctx->freemax) {#if ISC_MEM_USE_INTERNAL_MALLOC LOCK(&mctx->lock); mem_putunlocked(mctx, mem, mpctx->size); UNLOCK(&mctx->lock);#else /* ISC_MEM_USE_INTERNAL_MALLOC */ mem_put(mctx, mem, mpctx->size); LOCK(&mctx->lock); mem_putstats(mctx, mem, mpctx->size); UNLOCK(&mctx->lock);#endif /* ISC_MEM_USE_INTERNAL_MALLOC */ 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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -