libxtc 0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
xtc_credit.h
1/*-
2 * Copyright (c) 2026, The XTC Project
3 * Use of this source code is governed by the ISC License.
4 *
5 * src/inc/xtc_credit.h
6 * A sliding-window credit regulator: cap the number of operations a
7 * producer keeps IN FLIGHT (outstanding, un-acknowledged) at once.
8 * Take a credit before issuing an operation, return it when the
9 * operation's acknowledgement comes back; when credits are exhausted
10 * the producer blocks (as a fiber) until an ack frees one.
11 *
12 * This is the credit-based flow-control pattern, transport-agnostic:
13 * it works over a request/reply RPC to another process, over socket
14 * writes, over disk operations -- anywhere a fast issuer can outrun a
15 * slower acknowledger. The demand channel (xtc_chan_demand) is its
16 * producer/consumer-channel sibling; this regulator is for the
17 * request-issue/ack-return sliding window.
18 *
19 * Precedent: Erlang's :jobs regulator, RabbitMQ credit_flow, and
20 * GenStage's max_demand/min_demand all express exactly this window.
21 * OTP has no single named behaviour for it -- it is a gen_server plus
22 * an integer counter -- which is what this regulator packages, with
23 * peak-in-flight observability the hand-rolled version drops.
24 *
25 * Built on xtc_sem (the credits ARE semaphore units), so a producer
26 * running inside a fiber parks its fiber (not the OS thread) while
27 * waiting for a credit.
28 */
29
30#ifndef XTC_CREDIT_H
31#define XTC_CREDIT_H
32
33#include <stddef.h>
34#include <stdint.h>
35
36#include "xtc.h"
37
38typedef struct xtc_credit xtc_credit_t;
39
40/*
41 * PUBLIC: int xtc_credit_create __P((unsigned, xtc_credit_t **));
42 * PUBLIC: void xtc_credit_destroy __P((xtc_credit_t *));
43 * PUBLIC: int xtc_credit_acquire __P((xtc_credit_t *, int64_t));
44 * PUBLIC: int xtc_credit_try_acquire __P((xtc_credit_t *));
45 * PUBLIC: int xtc_credit_release __P((xtc_credit_t *));
46 * PUBLIC: unsigned xtc_credit_in_flight __P((const xtc_credit_t *));
47 * PUBLIC: unsigned xtc_credit_peak __P((const xtc_credit_t *));
48 * PUBLIC: unsigned xtc_credit_window __P((const xtc_credit_t *));
49 */
50
51/* Create a regulator with a window of `window` credits (max operations
52 * in flight). window must be > 0. */
53int xtc_credit_create(unsigned window, xtc_credit_t **out);
54void xtc_credit_destroy(xtc_credit_t *c);
55
56/* Take one credit before issuing an operation, blocking the calling
57 * fiber until one is free or `timeout_ns` elapses (XTC_E_AGAIN).
58 * timeout_ns == 0 tries once; a negative timeout blocks indefinitely. */
59int xtc_credit_acquire(xtc_credit_t *c, int64_t timeout_ns);
60
61/* Take one credit if immediately available (XTC_E_AGAIN otherwise). */
62int xtc_credit_try_acquire(xtc_credit_t *c);
63
64/* Return one credit when an operation's acknowledgement arrives,
65 * unblocking one waiter. XTC_E_INVAL if it would exceed the window
66 * (a release without a matching acquire is a bug in the caller). */
67int xtc_credit_release(xtc_credit_t *c);
68
69/* Operations currently in flight (acquired but not yet released). */
70unsigned xtc_credit_in_flight(const xtc_credit_t *c);
71
72/* Peak in-flight observed since creation (the high-water mark; useful
73 * for tuning the window). */
74unsigned xtc_credit_peak(const xtc_credit_t *c);
75
76/* The configured window size. */
77unsigned xtc_credit_window(const xtc_credit_t *c);
78
79#endif /* XTC_CREDIT_H */