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 "xtc_export.h"
34
35#include <stddef.h>
36#include <stdint.h>
37
38#include "xtc.h"
39
40typedef struct xtc_credit xtc_credit_t;
41
42/*
43 * PUBLIC: int xtc_credit_create __P((unsigned, xtc_credit_t **));
44 * PUBLIC: void xtc_credit_destroy __P((xtc_credit_t *));
45 * PUBLIC: int xtc_credit_acquire __P((xtc_credit_t *, int64_t));
46 * PUBLIC: int xtc_credit_try_acquire __P((xtc_credit_t *));
47 * PUBLIC: int xtc_credit_release __P((xtc_credit_t *));
48 * PUBLIC: unsigned xtc_credit_in_flight __P((const xtc_credit_t *));
49 * PUBLIC: unsigned xtc_credit_peak __P((const xtc_credit_t *));
50 * PUBLIC: unsigned xtc_credit_window __P((const xtc_credit_t *));
51 */
52
53/* Create a regulator with a window of `window` credits (max operations
54 * in flight). window must be > 0. */
55XTC_API int xtc_credit_create(unsigned window, xtc_credit_t **out);
56XTC_API void xtc_credit_destroy(xtc_credit_t *c);
57
58/* Take one credit before issuing an operation, blocking the calling
59 * fiber until one is free or `timeout_ns` elapses (XTC_E_AGAIN).
60 * timeout_ns == 0 tries once; a negative timeout blocks indefinitely. */
61XTC_API int xtc_credit_acquire(xtc_credit_t *c, int64_t timeout_ns);
62
63/* Take one credit if immediately available (XTC_E_AGAIN otherwise). */
64XTC_API int xtc_credit_try_acquire(xtc_credit_t *c);
65
66/* Return one credit when an operation's acknowledgement arrives,
67 * unblocking one waiter. XTC_E_INVAL if it would exceed the window
68 * (a release without a matching acquire is a bug in the caller). */
69XTC_API int xtc_credit_release(xtc_credit_t *c);
70
71/* Operations currently in flight (acquired but not yet released). */
72XTC_API unsigned xtc_credit_in_flight(const xtc_credit_t *c);
73
74/* Peak in-flight observed since creation (the high-water mark; useful
75 * for tuning the window). */
76XTC_API unsigned xtc_credit_peak(const xtc_credit_t *c);
77
78/* The configured window size. */
79XTC_API unsigned xtc_credit_window(const xtc_credit_t *c);
80
81#endif /* XTC_CREDIT_H */