xtc_res(3)

---

xtc_res(3)

resource accountant with hard caps and high-water alerts

XTC_RES(3) Library Functions Manual XTC_RES(3)

xtc_res_init, xtc_res_fini, xtc_res_acquire, xtc_res_release, xtc_res_used, xtc_res_cap, xtc_res_set_cap, xtc_res_high, xtc_res_rejects, xtc_res_set_alert, xtc_res_set_alert_fnresource accountant with hard caps and high-water alerts

#include <xtc.h>
#include <xtc_res.h>

int
xtc_res_init(xtc_res_t *res, const xtc_res_caps_t *caps);

void
xtc_res_fini(xtc_res_t *res);

int
xtc_res_acquire(xtc_res_t *res, xtc_res_kind_t kind, int64_t amount);

void
xtc_res_release(xtc_res_t *res, xtc_res_kind_t kind, int64_t amount);

int64_t
xtc_res_used(const xtc_res_t *res, xtc_res_kind_t kind);

int64_t
xtc_res_cap(const xtc_res_t *res, xtc_res_kind_t kind);

void
xtc_res_set_cap(xtc_res_t *res, xtc_res_kind_t kind, int64_t cap);

int64_t
xtc_res_high(const xtc_res_t *res, xtc_res_kind_t kind);

int64_t
xtc_res_rejects(const xtc_res_t *res, xtc_res_kind_t kind);

int
xtc_res_set_alert(xtc_res_t *res, xtc_res_kind_t kind, int64_t threshold);

int
xtc_res_set_alert_fn(xtc_res_t *res, xtc_res_alert_fn fn, void *user);

xtc_res tracks resource consumption against operator-configured hard caps. Tracked kinds:

Bytes of allocated memory.
In-flight tasks (xtc_proc + xtc_task).
Open file descriptors.
Network throughput (for rate limiting).
Disk I/O byte count.
Cross-loop inbox queue length.

Each kind has an optional cap. () returns XTC_E_RESOURCE if the request would exceed the cap; () gives capacity back. Both are atomic; thread-safe under concurrent calls.

: when usage crosses threshold upward, the alert fn fires. When usage drops back below the threshold, the alert re-arms. This avoids alert floods while ensuring each crossing fires.

() changes the cap for a kind at runtime. () returns the high-water mark of usage for a kind, and () returns the number of acquires rejected because they would have exceeded the cap.

This is the centerpiece of xtc's ‘predictable behaviour under stress’ discipline: every resource that grows under load (memory, FDs, in-flight requests) must be charged to a res accountant so the cap holds.

xtc_res_t res;
xtc_res_caps_t caps = XTC_RES_CAPS_DEFAULT;
caps.mem_bytes = 100 * 1024 * 1024;       /* 100 MiB */
caps.tasks     = 10000;
caps.fds       = 4096;

xtc_res_init(&res, &caps);

/* Charge memory before allocating. */
if (xtc_res_acquire(&res, XTC_RES_MEM_BYTES, sz) != XTC_OK)
    return XTC_E_RESOURCE;
ptr = malloc(sz);
if (!ptr) {
    xtc_res_release(&res, XTC_RES_MEM_BYTES, sz);
    return XTC_E_NOMEM;
}

/* When done: */
free(ptr);
xtc_res_release(&res, XTC_RES_MEM_BYTES, sz);

xtc_slab(3), xtc_log(3), xtc(7)

Appeared in xtc 0.1.

May 28, 2026 Debian

View the mdoc source