b3727a9b46
Issue #3159
111 lines
2.4 KiB
C++
111 lines
2.4 KiB
C++
/*
|
|
* \brief Time source that uses an extra thread for timeout handling
|
|
* \author Norman Feske
|
|
* \author Martin Stein
|
|
* \date 2009-06-16
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2009-2017 Genode Labs GmbH
|
|
*
|
|
* 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 _THREADED_TIME_SOURCE_H_
|
|
#define _THREADED_TIME_SOURCE_H_
|
|
|
|
/* Genode inludes */
|
|
#include <base/env.h>
|
|
#include <base/rpc_client.h>
|
|
#include <timer/timeout.h>
|
|
|
|
namespace Timer {
|
|
|
|
using Genode::Microseconds;
|
|
using Genode::Duration;
|
|
class Threaded_time_source;
|
|
}
|
|
|
|
|
|
class Timer::Threaded_time_source : public Genode::Time_source,
|
|
protected Genode::Thread
|
|
{
|
|
private:
|
|
|
|
struct Irq_dispatcher : Genode::Interface
|
|
{
|
|
GENODE_RPC(Rpc_do_dispatch, void, do_dispatch);
|
|
GENODE_RPC_INTERFACE(Rpc_do_dispatch);
|
|
};
|
|
|
|
struct Irq_dispatcher_component : Genode::Rpc_object<Irq_dispatcher,
|
|
Irq_dispatcher_component>
|
|
{
|
|
private:
|
|
|
|
/*
|
|
* Noncopyable
|
|
*/
|
|
Irq_dispatcher_component(Irq_dispatcher_component const &);
|
|
Irq_dispatcher_component &operator = (Irq_dispatcher_component const &);
|
|
|
|
public:
|
|
|
|
Timeout_handler *handler = nullptr;
|
|
Threaded_time_source &ts;
|
|
|
|
Irq_dispatcher_component(Threaded_time_source &ts) : ts(ts) { }
|
|
|
|
/********************
|
|
** Irq_dispatcher **
|
|
********************/
|
|
|
|
void do_dispatch()
|
|
{
|
|
/* call curr_time in ep and not in ts (no locks in use!) */
|
|
ts._irq = true;
|
|
Duration us = ts.curr_time();
|
|
ts._irq = false;
|
|
|
|
if (handler)
|
|
handler->handle_timeout(us);
|
|
}
|
|
|
|
} _irq_dispatcher_component;
|
|
|
|
Genode::Capability<Irq_dispatcher> _irq_dispatcher_cap;
|
|
|
|
virtual void _wait_for_irq() = 0;
|
|
|
|
/***********************
|
|
** Thread_deprecated **
|
|
***********************/
|
|
|
|
void entry() override
|
|
{
|
|
while (true) {
|
|
_wait_for_irq();
|
|
_irq_dispatcher_cap.call<Irq_dispatcher::Rpc_do_dispatch>();
|
|
}
|
|
}
|
|
|
|
protected:
|
|
|
|
bool _irq { false };
|
|
|
|
public:
|
|
|
|
Threaded_time_source(Genode::Env &env)
|
|
:
|
|
Thread(env, "threaded_time_source", 8 * 1024 * sizeof(Genode::addr_t)),
|
|
_irq_dispatcher_component(*this),
|
|
_irq_dispatcher_cap(env.ep().rpc_ep().manage(&_irq_dispatcher_component))
|
|
{ }
|
|
|
|
void handler(Timeout_handler &handler) {
|
|
_irq_dispatcher_component.handler = &handler; }
|
|
};
|
|
|
|
#endif /* _THREADED_TIME_SOURCE_H_ */
|