Monotonic token bucket rate limiter in portable C
C
#define _POSIX_C_SOURCE 200809L
#include <time.h>
typedef struct { double tokens, rate, cap; struct timespec last; } Bucket;
void tb_init(Bucket *b, double rate, double cap) {
b->tokens = b->cap = cap;
b->rate = rate;
clock_gettime(CLOCK_MONOTONIC, &b->last);
}
int tb_allow(Bucket *b, double cost) {
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
double elapsed = (now.tv_sec - b->last.tv_sec)
+ (now.tv_nsec - b->last.tv_nsec) / 1e9;
b->last = now;
b->tokens += elapsed * b->rate;
if (b->tokens > b->cap) b->tokens = b->cap;
if (b->tokens < cost) return 0;
b->tokens -= cost;
return 1;
}