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 + -
显示快捷键?