1 /* Copyright (c) 2018-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
6 * \brief Headers for token_bucket.c
9 #ifndef TOR_TOKEN_BUCKET_H
10 #define TOR_TOKEN_BUCKET_H
12 #include "lib/cc/torint.h"
13 #include "lib/testsupport/testsupport.h"
15 /** Largest allowable burst value for a token buffer. */
16 #define TOKEN_BUCKET_MAX_BURST INT32_MAX
18 /** A generic token buffer configuration: determines the number of tokens
19 * added to the bucket in each time unit (the "rate"), and the maximum number
20 * of tokens in the bucket (the "burst") */
21 typedef struct token_bucket_cfg_t
{
26 /** A raw token bucket, decoupled from its configuration and timestamp. */
27 typedef struct token_bucket_raw_t
{
31 void token_bucket_cfg_init(token_bucket_cfg_t
*cfg
,
35 void token_bucket_raw_adjust(token_bucket_raw_t
*bucket
,
36 const token_bucket_cfg_t
*cfg
);
38 void token_bucket_raw_reset(token_bucket_raw_t
*bucket
,
39 const token_bucket_cfg_t
*cfg
);
41 int token_bucket_raw_dec(token_bucket_raw_t
*bucket
,
44 int token_bucket_raw_refill_steps(token_bucket_raw_t
*bucket
,
45 const token_bucket_cfg_t
*cfg
,
46 const uint32_t elapsed_steps
);
48 static inline size_t token_bucket_raw_get(const token_bucket_raw_t
*bucket
);
49 /** Return the current number of bytes set in a token bucket. */
51 token_bucket_raw_get(const token_bucket_raw_t
*bucket
)
53 return bucket
->bucket
>= 0 ? bucket
->bucket
: 0;
56 /** A convenience type containing all the pieces needed for a coupled
57 * read-bucket and write-bucket that have the same rate limit, and which use
58 * "timestamp units" (see compat_time.h) for their time. */
59 typedef struct token_bucket_rw_t
{
60 token_bucket_cfg_t cfg
;
61 token_bucket_raw_t read_bucket
;
62 token_bucket_raw_t write_bucket
;
63 uint32_t last_refilled_at_timestamp
;
66 void token_bucket_rw_init(token_bucket_rw_t
*bucket
,
71 void token_bucket_rw_adjust(token_bucket_rw_t
*bucket
,
72 uint32_t rate
, uint32_t burst
);
74 void token_bucket_rw_reset(token_bucket_rw_t
*bucket
,
80 int token_bucket_rw_refill(token_bucket_rw_t
*bucket
,
83 int token_bucket_rw_dec_read(token_bucket_rw_t
*bucket
,
85 int token_bucket_rw_dec_write(token_bucket_rw_t
*bucket
,
88 int token_bucket_rw_dec(token_bucket_rw_t
*bucket
,
89 ssize_t n_read
, ssize_t n_written
);
91 static inline size_t token_bucket_rw_get_read(const token_bucket_rw_t
*bucket
);
93 token_bucket_rw_get_read(const token_bucket_rw_t
*bucket
)
95 return token_bucket_raw_get(&bucket
->read_bucket
);
98 static inline size_t token_bucket_rw_get_write(
99 const token_bucket_rw_t
*bucket
);
101 token_bucket_rw_get_write(const token_bucket_rw_t
*bucket
)
103 return token_bucket_raw_get(&bucket
->write_bucket
);
107 * A specialized bucket containing a single counter.
110 typedef struct token_bucket_ctr_t
{
111 token_bucket_cfg_t cfg
;
112 token_bucket_raw_t counter
;
113 uint32_t last_refilled_at_timestamp
;
114 } token_bucket_ctr_t
;
116 void token_bucket_ctr_init(token_bucket_ctr_t
*bucket
, uint32_t rate
,
117 uint32_t burst
, uint32_t now_ts
);
118 void token_bucket_ctr_adjust(token_bucket_ctr_t
*bucket
, uint32_t rate
,
120 void token_bucket_ctr_reset(token_bucket_ctr_t
*bucket
, uint32_t now_ts
);
121 void token_bucket_ctr_refill(token_bucket_ctr_t
*bucket
, uint32_t now_ts
);
124 token_bucket_ctr_dec(token_bucket_ctr_t
*bucket
, ssize_t n
)
126 return token_bucket_raw_dec(&bucket
->counter
, n
);
130 token_bucket_ctr_get(const token_bucket_ctr_t
*bucket
)
132 return token_bucket_raw_get(&bucket
->counter
);
135 #ifdef TOKEN_BUCKET_PRIVATE
137 /* To avoid making the rates too small, we consider units of "steps",
138 * where a "step" is defined as this many timestamp ticks. Keep this
139 * a power of two if you can. */
140 #define TICKS_PER_STEP 16
142 STATIC
uint32_t rate_per_sec_to_rate_per_step(uint32_t rate
);
144 #endif /* defined(TOKEN_BUCKET_PRIVATE) */
146 #endif /* !defined(TOR_TOKEN_BUCKET_H) */