+#define DO_RATE_LIMIT(do_lock, rate, time_masked, amt_in_pkt, limit_ns_per_pkt, matchbool) do { \
+if (rate) { \
+ do_lock; \
+ int64_t bucket_pkts = (rate->sent_time & (~RATE_TIME_MASK)) >> (64 - RATE_BUCKET_BITS); \
+ /* We mask the top 12 bits, so date overflows every 52 days, handled below */ \
+ int64_t time_diff = time_masked - ((int64_t)(rate->sent_time & RATE_TIME_MASK)); \
+ if (unlikely(time_diff < -1000000000 || time_diff > 16000000000)) { \
+ bucket_pkts = 0; \
+ } else { \
+ if (unlikely(time_diff < 0)) { time_diff = 0; } \
+ int64_t pkts_since_last = (time_diff << RATE_BUCKET_BITS) * ((uint64_t)amt_in_pkt) / ((uint64_t)limit_ns_per_pkt); \
+ bucket_pkts -= pkts_since_last; \
+ } \
+ if (bucket_pkts < (((1 << RATE_BUCKET_INTEGER_BITS) - 1) << RATE_BUCKET_DECIMAL_BITS)) { \
+ if (unlikely(bucket_pkts < 0)) bucket_pkts = 0; \
+ rate->sent_time = time_masked | ((bucket_pkts + (1 << RATE_BUCKET_DECIMAL_BITS)) << (64 - RATE_BUCKET_BITS)); \
+ matchbool = 0; \
+ } else { \
+ matchbool = 1; \
+ } \
+} \
+} while(0);