#include "Cond.h"
class Throttle {
- uint64_t count, max, waiting;
+ int64_t count, max, waiting;
Mutex lock;
Cond cond;
public:
- Throttle(uint64_t m = 0) : count(0), max(m), waiting(0),
+ Throttle(int64_t m = 0) : count(0), max(m), waiting(0),
lock("Throttle::lock") {}
private:
- void _reset_max(uint64_t m) {
+ void _reset_max(int64_t m) {
if (m < max)
cond.SignalOne();
max = m;
}
- bool _should_wait(uint64_t c) {
+ bool _should_wait(int64_t c) {
return
max &&
((c < max && count + c > max) || // normally stay under max
(c >= max && count > max)); // except for large c
}
- bool _wait(uint64_t c) {
+ bool _wait(int64_t c) {
bool waited = false;
if (_should_wait(c)) {
waiting += c;
}
public:
- uint64_t get_current() {
+ int64_t get_current() {
Mutex::Locker l(lock);
return count;
}
- uint64_t get_max() { return max; }
+ int64_t get_max() { return max; }
- bool wait(uint64_t m = 0) {
+ bool wait(int64_t m = 0) {
Mutex::Locker l(lock);
if (m)
_reset_max(m);
return _wait(0);
}
- uint64_t take(uint64_t c = 1) {
+ int64_t take(int64_t c = 1) {
Mutex::Locker l(lock);
count += c;
return count;
}
- bool get(uint64_t c = 1, uint64_t m = 0) {
+ bool get(int64_t c = 1, int64_t m = 0) {
Mutex::Locker l(lock);
if (m)
_reset_max(m);
return waited;
}
- uint64_t put(uint64_t c = 1) {
+ int64_t put(int64_t c = 1) {
Mutex::Locker l(lock);
cond.SignalOne();
count -= c;
+ assert(c>=0); //if count goes negative, we failed somewhere!
return count;
}
};