L4Re - L4 Runtime Environment
ipc_timeout_queue
1 // vim: ft=cpp:
2 /*
3  * (c) 2014 Steffen Liebergeld <steffen.liebergeld@kernkonzept.com>
4  *
5  * This file is licensed under the terms of the GNU Lesser General Public
6  * License 2.1.
7  * See file COPYING-LGPL-2.1 for details.
8  */
9 #pragma once
10 
11 #include <l4/cxx/hlist>
12 #include <l4/sys/cxx/ipc_server_loop>
13 
14 namespace L4 { namespace Ipc_svr {
15 
20 class Timeout : public cxx::H_list_item
21 {
22  friend class Timeout_queue;
23 public:
25  Timeout() : _timeout(0) {}
26 
28  virtual ~Timeout() = 0;
29 
35  virtual void expired() = 0;
36 
44  { return _timeout; }
45 
46 private:
47  l4_kernel_clock_t _timeout;
48 };
49 
50 inline Timeout::~Timeout() {}
51 
57 {
58 public:
61 
67  {
68  if (auto e = _timeouts.front())
69  return e->timeout();
70 
71  return 0;
72  }
73 
83  {
84  l4_kernel_clock_t next = next_timeout();
85  return (next != 0) && (next <= now);
86  }
87 
93  {
94  while (!_timeouts.empty())
95  {
96  Queue::Iterator top = _timeouts.begin();
97  if ((*top)->_timeout > now)
98  return;
99 
100  Timeout *t = *top;
101  top = _timeouts.erase(top);
102  t->expired();
103  }
104  }
105 
112  void add(Timeout *timeout, l4_kernel_clock_t time)
113  {
114  timeout->_timeout = time;
115  Queue::Iterator i = _timeouts.begin();
116  while (i != _timeouts.end() && (*i)->timeout() < time)
117  ++i;
118 
119  _timeouts.insert_before(timeout, i);
120  }
121 
127  void remove(Timeout *timeout)
128  {
129  _timeouts.remove(timeout);
130  }
131 
132 private:
133  typedef cxx::H_list<Timeout> Queue;
134  Queue _timeouts;
135 };
136 
150 template< typename HOOKS, typename BR_MAN = Br_manager_no_buffers >
151 class Timeout_queue_hooks : public BR_MAN
152 {
153  l4_kernel_clock_t _now()
154  { return static_cast<HOOKS*>(this)->now(); }
155 
156  unsigned _timeout_br()
157  { return this->first_free_br(); }
158 
159 public:
162  {
163  l4_kernel_clock_t t = queue.next_timeout();
164  if (t)
165  return l4_timeout(L4_IPC_TIMEOUT_0, l4_timeout_abs(t, _timeout_br()));
166  return L4_IPC_SEND_TIMEOUT_0;
167  }
168 
171  {
172  // we must handle the timer only when called after a possible reply
173  // otherwise we probably destroy the reply message.
174  if (mode == L4::Ipc_svr::Reply_separate)
175  {
176  l4_kernel_clock_t now = _now();
177  if (queue.timeout_expired(now))
178  queue.handle_expired_timeouts(now);
179  }
180 
181  BR_MAN::setup_wait(utcb, mode);
182  }
183 
186  {
187  // split up reply and wait when a timeout has expired
188  if (queue.timeout_expired(_now()))
191  }
192 
204  {
205  queue.add(timeout, time);
206  return 0;
207  }
208 
217  {
218  queue.remove(timeout);
219  return 0;
220  }
221 
223 };
224 
225 }}
l4_timeout_t l4_timeout(l4_timeout_s snd, l4_timeout_s rcv) L4_NOTHROW
Combine send and receive timeout in a timeout.
Definition: __timeout.h:221
Reply_mode
Reply mode for server loop.
Definition: ipc_server_loop:50
Server shall call reply and wait separately.
Definition: ipc_server_loop:53
L4::Ipc_svr::Reply_mode before_reply(l4_msgtag_t, l4_utcb_t *)
server loop hook
void handle_expired_timeouts(l4_kernel_clock_t now)
run the callbacks of expired timeouts
Timeout queue to be used in l4re server loop.
L4 low-level kernel interface.
L4::Ipc_svr::Timeout Timeout
Provide a local definition of Timeout for backward compat.
void setup_wait(l4_utcb_t *utcb, L4::Ipc_svr::Reply_mode mode)
setup_wait() for the server loop
l4_kernel_clock_t timeout() const
return absolute timeout of this callback.
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
Definition: utcb.h:67
Callback interface for Timeout_queue.
Timeout pair.
Definition: __timeout.h:57
l4_timeout_s l4_timeout_abs(l4_kernel_clock_t pint, int br) L4_NOTHROW
Set an absolute timeout.
Definition: utcb.h:383
l4_kernel_clock_t next_timeout() const
Get the time for the next timeout.
bool timeout_expired(l4_kernel_clock_t now) const
Determine if a timeout has happened.
virtual ~Timeout()=0
Destroy a timeout.
Basic element type for a double-linked H_list.
Definition: hlist:33
l4_uint64_t l4_kernel_clock_t
Kernel clock type.
Definition: l4int.h:65
Timeout_queue queue
Use this timeout queue.
virtual void expired()=0
callback function to be called when timeout happened
int add_timeout(Timeout *timeout, l4_kernel_clock_t time)
Add a timout to the queue for time time.
l4_timeout_t timeout()
get the time for the next timeout
int remove_timeout(Timeout *timeout)
Remove timeout from the queue.
#define L4_IPC_SEND_TIMEOUT_0
0 send timeout
Definition: __timeout.h:82
Timeout()
Make a timeout.
void add(Timeout *timeout, l4_kernel_clock_t time)
Add a timeout to the queue.
#define L4_IPC_TIMEOUT_0
Timeout constants.
Definition: __timeout.h:77
Message tag data structure.
Definition: types.h:158
Loop hooks mixin for integrating a timeout queue into the server loop.
Server shall use a compound reply and wait (fast).
Definition: ipc_server_loop:52