L4Re – L4 Runtime Environment
ipc_timeout_queue
1 // vim:set ft=cpp: -*- Mode: C++ -*-
2 /*
3  * (c) 2014 Steffen Liebergeld <steffen.liebergeld@kernkonzept.com>
4  *
5  * This file is licensed under the terms of the GNU General Public License 2.
6  * Please see the COPYING-GPL-2 file for details.
7  *
8  * As a special exception, you may use this file as part of a free software
9  * library without restriction. Specifically, if other files instantiate
10  * templates or use macros or inline functions from this file, or you compile
11  * this file and link it with other files to produce an executable, this file
12  * does not by itself cause the resulting executable to be covered by the GNU
13  * General Public License. This exception does not however invalidate any other
14  * reasons why the executable file might be covered by the GNU General Public
15  * License.
16  */
17 #pragma once
18 
19 #include <l4/cxx/hlist>
20 #include <l4/sys/cxx/ipc_server_loop>
21 
22 namespace L4 { namespace Ipc_svr {
23 
28 class Timeout : public cxx::H_list_item
29 {
30  friend class Timeout_queue;
31 public:
33  Timeout() : _timeout(0) {}
34 
36  virtual ~Timeout() = 0;
37 
44  virtual void expired() = 0;
45 
53  { return _timeout; }
54 
55 private:
56  l4_kernel_clock_t _timeout;
57 };
58 
59 inline Timeout::~Timeout() {}
60 
66 {
67 public:
70 
76  {
77  if (auto e = _timeouts.front())
78  return e->timeout();
79 
80  return 0;
81  }
82 
92  {
94  return (next != 0) && (next <= now);
95  }
96 
102  {
103  while (!_timeouts.empty())
104  {
105  Queue::Iterator top = _timeouts.begin();
106  if ((*top)->_timeout > now)
107  return;
108 
109  Timeout *t = *top;
110  top = _timeouts.erase(top);
111  t->expired();
112  }
113  }
114 
121  void add(Timeout *timeout, l4_kernel_clock_t time)
122  {
123  timeout->_timeout = time;
124  Queue::Iterator i = _timeouts.begin();
125  while (i != _timeouts.end() && (*i)->timeout() < time)
126  ++i;
127 
128  _timeouts.insert_before(timeout, i);
129  }
130 
136  void remove(Timeout *timeout)
137  {
138  _timeouts.remove(timeout);
139  }
140 
141 private:
142  typedef cxx::H_list<Timeout> Queue;
143  Queue _timeouts;
144 };
145 
159 template< typename HOOKS, typename BR_MAN = Br_manager_no_buffers >
160 class Timeout_queue_hooks : public BR_MAN
161 {
162  l4_kernel_clock_t _now()
163  { return static_cast<HOOKS*>(this)->now(); }
164 
165  unsigned _timeout_br()
166  { return this->first_free_br(); }
167 
168 public:
171  {
173  if (t)
174  return l4_timeout(L4_IPC_TIMEOUT_0, l4_timeout_abs(t, _timeout_br()));
175  return L4_IPC_SEND_TIMEOUT_0;
176  }
177 
180  {
181  // we must handle the timer only when called after a possible reply
182  // otherwise we probably destroy the reply message.
183  if (mode == L4::Ipc_svr::Reply_separate)
184  {
185  l4_kernel_clock_t now = _now();
186  if (queue.timeout_expired(now))
188  }
189 
190  BR_MAN::setup_wait(utcb, mode);
191  }
192 
195  {
196  // split up reply and wait when a timeout has expired
197  if (queue.timeout_expired(_now()))
200  }
201 
213  {
214  queue.add(timeout, time);
215  return 0;
216  }
217 
226  {
228  return 0;
229  }
230 
232 };
233 
234 }}
unsigned first_free_br() const
Returns 1 as first free buffer.
Loop hooks mixin for integrating a timeout queue into the server loop.
L4::Ipc_svr::Reply_mode before_reply(l4_msgtag_t, l4_utcb_t *)
server loop hook
void setup_wait(l4_utcb_t *utcb, L4::Ipc_svr::Reply_mode mode)
setup_wait() for the server loop
int remove_timeout(Timeout *timeout)
Remove timeout from the queue.
l4_timeout_t timeout()
get the time for the next timeout
Timeout_queue queue
Use this timeout queue.
int add_timeout(Timeout *timeout, l4_kernel_clock_t time)
Add a timout to the queue for time time.
Timeout queue to be used in l4re server loop.
void remove(Timeout *timeout)
Remove timeout from the queue.
L4::Ipc_svr::Timeout Timeout
Provide a local definition of Timeout for backward compat.
l4_kernel_clock_t next_timeout() const
Get the time for the next timeout.
void handle_expired_timeouts(l4_kernel_clock_t now)
run the callbacks of expired timeouts
bool timeout_expired(l4_kernel_clock_t now) const
Determine if a timeout has happened.
void add(Timeout *timeout, l4_kernel_clock_t time)
Add a timeout to the queue.
Callback interface for Timeout_queue.
virtual void expired()=0
callback function to be called when timeout happened
virtual ~Timeout()=0
Destroy a timeout.
Timeout()
Make a timeout.
l4_kernel_clock_t timeout() const
return absolute timeout of this callback.
Const_iterator end() const
Return a const iterator to the end of the list.
Definition: list_basics.h:150
bool empty() const
Check if the list is empty.
Definition: list_basics.h:126
Iterator begin()
Return an iterator to the beginning of the list.
Definition: list_basics.h:138
Value_type front() const
Return the first element in the list.
Definition: list_basics.h:128
Basic element type for a double-linked H_list.
Definition: hlist:34
static Iterator erase(Iterator const &e)
Remove the element at the given iterator position.
Definition: hlist:247
static void insert_before(T *e, Iterator const &succ)
Insert an element before the iterator position.
Definition: hlist:191
static void remove(T *e)
Remove the given element from its list.
Definition: hlist:231
Reply_mode
Reply mode for server loop.
Definition: ipc_server_loop:51
@ Reply_separate
Server shall call reply and wait separately.
Definition: ipc_server_loop:53
@ Reply_compound
Server shall use a compound reply and wait (fast).
Definition: ipc_server_loop:52
l4_uint64_t l4_kernel_clock_t
Kernel clock type.
Definition: l4int.h:64
#define L4_IPC_TIMEOUT_0
Timeout constants.
Definition: __timeout.h:79
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:198
l4_timeout_s l4_timeout_abs(l4_kernel_clock_t pint, int br) L4_NOTHROW
Set an absolute timeout.
Definition: utcb.h:383
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
Definition: utcb.h:67
L4 low-level kernel interface.
Message tag data structure.
Definition: types.h:160
Timeout pair.
Definition: __timeout.h:59