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