CppCommon  1.0.4.1
C++ Common Library
token_bucket.cpp
Go to the documentation of this file.
1 
10 
11 #include "time/timestamp.h"
12 
13 namespace CppCommon {
14 
15 bool TokenBucket::Consume(uint64_t tokens)
16 {
17  uint64_t now = Timestamp::nano();
18  uint64_t delay = tokens * _time_per_token.load(std::memory_order_relaxed);
19  uint64_t minTime = now - _time_per_burst.load(std::memory_order_relaxed);
20  uint64_t oldTime = _time.load(std::memory_order_relaxed);
21  uint64_t newTime = oldTime;
22 
23  // Previous consume performed long time ago... Shift the new time to the start of a new burst.
24  if (minTime > oldTime)
25  newTime = minTime;
26 
27  // Lock-free token consume loop
28  for (;;)
29  {
30  // Consume tokens
31  newTime += delay;
32 
33  // No more tokens left in the bucket
34  if (newTime > now)
35  return false;
36 
37  // Try to update the current time atomically
38  if (_time.compare_exchange_weak(oldTime, newTime, std::memory_order_relaxed, std::memory_order_relaxed))
39  return true;
40 
41  // Failed... Then retry consume tokens with a new time value
42  newTime = oldTime;
43  }
44 }
45 
46 } // namespace CppCommon
static uint64_t nano()
Get the high resolution timestamp.
Definition: timestamp.cpp:153
bool Consume(uint64_t tokens=1)
Try to consume the given count of tokens.
C++ Common project definitions.
Definition: token_bucket.h:15
Timestamp definition.
Token bucket rate limit algorithm definition.