Agent skill

Isc Mem Allocator

by isc-projects in isc-projects/bind9

BIND 9's memory allocator wrapper (iscmem memory contexts and iscmempool fixed-size pools).

MPL-2.0Auto-check passedDevelopment

Install Isc Mem Allocator

skills CLI
$ npx skills add isc-projects/bind9 --skill isc-mem-allocator -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install isc-projects/bind9 isc-mem-allocator --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/isc-projects/bind9.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/isc-mem-allocator .claude/skills/isc-mem-allocator && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
isc-mem-allocator
GitHub stars
780
Token cost
~2.9k tokens
SKILL.md length
1,368 words
Files
1
Skills in repo
9
Repo updated
First seen
Licence
MPL-2.0

At a glance

BIND 9's memory allocator wrapper (iscmem memory contexts and iscmempool fixed-size pools).

  • Works in 7 steps: get↔put / allocate↔free pairing, same… → Realloc sizing: isc_mem_reget needs the… → No NULL checks / error paths after… → …
  • Reviewing code that allocates/frees memory anywhere in BIND 9
  • SKILL.md covers Big picture, The two allocation families —…, Context lifecycle and Statistics and accounting…, plus 3 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Isc Mem Allocator is an agent skill from isc-projects/bind9. BIND 9's memory allocator wrapper (iscmem memory contexts and iscmempool fixed-size pools). Use when writing or reviewing code that allocates/frees memory anywhere in BIND 9, when choosing between iscmemget/put and iscmemallocate/free, when debugging "iscmeminuse(ctx) == 0" or mempool-leak assertion failures, memory-leak reports, overmem/water-mark behavior, or ISCMEMDEBUG tracing.

Its SKILL.md is about 2.9k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Development, covering Performance optimization and Debugging. The repository describes itself as: Archived mirror of https://gitlab.isc.org/isc-projects/bind9, please submit issues and PR/MRs in the GitLab. The licence is MPL-2.0.

When your agent uses it

  • Reviewing code that allocates/frees memory anywhere in BIND 9
  • Choosing between iscmemget/put and iscmemallocate/free
  • Debugging iscmeminuse(ctx) == 0
  • Mempool-leak assertion failures

Example prompts

  • “iscmeminuse(ctx) == 0”
  • “/isc-mem-allocator”

Workflow steps

7 steps, taken from the first numbered list in SKILL.md.

  1. get↔put / allocate↔free pairing, same mctx, same size (or matched
  2. Realloc sizing: isc_mem_reget needs the correct old size; on the
  3. No NULL checks / error paths after allocation — remove dead OOM handling.
  4. Put-macro arguments: lvalue, no side effects, and nothing reads the
  5. Destructor idiom: last-ref objects use isc_mem_putanddetach.
  6. Mempools: single-thread confinement is actually guaranteed; destroy path
  7. New long-lived subsystems get their own named mctx (visible in stats

What it can do on your machine

Read from SKILL.md and the folder at commit 12d28b2. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are c).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Isc Mem Allocator loads about 2.9k tokens when it runs. Until then it costs about 103 tokens; SKILL.md has 1,368 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~103
When it runs · the whole SKILL.md, loaded when a task matches
~2.9k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from isc-projects/bind9 at commit 12d28b2, republished under its MPL-2.0 licence (© isc-projects). 1,368 words, ~2,881 tokens.

Download SKILL.mdSave it as .claude/skills/isc-mem-allocator/SKILL.md (or your agent's skills folder).
name
isc-mem-allocator
description
BIND 9's memory allocator wrapper (isc_mem memory contexts and isc_mempool fixed-size pools). Use when writing or reviewing code that allocates/frees memory anywhere in BIND 9, when choosing between isc_mem_get/put and isc_mem_allocate/free, when debugging "isc_mem_inuse(ctx) == 0" or mempool-leak assertion failures, memory-leak reports, overmem/water-mark behavior, or ISC_MEM_DEBUG* tracing.

BIND 9 allocator wrapper (isc_mem / isc_mempool)

Source of truth: lib/isc/include/isc/mem.h (public API), lib/isc/mem.c (implementation), lib/isc/mem_p.h (private init/shutdown), lib/isc/jemalloc_shim.h (non-jemalloc fallback).

Big picture

isc_mem_t (an "mctx") is a thin, reference-counted accounting wrapper over jemalloc's non-standard API: mallocx / sdallocx / rallocx / sallocx. On systems without jemalloc, jemalloc_shim.h emulates those on top of malloc, recovering sizes from malloc_usable_size() / malloc_size(), or as a last resort by prepending a size_info header to every allocation.

Key consequences:

  • Allocation never fails. OOM calls oom(), which writes a signal-safe report + backtrace to stderr and abort()s. Never write if (ptr == NULL) after an isc_mem_* call; there is no NULL return.
  • Deallocation is size-hinted (sdallocx). Freeing with the wrong size is undefined behavior inside jemalloc, not just a stats bug.
  • All contexts share jemalloc arenas (jemalloc_flags is currently always 0), so an mctx is an accounting domain, not a heap: it tracks who owes what, it does not partition memory.
  • A global default context isc_g_mctx always exists (created by the library constructor isc__lib_initialize() → isc__mem_initialize() in lib/isc/lib.c). Use it only when nothing more specific fits.

The two allocation families — never mix them

sized familyusable-size family
allocisc_mem_get(mctx, size)isc_mem_allocate(mctx, size)
zeroedisc_mem_cget(mctx, n, size)isc_mem_callocate(mctx, n, size)
reallocisc_mem_reget(mctx, p, oldsize, newsize) / isc_mem_creget(mctx, p, oldn, newn, size)isc_mem_reallocate(mctx, p, newsize)
freeisc_mem_put(mctx, p, size) / isc_mem_cput(mctx, p, n, size)isc_mem_free(mctx, p)
strdup—isc_mem_strdup(mctx, s)
stats chargethe size you passedreal usable size via sallocx (≥ requested)

Rules:

  • Memory from isc_mem_get must be returned with isc_mem_put using the same mctx and the same size. Memory from isc_mem_allocate must go back via isc_mem_free. Crossing the families corrupts the per-context inuse counter (put charges the requested size, free charges the sallocx size), which detonates later as INSIST(isc_mem_inuse(ctx) == 0) when the context is destroyed. The header's ISC_ATTR_MALLOC_DEALLOCATOR_IDX attributes make compilers warn about some mismatches — treat those warnings as errors.
  • Prefer the sized family whenever the caller knows the size (the common case: isc_mem_get(mctx, sizeof(*obj))). Use allocate/free only for variable-length data whose size is inconvenient to carry around.
  • The c-prefixed variants are calloc-alikes: ISC_CHECKED_MUL(n, size) (overflow-fatal multiply) plus ISC__MEM_ZERO. ISC__MEM_ZERO is verbatim jemalloc's MALLOCX_ZERO (0x40), RUNTIME_CHECKed at startup. Free a cget'd array with isc_mem_cput(mctx, p, n, size) so the sizes match.
  • Size 0 is legal and symmetric: both get and put bump 0 to sizeof(void *) (ADJUST_ZERO_ALLOCATION_SIZE).
The put/free macros NULL the pointer

isc_mem_put, isc_mem_cput, isc_mem_free, isc_mem_putanddetach, and isc_mempool_put are statement macros that end with (p) = NULL;. So:

  • The pointer argument must be an assignable lvalue and must not have side effects (macro arguments are expanded more than once — never isc_mem_put(mctx, arr[i++], size)).
  • After the call the variable is NULL — code relying on the old pointer value afterwards is a bug even though the memory "was just there".
isc_mem_putanddetach

For objects that hold a reference to their own mctx:

c
isc_mem_putanddetach(&obj->mctx, obj, sizeof(*obj));

frees obj and then drops the mctx reference in the safe order (equivalent to attach-to-local / detach-member / put / detach-local). This is the standard destructor idiom; use it instead of an open-coded put + detach.

Context lifecycle

  • isc_mem_create("name", &mctx) — name is mandatory, copied, shows up in stats channel output and leak dumps. (The create macro also re-assigns isc__mem_malloc = mallocx; that is a deliberate link-order hack for jemalloc — see jemalloc issue #2566 — don't "clean it up".)
  • Refcounted via ISC_REFCOUNT_IMPL: isc_mem_attach(src, &dst), isc_mem_detach(&mctx) (NULLs the pointer), isc_mem_ref/unref. The last detach destroys the context.
  • Destruction asserts the books balance: INSIST(isc_mem_inuse(ctx) == 0) and that no pools remain. isc_mem_setdestroycheck(mctx, false) disables the leak check — almost never the right fix; a failing inuse INSIST means a leak or a family/size mismatch.
  • isc_mem_checkdestroyed(stderr) (called by named/tests at shutdown) arms a library-shutdown check that every context was destroyed; it hits UNREACHABLE() otherwise, after dumping live contexts when debugging is on.
  • isc__mem_shutdown() runs rcu_barrier() before checking, so RCU-deferred frees (call_rcu) are flushed first — deferred frees still count as live until the grace period runs.

Statistics and accounting internals

  • inuse is striped per thread id: stat_s[ISC_TID_MAX + 1] cacheline-padded slots; ctx->stat = &stat_s[1] so isc_tid() == -1 (ISC_TID_UNKNOWN, i.e. threads outside the loopmgr) indexes stat[-1] legally. Updates are relaxed atomics on the caller's own stripe.
  • A stripe can go negative (thread A frees what thread B allocated) — that's why stripes are signed. Only the sum (isc_mem_inuse(), which walks -1..isc_tid_count()) is meaningful.
  • isc_mem_inuse() is O(threads) and iterates all stripes — fine for water-mark checks, don't put it in per-packet hot paths gratuitously.
Water marks / overmem
  • isc_mem_setwater(mctx, hiwater, lowater) (0,0 or isc_mem_clearwater() disables). Used by the resolver/cache to bound cache memory.
  • isc_mem_isovermem() is probabilistic: false below lowater, true above hiwater, and in between returns true with probability ramping linearly 0→1 (8-bit resolution, isc_random8()). This deliberately spreads cache cleaning over many inserts instead of a thundering herd at the mark — do not "fix" the randomness, and don't expect two consecutive calls to agree.
Returning memory to the OS
  • Each thread counts bytes it frees (freed_bytes, thread-local); every 16 MiB it triggers mem_purge(): jemalloc arena.<all>.decay (or glibc malloc_trim(0)), rate-limited via CAS on last_purge to once per second globally.
  • Init-time jemalloc tuning: background_thread = true, dirty_decay_ms = 10000 applied to existing and future arenas. Failures are ignored on purpose (the volumetric purge covers it).
Show full SKILL.md (527 more words)Show less

Debugging facilities

Compile-time gate: ISC_MEM_TRACKLINES (set automatically by -Ddeveloper=enabled meson builds) compiles in per-call __func__/__FILE__/__LINE__ plumbing. Without it, the runtime flags below are inert no-ops. ISC_MEM_TRACE additionally turns attach/detach into traced refcounting.

Runtime flags (a context copies the global default at creation; isc_mem_debugon()/debugoff() adjust the default and isc_g_mctx; isc_mem_setdebugging() sets one context but requires inuse == 0):

  • ISC_MEM_DEBUGTRACE — print every alloc/free (add ptr size func file line mctx / del ...) to stderr.
  • ISC_MEM_DEBUGRECORD — record every live allocation in a 512-bucket hash table; freeing something never allocated hits UNREACHABLE(); leaks are dumped (print_active) with file:line when the context is destroyed. This is the tool for "inuse != 0 at destroy" hunts.
  • ISC_MEM_DEBUGUSAGE — log when usage crosses the water marks.

Each flag can be enabled by simply setting the environment variable of the same name (existence is checked, not the value) before start; the file name in each record is copied, not pointed to, so plugins can be unloaded safely.

Observability: isc_mem_stats(mctx, fp) (pool table + active allocations), isc__mem_printactive() (unit tests), and the statistics channel renders all contexts via isc_mem_renderxml() / isc_mem_renderjson() (id, name, references, inuse, pool count, water marks).

isc_mempool — fixed-size free-list pools

isc_mempool_t batches fixed-size items on top of an mctx to cut allocator round-trips (used for message buffers etc.):

c
isc_mempool_create(mctx, sizeof(item_t), "items", &pool);
isc_mempool_setfillcount(pool, 32);  /* items grabbed per refill, default 1 */
isc_mempool_setfreemax(pool, 32);    /* free-list cap, default 1 */
...
item_t *it = isc_mempool_get(pool);   /* never NULL */
isc_mempool_put(pool, it);            /* NULLs 'it' */
...
isc_mempool_destroy(&pool);

Critical facts:

  • No locking whatsoever. The struct comment says "always unlocked"; the caller must confine a pool to one thread or provide external locking. Getters (getallocated, getfreecount, ...) return garbage under concurrent mutation.
  • get: pops the free list; if empty, grabs fillcount items from the mctx in one loop. put: pushes back on the free list unless freecount >= freemax, in which case the item goes straight back to the mctx.
  • Item size is silently raised to sizeof(element) (one pointer) because free items are chained through their own storage — a pool of very small items wastes the difference.
  • Under AddressSanitizer, fillcount is forced to 1 and freemax to 0 so every get/put reaches the real allocator and poisoning/use-after-free detection works. Don't assume pooling behavior in ASAN builds.
  • isc_mempool_destroy() requires every item returned: outstanding items log UNEXPECTED_ERROR("mempool %s leaked memory") and fail a REQUIRE.
  • The pool holds a reference on its mctx and is linked on the context's pools list (isc_mem_stats prints them); a context cannot be destroyed while its pools exist.
  • Pool items are charged to the mctx when fetched from it (i.e. items sitting on the pool free list still count as inuse for the mctx).

Review checklist

When touching allocation code, check:

  1. get↔put / allocate↔free pairing, same mctx, same size (or matched n, size pairs for cget/cput). Grep for the struct's free sites when a size or family changes.
  2. Realloc sizing: isc_mem_reget needs the correct old size; on the non-jemalloc path it manually zeroes the growth for creget, so a wrong old size also breaks zeroing.
  3. No NULL checks / error paths after allocation — remove dead OOM handling.
  4. Put-macro arguments: lvalue, no side effects, and nothing reads the pointer after the macro (it's NULL now).
  5. Destructor idiom: last-ref objects use isc_mem_putanddetach.
  6. Mempools: single-thread confinement is actually guaranteed; destroy path returns every item first.
  7. New long-lived subsystems get their own named mctx (visible in stats channel), not isc_g_mctx.

© isc-projects, MPL-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/isc-mem-allocator of isc-projects/bind9.

Open the folder on GitHubat commit 12d28b2

Compare with similar skills

Isc Mem Allocator next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Isc Mem Allocator compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Isc Mem Allocator this skillisc-projects/bind9780—~2.9kAutomated safety check: PassMPL-2.0
Cmux Debugging Guidemanaflow-ai/cmux28k1 repos~1.1kAutomated safety check: PassCustom licence
Electron Heap Snapshot Analysiskeybase/client9.3k—~875Automated safety check: PassBSD-3-Clause
Issue Fixmono/SkiaSharp5.6k—~5.1kAutomated safety check: PassMIT
PlotJuggler 4 Perf ProfilingPlotJuggler/PlotJuggler6.2k—~1.6kAutomated safety check: NotesMPL-2.0
Electron DevTools Trace Analysiskeybase/client9.3k—~809Automated safety check: PassBSD-3-Clause

Similar skills

  • Cmux Debugging Guide

    manaflow-ai/cmux

    Covers debug logging, the Debug menu, profiling rules and runtime pitfalls for working on the cmux macOS terminal app.

    28k GitHub starsUsed in 1 repo~1.1k tokens
    DevelopmentAuto-check passed
  • Analyzes V8, Chrome and Electron .heapsnapshot files with Node scripts to find memory leaks, detached DOM nodes and the retainer paths that keep objects alive.

    9.3k GitHub stars~875 tokensUpdated today
    DevelopmentAuto-check passed
  • Issue Fix

    mono/SkiaSharp

    Fix bugs in SkiaSharp C bindings. An agent skill from mono/SkiaSharp.

    5.6k GitHub stars~5.1k tokensUpdated today
    DevelopmentAuto-check passed
  • PlotJuggler 4 Perf Profiling

    PlotJuggler/PlotJuggler

    Guides CPU profiling of PlotJuggler 4 on Linux with perf: count first, record cheaply with LBR, then read per-thread, flat, flamegraph or time-window views.

    6.2k GitHub stars~1.6k tokensUpdated 6 days ago
    DevelopmentAuto-check: notes
  • Analyzes Chrome or Electron DevTools Performance trace exports with Python scripts to find where render time actually goes, without opening DevTools.

    9.3k GitHub stars~809 tokensUpdated today
    DevelopmentAuto-check passed
  • Profiles slow Python code with cProfile and memory profilers, then applies targeted fixes for CPU, memory, I/O and query bottlenecks.

    40k GitHub starsUsed in 13 repos~814 tokens
    DevelopmentAuto-check passed

More from isc-projects/bind9

All 9 skills in this repo
  • Rcu Mutation

    isc-projects/bind9

    Correct discipline for mutating an RCU / lock-free pointer-based data structure (trie, tree, list, graph) that has concurrent readers — build a new node cluster invisibly, publish it, then reclaim…

    780 GitHub stars~3.8k tokensUpdated today
    Auto-check passed
  • Struct Layout Analysis

    isc-projects/bind9

    Measure and fix C struct layout in BIND 9 — pahole on the build's DWARF for sizes, padding holes, and cacheline boundaries, plus the house cacheline-padding idiom.

    780 GitHub stars~461 tokensUpdated today
    Auto-check passed
  • Tweak Release Notes

    isc-projects/bind9

    Review and refine ISC BIND 9 release notes for a new version — audit audience/action tags against the actual change substance, verify every covered issue is closed, and rewrite the auto-generated…

    780 GitHub stars~1.2k tokensUpdated today
    Auto-check passed
  • Bind Mr Description

    isc-projects/bind9

    Drafting BIND 9 merge-request titles and descriptions — they feed the generated release notes, so the audience is system administrators.

    780 GitHub stars~674 tokensUpdated today
    Auto-check passed
  • Isc Async Scheduling

    isc-projects/bind9

    How BIND 9 schedules callbacks — iscjobrun (same loop), iscasyncrun (any thread → any loop), iscworkenqueue (offload to a worker thread).

    780 GitHub stars~1.8k tokensUpdated today
    Auto-check passed
  • Methodology for root-causing hard concurrency / memory-ordering bugs (intermittent races, use-after-free, RCU/lock-free publish-order defects, "impossible" stale reads) with LTTng flight-recorder…

    780 GitHub stars~2.5k tokensUpdated today
    Auto-check passed

Categories

Questions about Isc Mem Allocator

What does Isc Mem Allocator do?

BIND 9's memory allocator wrapper (iscmem memory contexts and iscmempool fixed-size pools). Isc Mem Allocator is an agent skill from isc-projects/bind9. BIND 9's memory allocator wrapper (iscmem memory contexts and iscmempool fixed-size pools).

When should I use Isc Mem Allocator?

Isc Mem Allocator fits situations like: reviewing code that allocates/frees memory anywhere in BIND 9; choosing between iscmemget/put and iscmemallocate/free; debugging iscmeminuse(ctx) == 0; mempool-leak assertion failures.

How do I install Isc Mem Allocator in Claude Code?

Run `npx skills add isc-projects/bind9 --skill isc-mem-allocator -a claude-code`. Or copy the skill folder (.agents/skills/isc-mem-allocator in isc-projects/bind9) into .claude/skills/isc-mem-allocator in your project. Claude Code loads it when a task matches its description.

How do I install Isc Mem Allocator in Codex?

Run `npx skills add isc-projects/bind9 --skill isc-mem-allocator -a codex`. Or copy the skill folder (.agents/skills/isc-mem-allocator in isc-projects/bind9) into .agents/skills/isc-mem-allocator in your project. Codex loads it when a task matches its description.

Can I use Isc Mem Allocator in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add isc-projects/bind9 --skill isc-mem-allocator -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/isc-mem-allocator, .gemini/skills/isc-mem-allocator, .github/skills/isc-mem-allocator and .opencode/skills/isc-mem-allocator in your project.

What does Isc Mem Allocator need to run?

SKILL.md names no scripts, command-line tools or credentials: Isc Mem Allocator is instructions for the agent only.

Does Isc Mem Allocator access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Isc Mem Allocator safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Isc Mem Allocator use?

Isc Mem Allocator is published under the MPL-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Isc Mem Allocator use?

About 2.9k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Isc Mem Allocator?

Skills that share tags, products or a category with Isc Mem Allocator: Cmux Debugging Guide (manaflow-ai/cmux, 28k stars), Electron Heap Snapshot Analysis (keybase/client, 9.3k stars), Issue Fix (mono/SkiaSharp, 5.6k stars) and PlotJuggler 4 Perf Profiling (PlotJuggler/PlotJuggler, 6.2k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Isc Mem Allocator?

isc-projects (a GitHub organization) maintains it in isc-projects/bind9, which has 780 GitHub stars. The repository holds 9 skills in this directory. The repository was last updated on October 7, 2026.

Source: isc-projects/bind9 on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.