genode/repos/base/src/timer/include/session_component.h

100 lines
2.8 KiB
C++

/*
* \brief Instance of the timer session interface
* \author Norman Feske
* \author Markus Partheymueller
* \author Martin Stein
* \date 2006-08-15
*/
/*
* Copyright (C) 2006-2017 Genode Labs GmbH
* Copyright (C) 2012 Intel Corporation
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _SESSION_COMPONENT_
#define _SESSION_COMPONENT_
/* Genode includes */
#include <util/list.h>
#include <timer_session/timer_session.h>
#include <base/rpc_server.h>
#include <timer/timeout.h>
namespace Timer {
using Genode::uint64_t;
using Microseconds = Genode::Microseconds;
using Duration = Genode::Duration;
class Session_component;
}
class Timer::Session_component : public Genode::Rpc_object<Session>,
private Genode::List<Session_component>::Element,
private Genode::Timeout::Handler
{
private:
friend class Genode::List<Session_component>;
Genode::Timeout _timeout;
Genode::Timeout_scheduler &_timeout_scheduler;
Genode::Signal_context_capability _sigh { };
uint64_t const _init_time_us =
_timeout_scheduler.curr_time().trunc_to_plain_us().value;
void handle_timeout(Duration) override {
Genode::Signal_transmitter(_sigh).submit(); }
public:
Session_component(Genode::Timeout_scheduler &timeout_scheduler)
: _timeout(timeout_scheduler), _timeout_scheduler(timeout_scheduler) { }
/********************
** Timer::Session **
********************/
void trigger_once(uint64_t us) override {
/*
* FIXME Workaround for the problem that Alarm scheduler may
* categorize big timeouts into the wrong time counter
* period due to its outdated internal time. This is needed
* only because the Alarm framework solely takes absolute
* time values on one-shot timeouts. and thus As soon as the
* Alarm framework takes solely relative time values, please
* remove this.
*/
Microseconds typed_us((us > ~(uint64_t)0 >> 1) ? ~(uint64_t)0 >> 1 : us);
_timeout.schedule_one_shot(typed_us, *this);
}
void trigger_periodic(uint64_t us) override {
_timeout.schedule_periodic(Microseconds(us), *this); }
void sigh(Signal_context_capability sigh) override
{
_sigh = sigh;
if (!sigh.valid())
_timeout.discard();
}
uint64_t elapsed_ms() const override {
return elapsed_us() / 1000; }
uint64_t elapsed_us() const override {
return _timeout_scheduler.curr_time().trunc_to_plain_us().value -
_init_time_us; }
void msleep(uint64_t) override { /* never called at the server side */ }
void usleep(uint64_t) override { /* never called at the server side */ }
};
#endif /* _SESSION_COMPONENT_ */