Click
Loading...
Searching...
No Matches
timerset.hh
1// -*- related-file-name: "../../lib/timerset.cc" -*-
2#ifndef CLICK_TIMERSET_HH
3#define CLICK_TIMERSET_HH 1
4#include <click/timer.hh>
5#include <click/sync.hh>
6#include <click/vector.hh>
7CLICK_DECLS
8class Router;
9class RouterThread;
10class Timer;
11
12class TimerSet { public:
13
14 TimerSet();
15
16 Timestamp timer_expiry_steady() const { return _timer_expiry; }
17 inline Timestamp timer_expiry_steady_adjusted() const;
18#if CLICK_USERLEVEL
19 inline int next_timer_delay(bool more_tasks, Timestamp &t) const;
20#endif
21
22 Timer *next_timer(); // useful for benchmarking
23
24 unsigned max_timer_stride() const { return _max_timer_stride; }
25 unsigned timer_stride() const { return _timer_stride; }
26 void set_max_timer_stride(unsigned timer_stride);
27
28 void kill_router(Router *router);
29
30 void run_timers(RouterThread *thread, Master *master);
31
32 inline void fence();
33
34 private:
35
36 struct heap_element {
37 Timestamp expiry_s;
38 Timer *t;
39#if SIZEOF_VOID_P == 4
40 uint32_t padding; /* the structure should have size 16 */
41#endif
42 heap_element(Timer *t_)
43 : expiry_s(t_->expiry_steady()), t(t_) {
44 }
45 };
46 struct heap_less {
47 inline bool operator()(const heap_element &a, const heap_element &b) {
48 return a.expiry_s < b.expiry_s;
49 }
50 };
51 struct heap_place {
52 inline void operator()(heap_element *begin, heap_element *t) {
53 t->t->_schedpos1 = (t - begin) + 1;
54 }
55 };
56
57 // Most likely _timer_expiry now fits in a cache line
58 Timestamp _timer_expiry CLICK_ALIGNED(8);
59
60 unsigned _max_timer_stride;
61 unsigned _timer_stride;
62 unsigned _timer_count;
63 Vector<heap_element> _timer_heap;
64 Vector<Timer *> _timer_runchunk;
65 SimpleSpinlock _timer_lock;
66#if CLICK_LINUXMODULE
67 struct task_struct *_timer_task;
68#elif HAVE_MULTITHREAD
69 click_processor_t _timer_processor;
70#endif
71 Timestamp _timer_check;
72 uint32_t _timer_check_reports;
73
74 inline void run_one_timer(Timer *);
75
76 void set_timer_expiry() {
77 if (_timer_heap.size())
78 _timer_expiry = _timer_heap.unchecked_at(0).expiry_s;
79 else
80 _timer_expiry = Timestamp();
81 }
82 void check_timer_expiry(Timer *t);
83
84 inline void lock_timers();
85 inline bool attempt_lock_timers();
86 inline void unlock_timers();
87
88 friend class Timer;
89
90};
91
92inline Timestamp
93TimerSet::timer_expiry_steady_adjusted() const
94{
95 Timestamp e = _timer_expiry;
96#if TIMESTAMP_WARPABLE
97 if (likely(!Timestamp::warp_jumping())) {
98#endif
99 if (_timer_stride >= 8 || !e)
100 /* do nothing */;
101 else if (_timer_stride >= 4)
102 e -= Timer::adjustment();
103 else
105#if TIMESTAMP_WARPABLE
106 }
107#endif
108 return e;
109}
110
111inline void
112TimerSet::lock_timers()
113{
114#if CLICK_LINUXMODULE
115 if (current != _timer_task)
116 _timer_lock.acquire();
117#elif HAVE_MULTITHREAD
118 if (click_current_processor() != _timer_processor)
119 _timer_lock.acquire();
120#endif
121}
122
123inline bool
124TimerSet::attempt_lock_timers()
125{
126#if CLICK_LINUXMODULE || HAVE_MULTITHREAD
127 return _timer_lock.attempt();
128#else
129 return true;
130#endif
131}
132
133inline void
134TimerSet::unlock_timers()
135{
136#if CLICK_LINUXMODULE
137 if (current != _timer_task)
138 _timer_lock.release();
139#elif HAVE_MULTITHREAD
140 if (click_current_processor() != _timer_processor)
141 _timer_lock.release();
142#endif
143}
144
145inline void
146TimerSet::fence()
147{
148 lock_timers();
149 unlock_timers();
150}
151
152inline Timer *
153TimerSet::next_timer()
154{
155 lock_timers();
156 Timer *t = _timer_heap.empty() ? 0 : _timer_heap.unchecked_at(0).t;
157 unlock_timers();
158 return t;
159}
160
161CLICK_ENDDECLS
162#endif
A router configuration.
Definition router.hh:28
A set of Tasks scheduled on the same CPU.
Definition routerthread.hh:32
A non-recursive spinlock for SMP Click threads.
Definition sync.hh:587
bool attempt()
Attempts to acquire the SimpleSpinlock.
Definition sync.hh:648
void release()
Releases the SimpleSpinlock.
Definition sync.hh:665
void acquire()
Acquires the SimpleSpinlock.
Definition sync.hh:628
Triggers execution at a given time.
Definition timer.hh:14
static Timestamp adjustment()
Return an adjustment interval useful for precise timers.
Definition timer.hh:307
Represents a moment or interval in time.
Definition timestamp.hh:125
Vector template.
Definition vector.hh:111
bool empty() const
Test if the vector is empty (size() == 0).
Definition vector.hh:237
T & unchecked_at(size_type i)
Return a reference to the ith element.
Definition vector.hh:350
size_type size() const
Return the number of elements.
Definition vector.hh:231
Classes for synchronizing among multiple CPUs, particularly in the Linux kernel.
Support for Timer, which triggers execution at a given time.
Click's vector container template.