Click
Loading...
Searching...
No Matches
timerwheel.hh
1#ifndef CLICK_TIMERWHEEL_HH
2#define CLICK_TIMERWHEEL_HH 1
3
4#include <click/algorithm.hh>
5
6CLICK_DECLS
7
8template <typename T>
9class TimerWheel {
10 public:
11 TimerWheel() : _index(0) {
12 }
13
14 void initialize(int max) {
15 max = next_pow2(max + 2);
16 _mask = max - 1;
17 _buckets.resize(max, 0);
18 }
19
24 inline void schedule_after(T* obj, uint32_t timeout, const std::function<void(T*,T*)> setter) {
25 assert(timeout > 0); //Likely a bug
26 assert(timeout < _mask);
27 unsigned id = ((*(volatile uint32_t*)&_index) + timeout) & _mask;
28
29 //click_chatter("Enqueue %p at %d", obj, id);
30 T* f = _buckets.unchecked_at(id);
31 setter(obj,f);
32
33 _buckets.unchecked_at(id) = obj;
34 }
35
36 inline void schedule_after_mp(T* obj, uint32_t timeout, const std::function<void(T*,T*)> setter) {
37 _writers_lock.acquire();
38 unsigned id = ((*(volatile uint32_t*)&_index) + timeout) & _mask;
39
40 //click_chatter("Enqueuemp %p at %d", obj, id);
41 T* f = _buckets.unchecked_at(id);
42 setter(obj,f);
43 _buckets.unchecked_at(id) = obj;
44 //click_write_fence(); done by release()
45 _writers_lock.release();
46 }
47
51 inline void run_timers(std::function<T*(T*)> expire) {
52 T* f = _buckets.unchecked_at((_index) & _mask);
53 //click_chatter("Expire %d -> %d (_mask %d)", _index, _index & _mask, _mask);
54 while (f != 0) {
55 f = expire(f);
56 }
57 _buckets.unchecked_at((_index) & _mask) = 0;
58 _index++;
59 }
60
61 bool debug_find(T*obj, std::function<T*(T*)> next ) {
62 int id = _index;
63 for (int i =0; i <= _mask; i++) {
64 T* a = _buckets[(id + i) & _mask];
65 while(a) {
66 if (a == obj)
67 return true;
68 a = next(a);
69 }
70 }
71 return false;
72 }
73
74 private:
75 uint32_t _mask;
76 uint32_t _index;
77 Vector<T*> _buckets;
78 Spinlock _writers_lock;
79};
80
81CLICK_ENDDECLS
82#endif
A recursive spinlock for SMP Click threads.
Definition sync.hh:439
Vector template.
Definition vector.hh:111