Loading...
Searching...
No Matches
ipc_timeout_queue
// vim:set ft=cpp: -*- Mode: C++ -*-
/*
* (c) 2014 Steffen Liebergeld <steffen.liebergeld@kernkonzept.com>
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include <l4/cxx/hlist>
#include <l4/sys/cxx/ipc_server_loop>
namespace L4 { namespace Ipc_svr {
class Timeout : public cxx::H_list_item
{
friend class Timeout_queue;
public:
Timeout() : _timeout(0) {}
virtual ~Timeout() = 0;
virtual void expired() = 0;
l4_kernel_clock_t timeout() const
{ return _timeout; }
private:
l4_kernel_clock_t _timeout;
};
inline Timeout::~Timeout() {}
class Timeout_queue
{
public:
typedef L4::Ipc_svr::Timeout Timeout;
l4_kernel_clock_t next_timeout() const
{
if (auto e = _timeouts.front())
return e->timeout();
return 0;
}
bool timeout_expired(l4_kernel_clock_t now) const
{
l4_kernel_clock_t next = next_timeout();
return (next != 0) && (next <= now);
}
void handle_expired_timeouts(l4_kernel_clock_t now)
{
while (!_timeouts.empty())
{
Queue::Iterator top = _timeouts.begin();
if ((*top)->_timeout > now)
return;
Timeout *t = *top;
top = _timeouts.erase(top);
t->expired();
}
}
void add(Timeout *timeout, l4_kernel_clock_t time)
{
timeout->_timeout = time;
Queue::Iterator i = _timeouts.begin();
while (i != _timeouts.end() && (*i)->timeout() < time)
++i;
_timeouts.insert_before(timeout, i);
}
void remove(Timeout *timeout)
{
_timeouts.remove(timeout);
}
private:
typedef cxx::H_list<Timeout> Queue;
Queue _timeouts;
};
template< typename HOOKS, typename BR_MAN = Br_manager_no_buffers >
class Timeout_queue_hooks : public BR_MAN
{
l4_kernel_clock_t _now()
{ return static_cast<HOOKS*>(this)->now(); }
unsigned _timeout_br()
{ return this->first_free_br(); }
public:
l4_timeout_t timeout()
{
l4_kernel_clock_t t = queue.next_timeout();
if (t)
return l4_timeout(L4_IPC_TIMEOUT_0, l4_timeout_abs(t, _timeout_br()));
return L4_IPC_SEND_TIMEOUT_0;
}
void setup_wait(l4_utcb_t *utcb, L4::Ipc_svr::Reply_mode mode)
{
// we must handle the timer only when called after a possible reply
// otherwise we probably destroy the reply message.
if (mode == L4::Ipc_svr::Reply_separate)
{
l4_kernel_clock_t now = _now();
if (queue.timeout_expired(now))
queue.handle_expired_timeouts(now);
}
BR_MAN::setup_wait(utcb, mode);
}
L4::Ipc_svr::Reply_mode before_reply(l4_msgtag_t, l4_utcb_t *)
{
// split up reply and wait when a timeout has expired
if (queue.timeout_expired(_now()))
return L4::Ipc_svr::Reply_separate;
return L4::Ipc_svr::Reply_compound;
}
int add_timeout(Timeout *timeout, l4_kernel_clock_t time) override
{
queue.add(timeout, time);
return 0;
}
int remove_timeout(Timeout *timeout) override
{
queue.remove(timeout);
return 0;
}
Timeout_queue queue;
};
}}
L4::Ipc_svr::Br_manager_no_buffers::first_free_br
unsigned first_free_br() const
Returns 1 as first free buffer.
Definition ipc_server_loop:265
L4::Ipc_svr::Timeout_queue_hooks
Loop hooks mixin for integrating a timeout queue into the server loop.
Definition ipc_timeout_queue:151
L4::Ipc_svr::Timeout_queue_hooks::add_timeout
int add_timeout(Timeout *timeout, l4_kernel_clock_t time) override
Add a timeout to the queue for time time.
Definition ipc_timeout_queue:202
L4::Ipc_svr::Timeout_queue_hooks::before_reply
L4::Ipc_svr::Reply_mode before_reply(l4_msgtag_t, l4_utcb_t *)
server loop hook
Definition ipc_timeout_queue:184
L4::Ipc_svr::Timeout_queue_hooks::remove_timeout
int remove_timeout(Timeout *timeout) override
Remove timeout from the queue.
Definition ipc_timeout_queue:215
L4::Ipc_svr::Timeout_queue_hooks::setup_wait
void setup_wait(l4_utcb_t *utcb, L4::Ipc_svr::Reply_mode mode)
setup_wait() for the server loop
Definition ipc_timeout_queue:169
L4::Ipc_svr::Timeout_queue_hooks::timeout
l4_timeout_t timeout()
get the time for the next timeout
Definition ipc_timeout_queue:160
L4::Ipc_svr::Timeout_queue_hooks::queue
Timeout_queue queue
Use this timeout queue.
Definition ipc_timeout_queue:221
L4::Ipc_svr::Timeout_queue
Timeout queue to be used in l4re server loop.
Definition ipc_timeout_queue:56
L4::Ipc_svr::Timeout_queue::remove
void remove(Timeout *timeout)
Remove timeout from the queue.
Definition ipc_timeout_queue:126
L4::Ipc_svr::Timeout_queue::Timeout
L4::Ipc_svr::Timeout Timeout
Provide a local definition of Timeout for backward compatibility.
Definition ipc_timeout_queue:59
L4::Ipc_svr::Timeout_queue::next_timeout
l4_kernel_clock_t next_timeout() const
Get the time for the next timeout.
Definition ipc_timeout_queue:65
L4::Ipc_svr::Timeout_queue::handle_expired_timeouts
void handle_expired_timeouts(l4_kernel_clock_t now)
run the callbacks of expired timeouts
Definition ipc_timeout_queue:91
L4::Ipc_svr::Timeout_queue::timeout_expired
bool timeout_expired(l4_kernel_clock_t now) const
Determine if a timeout has happened.
Definition ipc_timeout_queue:81
L4::Ipc_svr::Timeout_queue::add
void add(Timeout *timeout, l4_kernel_clock_t time)
Add a timeout to the queue.
Definition ipc_timeout_queue:111
L4::Ipc_svr::Timeout
Callback interface for Timeout_queue.
Definition ipc_timeout_queue:19
L4::Ipc_svr::Timeout::expired
virtual void expired()=0
callback function to be called when timeout happened
L4::Ipc_svr::Timeout::~Timeout
virtual ~Timeout()=0
Destroy a timeout.
Definition ipc_timeout_queue:49
L4::Ipc_svr::Timeout::Timeout
Timeout()
Make a timeout.
Definition ipc_timeout_queue:23
L4::Ipc_svr::Timeout::timeout
l4_kernel_clock_t timeout() const
return absolute timeout of this callback.
Definition ipc_timeout_queue:42
cxx::H_list
General double-linked list of unspecified cxx::H_list_item elements.
Definition hlist:70
L4::Ipc_svr::Reply_mode
Reply_mode
Reply mode for server loop.
Definition ipc_server_loop:47
L4::Ipc_svr::Reply_separate
@ Reply_separate
Server shall call reply and wait separately.
Definition ipc_server_loop:49
L4::Ipc_svr::Reply_compound
@ Reply_compound
Server shall use a compound reply and wait (fast).
Definition ipc_server_loop:48
l4_kernel_clock_t
l4_uint64_t l4_kernel_clock_t
Kernel clock type.
Definition l4int.h:53
L4_IPC_TIMEOUT_0
#define L4_IPC_TIMEOUT_0
Timeout constants.
Definition __timeout.h:73
L4_IPC_SEND_TIMEOUT_0
#define L4_IPC_SEND_TIMEOUT_0
0 send timeout
Definition __timeout.h:78
l4_timeout
L4_CONSTEXPR 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:213
l4_timeout_abs
l4_timeout_s l4_timeout_abs(l4_kernel_clock_t pint, int br) L4_NOTHROW
Set an absolute timeout.
Definition utcb.h:389
l4_utcb_t
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
Definition utcb.h:56
L4::Ipc_svr
Helper classes for L4::Server instantiation.
Definition ipc_epiface:25
L4
L4 low-level kernel interface.
Definition l4sys-l4f-groups.dox:50
cxx::H_list_item
H_list_item_t< void > H_list_item
Untyped list item.
Definition hlist:61
l4_msgtag_t
Message tag data structure.
Definition types.h:154
l4_timeout_t
Timeout pair.
Definition __timeout.h:53