mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-29 15:44:02 +00:00
Turn 'Timer::Session' into asynchronous interface
The 'Timer::Session::msleep' function is one of the last occurrences of long-blocking RPC calls. Synchronous blocking RPC interfaces turned out to be constant source of trouble and code complexity. I.e., a timer client that also wants to respond to non-timer events was forced to be a multi-threaded process. This patch replaces the blocking 'msleep' call by a mechanism for programming timeouts and receiving wakeup signals in an asynchronous fashion. Thereby signals originating from the timer can be handled along with signals from other signal sources by a single thread. The changed interface has been tested on Linux, L4/Fiasco, OKL4, NOVA, L4ka::Pistachio, Codezero, Fiasco.OC, and hw_pbxa9. Furthermore, this patch adds the timer test to autopilot. Fixes #1
This commit is contained in:
parent
0ed8797df2
commit
3049c1004c
@ -1,4 +1,4 @@
|
||||
LIBS = child
|
||||
LIBS = child signal
|
||||
SRC_CC = launchpad.cc
|
||||
|
||||
vpath launchpad.cc $(REP_DIR)/src/lib/launchpad
|
||||
|
@ -1,5 +1,5 @@
|
||||
TARGET = liquid_fb
|
||||
LIBS = scout_widgets
|
||||
LIBS = scout_widgets signal
|
||||
SRC_CC = main.cc services.cc
|
||||
INC_DIR += $(REP_DIR)/src/app/scout/include \
|
||||
$(REP_DIR)/src/app/scout/include/genode \
|
||||
|
@ -1,5 +1,5 @@
|
||||
TARGET = nitlog
|
||||
LIBS = cxx env server blit
|
||||
LIBS = cxx env server blit signal
|
||||
SRC_CC = main.cc
|
||||
SRC_BIN = mono.tff
|
||||
INC_DIR = $(REP_DIR)/src/server/nitpicker/include
|
||||
|
@ -26,9 +26,11 @@ namespace Timer {
|
||||
explicit Session_client(Session_capability session)
|
||||
: Genode::Rpc_client<Session>(session) { }
|
||||
|
||||
void msleep(unsigned ms) { call<Rpc_msleep>(ms); }
|
||||
void trigger_once(unsigned us) { call<Rpc_trigger_once>(us); }
|
||||
|
||||
void usleep(unsigned us) { call<Rpc_usleep>(us); }
|
||||
void trigger_periodic(unsigned us) { call<Rpc_trigger_periodic>(us); }
|
||||
|
||||
void sigh(Signal_context_capability sigh) { call<Rpc_sigh>(sigh); }
|
||||
|
||||
unsigned long elapsed_ms() const { return call<Rpc_elapsed_ms>(); }
|
||||
};
|
||||
|
@ -19,20 +19,61 @@
|
||||
|
||||
namespace Timer {
|
||||
|
||||
struct Connection : Genode::Connection<Session>, Session_client
|
||||
class Connection : public Genode::Connection<Session>, public Session_client
|
||||
{
|
||||
Connection()
|
||||
:
|
||||
/*
|
||||
* Because the timer service uses one thread per timer session,
|
||||
* we donate two pages. One of them is used as stack for the
|
||||
* timer thread and the other page holds the session meta data.
|
||||
*/
|
||||
Genode::Connection<Session>(session("ram_quota=%zd",
|
||||
sizeof(Genode::addr_t)*2048)),
|
||||
private:
|
||||
|
||||
Session_client(cap())
|
||||
{ }
|
||||
Lock _lock;
|
||||
Signal_receiver _sig_rec;
|
||||
Signal_context _default_sigh_ctx;
|
||||
Signal_context_capability _default_sigh_cap;
|
||||
Signal_context_capability _custom_sigh_cap;
|
||||
|
||||
public:
|
||||
|
||||
Connection()
|
||||
:
|
||||
Genode::Connection<Session>(session("ram_quota=8K")),
|
||||
Session_client(cap()),
|
||||
_default_sigh_cap(_sig_rec.manage(&_default_sigh_ctx))
|
||||
{
|
||||
/* register default signal handler */
|
||||
sigh(_default_sigh_cap);
|
||||
}
|
||||
|
||||
~Connection() { _sig_rec.dissolve(&_default_sigh_ctx); }
|
||||
|
||||
/*
|
||||
* Intercept 'sigh' to keep track of customized signal handlers
|
||||
*/
|
||||
void sigh(Signal_context_capability sigh)
|
||||
{
|
||||
_custom_sigh_cap = sigh;
|
||||
Session_client::sigh(_custom_sigh_cap);
|
||||
}
|
||||
|
||||
void usleep(unsigned us)
|
||||
{
|
||||
/* serialize sleep calls issued by different threads */
|
||||
Lock::Guard guard(_lock);
|
||||
|
||||
/* temporarily install to the default signal handler */
|
||||
if (_custom_sigh_cap.valid())
|
||||
sigh(_default_sigh_cap);
|
||||
|
||||
/* trigger timeout at default signal handler */
|
||||
trigger_once(us);
|
||||
_sig_rec.wait_for_signal();
|
||||
|
||||
/* revert custom signal handler if registered */
|
||||
if (_custom_sigh_cap.valid())
|
||||
sigh(_custom_sigh_cap);
|
||||
}
|
||||
|
||||
void msleep(unsigned ms)
|
||||
{
|
||||
usleep(1000*ms);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* \brief Server-side timer session interface
|
||||
* \author Norman Feske
|
||||
* \date 2006-08-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__TIMER_SESSION__SERVER_H_
|
||||
#define _INCLUDE__TIMER_SESSION__SERVER_H_
|
||||
|
||||
#include <timer_session/timer_session.h>
|
||||
#include <base/rpc_server.h>
|
||||
|
||||
namespace Timer {
|
||||
|
||||
struct Session_server : Genode::Rpc_object<Session> { };
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__TIMER_SESSION__SERVER_H_ */
|
@ -16,10 +16,13 @@
|
||||
#ifndef _INCLUDE__TIMER_SESSION__TIMER_SESSION_H_
|
||||
#define _INCLUDE__TIMER_SESSION__TIMER_SESSION_H_
|
||||
|
||||
#include <base/signal.h>
|
||||
#include <session/session.h>
|
||||
|
||||
namespace Timer {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
struct Session : Genode::Session
|
||||
{
|
||||
static const char *service_name() { return "Timer"; }
|
||||
@ -27,36 +30,49 @@ namespace Timer {
|
||||
virtual ~Session() { }
|
||||
|
||||
/**
|
||||
* Sleep number of milliseconds
|
||||
* Program single timeout (in microseconds)
|
||||
*/
|
||||
virtual void msleep(unsigned ms) = 0;
|
||||
virtual void trigger_once(unsigned us) = 0;
|
||||
|
||||
/**
|
||||
* Sleep number of microseconds
|
||||
* Program periodic timeout (in microseconds)
|
||||
*/
|
||||
virtual void usleep(unsigned us) = 0;
|
||||
virtual void trigger_periodic(unsigned us) = 0;
|
||||
|
||||
/**
|
||||
* Register timeout signal handler
|
||||
*/
|
||||
virtual void sigh(Signal_context_capability sigh) = 0;
|
||||
|
||||
/**
|
||||
* Return number of elapsed milliseconds since session creation
|
||||
*/
|
||||
virtual unsigned long elapsed_ms() const
|
||||
{
|
||||
/*
|
||||
* XXX Remove default implementation by implementing the
|
||||
* interface in all timer variants.
|
||||
*/
|
||||
return 0; }
|
||||
virtual unsigned long elapsed_ms() const = 0;
|
||||
|
||||
/**
|
||||
* Client-side convenience function for sleeping the specified number
|
||||
* of milliseconds
|
||||
*/
|
||||
virtual void msleep(unsigned ms) = 0;
|
||||
|
||||
/**
|
||||
* Client-side convenience function for sleeping the specified number
|
||||
* of microseconds
|
||||
*/
|
||||
virtual void usleep(unsigned us) = 0;
|
||||
|
||||
|
||||
/*********************
|
||||
** RPC declaration **
|
||||
*********************/
|
||||
|
||||
GENODE_RPC(Rpc_msleep, void, msleep, unsigned);
|
||||
GENODE_RPC(Rpc_usleep, void, usleep, unsigned);
|
||||
GENODE_RPC(Rpc_trigger_once, void, trigger_once, unsigned);
|
||||
GENODE_RPC(Rpc_trigger_periodic, void, trigger_periodic, unsigned);
|
||||
GENODE_RPC(Rpc_sigh, void, sigh, Genode::Signal_context_capability);
|
||||
GENODE_RPC(Rpc_elapsed_ms, unsigned long, elapsed_ms);
|
||||
|
||||
GENODE_RPC_INTERFACE(Rpc_msleep, Rpc_usleep, Rpc_elapsed_ms);
|
||||
GENODE_RPC_INTERFACE(Rpc_trigger_once, Rpc_trigger_periodic,
|
||||
Rpc_sigh, Rpc_elapsed_ms);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ install_config {
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="SIGNAL"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service><parent/><any-child/></any-service>
|
||||
|
@ -1,7 +1,7 @@
|
||||
TARGET = pl11x_drv
|
||||
REQUIRES = pl11x platform_pbxa9
|
||||
SRC_CC = main.cc video_memory.cc
|
||||
LIBS = cxx env server
|
||||
LIBS = cxx env server signal
|
||||
INC_DIR += $(PRG_DIR)/..
|
||||
|
||||
vpath %.cc $(PRG_DIR)/..
|
||||
|
@ -1,7 +1,7 @@
|
||||
TARGET = pl11x_drv
|
||||
REQUIRES = pl11x platform_vea9x4
|
||||
SRC_CC = main.cc video_memory.cc
|
||||
LIBS = cxx env server
|
||||
LIBS = cxx env server signal
|
||||
INC_DIR += $(PRG_DIR)/..
|
||||
|
||||
vpath main.cc $(PRG_DIR)/..
|
||||
|
@ -1,7 +1,7 @@
|
||||
TARGET = pl11x_drv
|
||||
REQUIRES = pl11x platform_vpb926
|
||||
SRC_CC = main.cc video_memory.cc
|
||||
LIBS = cxx env server
|
||||
LIBS = cxx env server signal
|
||||
INC_DIR += $(PRG_DIR)/..
|
||||
|
||||
vpath %.cc $(PRG_DIR)/..
|
||||
|
@ -26,7 +26,7 @@ using namespace Codezero;
|
||||
unsigned long Platform_timer::max_timeout() { return 1000; }
|
||||
|
||||
|
||||
unsigned long Platform_timer::curr_time()
|
||||
unsigned long Platform_timer::curr_time() const
|
||||
{
|
||||
Genode::Lock::Guard lock_guard(_lock);
|
||||
return _curr_time_usec;
|
||||
|
@ -1,7 +1,7 @@
|
||||
TARGET = timer
|
||||
SRC_CC = main.cc platform_timer.cc
|
||||
REQUIRES = codezero
|
||||
LIBS = cxx server env alarm
|
||||
LIBS = cxx server env alarm signal
|
||||
|
||||
INC_DIR += $(PRG_DIR)/../include $(PRG_DIR)/../include_periodic
|
||||
|
||||
|
@ -58,7 +58,7 @@ unsigned long Platform_timer::max_timeout()
|
||||
}
|
||||
|
||||
|
||||
unsigned long Platform_timer::curr_time()
|
||||
unsigned long Platform_timer::curr_time() const
|
||||
{
|
||||
Genode::Lock::Guard lock_guard(_lock);
|
||||
return _curr_time_usec;
|
||||
|
@ -1,7 +1,7 @@
|
||||
TARGET = timer
|
||||
SRC_CC = main.cc platform_timer.cc
|
||||
REQUIRES = fiasco
|
||||
LIBS = cxx server env alarm
|
||||
LIBS = cxx server env alarm signal
|
||||
|
||||
INC_DIR = $(PRG_DIR)/../include $(PRG_DIR)/../include_periodic
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
TARGET = timer
|
||||
SRC_CC = main.cc
|
||||
SRC_CC = main.cc platform_timer.cc
|
||||
REQUIRES = foc
|
||||
LIBS = cxx server env
|
||||
LIBS = cxx server env alarm signal
|
||||
|
||||
INC_DIR = $(PRG_DIR)
|
||||
INC_DIR = $(PRG_DIR)/../include $(PRG_DIR)/../include_periodic
|
||||
|
||||
vpath main.cc $(PRG_DIR)/..
|
||||
vpath platform_timer.cc $(REP_DIR)/src/drivers/timer/fiasco
|
||||
|
@ -1,95 +0,0 @@
|
||||
/*
|
||||
* \brief Root interface to timer service
|
||||
* \author Norman Feske
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2006-08-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_ROOT_H_
|
||||
#define _TIMER_ROOT_H_
|
||||
|
||||
#include <util/arg_string.h>
|
||||
#include <util/list.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <root/root.h>
|
||||
#include <cap_session/cap_session.h>
|
||||
|
||||
#include "timer_session_component.h"
|
||||
|
||||
|
||||
namespace Timer {
|
||||
|
||||
class Root_component : public Genode::Rpc_object<Genode::Typed_root<Session> >
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Allocator *_md_alloc;
|
||||
Genode::Cap_session *_cap_session;
|
||||
Genode::List<Session_component> _sessions;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Root_component(Genode::Rpc_entrypoint *session_ep,
|
||||
Genode::Allocator *md_alloc,
|
||||
Genode::Cap_session *cap)
|
||||
: _md_alloc(md_alloc), _cap_session(cap) { }
|
||||
|
||||
|
||||
/********************
|
||||
** Root interface **
|
||||
********************/
|
||||
|
||||
Genode::Session_capability session(Root::Session_args const &args)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
if (!args.is_valid_string()) throw Invalid_args();
|
||||
|
||||
size_t ram_quota = Arg_string::find_arg(args.string(), "ram_quota").ulong_value(0);
|
||||
size_t require = sizeof(Session_component) + STACK_SIZE;
|
||||
if (ram_quota < require) {
|
||||
PWRN("Insufficient donated ram_quota (%zd bytes), require %zd bytes",
|
||||
ram_quota, require);
|
||||
}
|
||||
|
||||
/* create session object */
|
||||
Session_component *sc = new (_md_alloc) Session_component(_cap_session);
|
||||
_sessions.insert(sc);
|
||||
return sc->cap();
|
||||
}
|
||||
|
||||
void upgrade(Genode::Session_capability, Root::Upgrade_args const &) { }
|
||||
|
||||
void close(Genode::Session_capability session_cap)
|
||||
{
|
||||
/*
|
||||
* Lookup session-component by its capability by asking each
|
||||
* entry point for object belonging to the capability. Only one
|
||||
* entry point is expected to give the right answer.
|
||||
*/
|
||||
Session_component *sc = _sessions.first();
|
||||
for (; sc && !sc->belongs_to(session_cap); sc = sc->next());
|
||||
|
||||
if (!sc) {
|
||||
PWRN("attempted to close non-existing session");
|
||||
return;
|
||||
}
|
||||
|
||||
_sessions.remove(sc);
|
||||
destroy(_md_alloc, sc);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,139 +0,0 @@
|
||||
/*
|
||||
* \brief Instance of the timer session interface
|
||||
* \author Norman Feske
|
||||
* \author Stefan Kalkowski
|
||||
* \author Markus Partheymueller
|
||||
* \date 2010-01-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 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 General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_SESSION_COMPONENT_
|
||||
#define _TIMER_SESSION_COMPONENT_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/rpc_server.h>
|
||||
#include <timer_session/capability.h>
|
||||
#include <os/attached_rom_dataspace.h>
|
||||
|
||||
/* Fiasco.OC includes */
|
||||
namespace Fiasco {
|
||||
#include <l4/sys/ipc.h>
|
||||
#include <l4/sys/kip.h>
|
||||
}
|
||||
|
||||
|
||||
static Fiasco::l4_timeout_s mus_to_timeout(unsigned int mus)
|
||||
{
|
||||
using namespace Fiasco;
|
||||
|
||||
if (mus == 0)
|
||||
return L4_IPC_TIMEOUT_0;
|
||||
else if (mus == ~0UL)
|
||||
return L4_IPC_TIMEOUT_NEVER;
|
||||
|
||||
long e = Genode::log2(mus) - 7;
|
||||
unsigned long m;
|
||||
|
||||
if (e < 0) e = 0;
|
||||
m = mus / (1UL << e);
|
||||
|
||||
/* check corner case */
|
||||
if ((e > 31 ) || (m > 1023)) {
|
||||
PWRN("invalid timeout %x, using max. values\n", mus);
|
||||
e = 0;
|
||||
m = 1023;
|
||||
}
|
||||
|
||||
return l4_timeout_rel(m, e);
|
||||
}
|
||||
|
||||
|
||||
namespace Timer {
|
||||
|
||||
enum { STACK_SIZE = 1024 * sizeof(Genode::addr_t) };
|
||||
|
||||
/**
|
||||
* Timer session
|
||||
*/
|
||||
class Session_component : public Genode::Rpc_object<Session>,
|
||||
public Genode::List<Session_component>::Element
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Rpc_entrypoint _entrypoint;
|
||||
Session_capability _session_cap;
|
||||
Genode::Attached_rom_dataspace _kip_ds;
|
||||
Fiasco::l4_kernel_info_t * const _kip;
|
||||
Fiasco::l4_cpu_time_t const _initial_clock_value;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Session_component(Genode::Cap_session *cap)
|
||||
:
|
||||
_entrypoint(cap, STACK_SIZE, "timer_session_ep"),
|
||||
_session_cap(_entrypoint.manage(this)),
|
||||
_kip_ds("l4v2_kip"),
|
||||
_kip(_kip_ds.local_addr<Fiasco::l4_kernel_info_t>()),
|
||||
_initial_clock_value(_kip->clock)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Session_component()
|
||||
{
|
||||
_entrypoint.dissolve(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if capability belongs to session object
|
||||
*/
|
||||
bool belongs_to(Genode::Session_capability cap)
|
||||
{
|
||||
Genode::Object_pool<Session_component>::Guard
|
||||
lcap(_entrypoint.lookup_and_lock(cap));
|
||||
return lcap == this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return session capability
|
||||
*/
|
||||
Session_capability cap() { return _session_cap; }
|
||||
|
||||
|
||||
/*****************************
|
||||
** Timer session interface **
|
||||
*****************************/
|
||||
|
||||
void msleep(unsigned ms)
|
||||
{
|
||||
using namespace Fiasco;
|
||||
|
||||
l4_ipc_sleep(l4_timeout(L4_IPC_TIMEOUT_NEVER, mus_to_timeout(1000*ms)));
|
||||
}
|
||||
|
||||
void usleep(unsigned us)
|
||||
{
|
||||
using namespace Fiasco;
|
||||
|
||||
l4_ipc_sleep(l4_timeout(L4_IPC_TIMEOUT_NEVER, mus_to_timeout(us)));
|
||||
}
|
||||
|
||||
unsigned long elapsed_ms() const
|
||||
{
|
||||
return (_kip->clock - _initial_clock_value) / 1000;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -14,10 +14,10 @@ SRC_CC += main.cc
|
||||
REQUIRES += hw_pbxa9
|
||||
|
||||
# Add libraries
|
||||
LIBS += cxx server env alarm
|
||||
LIBS += cxx server env alarm signal
|
||||
|
||||
# Add include paths
|
||||
INC_DIR += $(PRG_DIR) $(PRG_DIR)/../ $(PRG_DIR)/../../nova/
|
||||
INC_DIR += $(PRG_DIR) $(PRG_DIR)/../ $(PRG_DIR)/../../include
|
||||
|
||||
# Declare source paths
|
||||
vpath main.cc $(PRG_DIR)/../..
|
||||
|
@ -30,19 +30,21 @@ class Platform_timer : public Platform_timer_base,
|
||||
|
||||
enum { MAX_TIMER_IRQS_PER_MS = 1 };
|
||||
|
||||
unsigned long const _max_timeout_us; /* Maximum timeout in microsecs */
|
||||
unsigned long _curr_time_us; /* Accumulate already measured timeouts */
|
||||
unsigned long _init_value; /* Mark last processed timer value */
|
||||
Genode::Lock _update_curr_time_lock; /* Serialize curr_time access */
|
||||
unsigned long const _max_timeout_us; /* maximum timeout in microsecs */
|
||||
unsigned long mutable _curr_time_us; /* accumulate already measured timeouts */
|
||||
unsigned long mutable _init_value; /* mark last processed timer value */
|
||||
Genode::Lock mutable _update_curr_time_lock; /* serialize curr_time access */
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Platform_timer() : Irq_connection(Platform_timer_base::IRQ),
|
||||
_max_timeout_us(tics_to_us(max_value())),
|
||||
_curr_time_us(0), _init_value(0)
|
||||
Platform_timer()
|
||||
:
|
||||
Irq_connection(Platform_timer_base::IRQ),
|
||||
_max_timeout_us(tics_to_us(max_value())),
|
||||
_curr_time_us(0), _init_value(0)
|
||||
{ }
|
||||
|
||||
/**
|
||||
@ -51,22 +53,22 @@ class Platform_timer : public Platform_timer_base,
|
||||
* This function has to be executed regulary,
|
||||
* at least all max_timeout() us.
|
||||
*/
|
||||
unsigned long curr_time()
|
||||
unsigned long curr_time() const
|
||||
{
|
||||
/* Serialize updates on timeout counter */
|
||||
/* serialize updates on timeout counter */
|
||||
Genode::Lock::Guard lock(_update_curr_time_lock);
|
||||
|
||||
/* Get time that passed since last time we've read the timer */
|
||||
/* get time that passed since last time we've read the timer */
|
||||
bool wrapped;
|
||||
unsigned long const v = value(wrapped);
|
||||
unsigned long passed_time;
|
||||
if (wrapped) passed_time = _init_value + max_value() - v;
|
||||
else passed_time = _init_value - v;
|
||||
|
||||
/* Update initial value for subsequent calculations */
|
||||
/* update initial value for subsequent calculations */
|
||||
_init_value = v;
|
||||
|
||||
/* Refresh our timeout counter and return it */
|
||||
/* refresh our timeout counter and return it */
|
||||
_curr_time_us += tics_to_us(passed_time);
|
||||
return _curr_time_us;
|
||||
}
|
||||
@ -83,19 +85,23 @@ class Platform_timer : public Platform_timer_base,
|
||||
*/
|
||||
void schedule_timeout(unsigned long timeout_us)
|
||||
{
|
||||
/* Serialize updates on timeout counter */
|
||||
/* serialize updates on timeout counter */
|
||||
Genode::Lock::Guard lock(_update_curr_time_lock);
|
||||
|
||||
/* Constraint timout value with our maximum IRQ rate
|
||||
* and the maximum possible timout */
|
||||
/*
|
||||
* Constrain timout value with our maximum IRQ rate and the maximum
|
||||
* possible timeout.
|
||||
*/
|
||||
if (timeout_us < 1000/MAX_TIMER_IRQS_PER_MS)
|
||||
timeout_us = 1000/MAX_TIMER_IRQS_PER_MS;
|
||||
if (timeout_us > _max_timeout_us)
|
||||
timeout_us = _max_timeout_us;
|
||||
|
||||
/* Once the timer runs, one can wait for the its IRQ and update our
|
||||
/*
|
||||
* Once the timer runs, one can wait for its IRQ and update our
|
||||
* timeout counter through 'curr_time()' (We rely on the fact that
|
||||
* this is done at least one time in every max-timeout period) */
|
||||
* this is done at least one time in every max-timeout period)
|
||||
*/
|
||||
_init_value = us_to_tics(timeout_us);
|
||||
run_and_wrap(_init_value);
|
||||
}
|
||||
|
@ -14,10 +14,10 @@ SRC_CC += main.cc
|
||||
REQUIRES += hw_vea9x4
|
||||
|
||||
# Add libraries
|
||||
LIBS += cxx server env alarm
|
||||
LIBS += cxx server env alarm signal
|
||||
|
||||
# Add include paths
|
||||
INC_DIR += $(PRG_DIR)/../ $(PRG_DIR)/../pbxa9 $(PRG_DIR)/../../nova/
|
||||
INC_DIR += $(PRG_DIR)/../ $(PRG_DIR)/../pbxa9 $(PRG_DIR)/../../include
|
||||
|
||||
# Declare source paths
|
||||
vpath main.cc $(PRG_DIR)/../..
|
||||
|
@ -29,14 +29,14 @@ namespace Timer {
|
||||
{
|
||||
private:
|
||||
|
||||
Platform_timer _platform_timer;
|
||||
Timeout_scheduler _timeout_scheduler;
|
||||
Genode::Rpc_entrypoint *_entrypoint;
|
||||
Platform_timer _platform_timer;
|
||||
Timeout_scheduler _timeout_scheduler;
|
||||
|
||||
protected:
|
||||
|
||||
Session_component *_create_session(const char *args)
|
||||
{
|
||||
PLOG("args='%s'", args);
|
||||
Genode::size_t ram_quota = Genode::Arg_string::find_arg(args, "ram_quota").ulong_value(0);
|
||||
|
||||
if (ram_quota < sizeof(Session_component)) {
|
||||
@ -45,7 +45,7 @@ namespace Timer {
|
||||
}
|
||||
|
||||
return new (md_alloc())
|
||||
Session_component(&_timeout_scheduler, _entrypoint);
|
||||
Session_component(_timeout_scheduler);
|
||||
}
|
||||
|
||||
public:
|
||||
@ -61,8 +61,7 @@ namespace Timer {
|
||||
Genode::Cap_session *cap)
|
||||
:
|
||||
Genode::Root_component<Session_component>(session_ep, md_alloc),
|
||||
_timeout_scheduler(&_platform_timer, session_ep),
|
||||
_entrypoint(session_ep)
|
||||
_timeout_scheduler(&_platform_timer, session_ep)
|
||||
{ }
|
||||
};
|
||||
}
|
||||
|
@ -47,8 +47,8 @@ namespace Timer {
|
||||
* we are able to answer those requests from here (by calling the
|
||||
* 'handle()' function of the alarm scheduler).
|
||||
*/
|
||||
class Irq_dispatcher_component : public Genode::Rpc_object<Irq_dispatcher,
|
||||
Irq_dispatcher_component>
|
||||
class Irq_dispatcher_component : public Rpc_object<Irq_dispatcher,
|
||||
Irq_dispatcher_component>
|
||||
{
|
||||
private:
|
||||
|
||||
@ -95,24 +95,21 @@ namespace Timer {
|
||||
|
||||
|
||||
/**
|
||||
* Alarm for answering a sleep request
|
||||
* Alarm for answering an oneshot timeout request
|
||||
*/
|
||||
class Wake_up_alarm : public Genode::Alarm
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Native_capability _reply_cap;
|
||||
Genode::Rpc_entrypoint *_entrypoint;
|
||||
Signal_context_capability _sigh;
|
||||
bool _periodic;
|
||||
|
||||
public:
|
||||
|
||||
Wake_up_alarm(Genode::Rpc_entrypoint *ep) : _entrypoint(ep) { }
|
||||
Wake_up_alarm() : _periodic(false) { }
|
||||
|
||||
/**
|
||||
* Set reply target to wake up when the alarm triggers
|
||||
*/
|
||||
void reply_cap(Genode::Native_capability reply_cap) {
|
||||
_reply_cap = reply_cap; }
|
||||
void sigh(Signal_context_capability sigh) { _sigh = sigh; }
|
||||
void periodic(bool periodic) { _periodic = periodic; }
|
||||
|
||||
|
||||
/*********************
|
||||
@ -126,10 +123,9 @@ namespace Timer {
|
||||
*/
|
||||
bool on_alarm()
|
||||
{
|
||||
_entrypoint->explicit_reply(_reply_cap, 0);
|
||||
Signal_transmitter(_sigh).submit();
|
||||
|
||||
/* do not re-schedule */
|
||||
return 0;
|
||||
return _periodic;
|
||||
}
|
||||
};
|
||||
|
||||
@ -184,42 +180,51 @@ namespace Timer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from the 'msleep' function executed by the server activation
|
||||
* Called from the '_trigger' function executed by the server activation
|
||||
*/
|
||||
void schedule_timeout(Genode::Alarm *alarm, Genode::Alarm::Time timeout)
|
||||
{
|
||||
Genode::Alarm::Time now = _platform_timer->curr_time();
|
||||
Alarm::Time now = _platform_timer->curr_time();
|
||||
schedule_absolute(alarm, now + timeout);
|
||||
|
||||
/* interrupt current 'wait_for_timeout' */
|
||||
_platform_timer->schedule_timeout(0);
|
||||
}
|
||||
|
||||
unsigned long curr_time() const
|
||||
{
|
||||
return _platform_timer->curr_time();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Timer session
|
||||
*/
|
||||
class Session_component : public Genode::Rpc_object<Session>,
|
||||
public Genode::List<Session_component>::Element
|
||||
class Session_component : public Rpc_object<Session>,
|
||||
public List<Session_component>::Element
|
||||
{
|
||||
private:
|
||||
|
||||
Timeout_scheduler *_timeout_scheduler;
|
||||
Genode::Rpc_entrypoint *_entrypoint;
|
||||
Wake_up_alarm _wake_up_alarm;
|
||||
Timeout_scheduler &_timeout_scheduler;
|
||||
Wake_up_alarm _wake_up_alarm;
|
||||
unsigned long const _initial_time;
|
||||
|
||||
void _trigger(unsigned us, bool periodic)
|
||||
{
|
||||
_wake_up_alarm.periodic(periodic);
|
||||
_timeout_scheduler.schedule_timeout(&_wake_up_alarm, us);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Session_component(Timeout_scheduler *ts,
|
||||
Genode::Rpc_entrypoint *ep)
|
||||
Session_component(Timeout_scheduler &ts)
|
||||
:
|
||||
_timeout_scheduler(ts),
|
||||
_entrypoint(ep),
|
||||
_wake_up_alarm(ep)
|
||||
_initial_time(_timeout_scheduler.curr_time())
|
||||
{ }
|
||||
|
||||
/**
|
||||
@ -227,7 +232,7 @@ namespace Timer {
|
||||
*/
|
||||
~Session_component()
|
||||
{
|
||||
_timeout_scheduler->discard(&_wake_up_alarm);
|
||||
_timeout_scheduler.discard(&_wake_up_alarm);
|
||||
}
|
||||
|
||||
|
||||
@ -235,24 +240,29 @@ namespace Timer {
|
||||
** Timer session interface **
|
||||
*****************************/
|
||||
|
||||
void msleep(unsigned ms)
|
||||
void trigger_once(unsigned us)
|
||||
{
|
||||
usleep(1000*ms);
|
||||
_trigger(us, false);
|
||||
}
|
||||
|
||||
void usleep(unsigned us)
|
||||
void trigger_periodic(unsigned us)
|
||||
{
|
||||
_wake_up_alarm.reply_cap(_entrypoint->reply_dst());
|
||||
_timeout_scheduler->schedule_timeout(&_wake_up_alarm, us);
|
||||
|
||||
/*
|
||||
* Prevent the server activation from immediately answering the
|
||||
* current call. The caller of 'msleep' will be unblocked via
|
||||
* 'Rpc_entrypoint::explicit_reply' when its timeout alarm
|
||||
* triggers.
|
||||
*/
|
||||
_entrypoint->omit_reply();
|
||||
_trigger(us, true);
|
||||
}
|
||||
|
||||
void sigh(Signal_context_capability sigh)
|
||||
{
|
||||
_wake_up_alarm.sigh(sigh);
|
||||
}
|
||||
|
||||
unsigned long elapsed_ms() const
|
||||
{
|
||||
unsigned long const now = _timeout_scheduler.curr_time();
|
||||
return now - _initial_time;
|
||||
}
|
||||
|
||||
void msleep(unsigned) { /* never called at the server side */ }
|
||||
void usleep(unsigned) { /* never called at the server side */ }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -22,9 +22,9 @@ class Platform_timer
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Lock _lock; /* for protecting '_next_timeout_usec' */
|
||||
unsigned long _next_timeout_usec; /* timeout of current sleep */
|
||||
unsigned long _curr_time_usec; /* accumulated sleep time */
|
||||
Genode::Lock mutable _lock; /* for protecting '_next_timeout_usec' */
|
||||
unsigned long _next_timeout_usec; /* timeout of current sleep */
|
||||
unsigned long _curr_time_usec; /* accumulated sleep time */
|
||||
|
||||
/**
|
||||
* Platform-specific sleep implementation
|
||||
@ -38,7 +38,6 @@ class Platform_timer
|
||||
*/
|
||||
Platform_timer() : _next_timeout_usec(max_timeout()), _curr_time_usec(0) { }
|
||||
|
||||
|
||||
/**
|
||||
* Set next relative timeout
|
||||
*/
|
||||
@ -48,18 +47,15 @@ class Platform_timer
|
||||
_next_timeout_usec = timeout_usec;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return maximum supported timeout in microseconds
|
||||
*/
|
||||
unsigned long max_timeout();
|
||||
|
||||
|
||||
/**
|
||||
* Get current time in microseconds
|
||||
*/
|
||||
unsigned long curr_time();
|
||||
|
||||
unsigned long curr_time() const;
|
||||
|
||||
/**
|
||||
* Block until the scheduled timeout triggers
|
||||
|
@ -61,9 +61,9 @@ class Platform_timer
|
||||
|
||||
Genode::Io_port_connection _io_port;
|
||||
Genode::Irq_connection _timer_irq;
|
||||
unsigned long _curr_time_usec;
|
||||
unsigned long _counter_init_value;
|
||||
Genode::Lock _update_curr_time_lock;
|
||||
unsigned long mutable _curr_time_usec;
|
||||
unsigned long mutable _counter_init_value;
|
||||
Genode::Lock mutable _update_curr_time_lock;
|
||||
|
||||
/**
|
||||
* Set PIT counter value
|
||||
@ -117,15 +117,21 @@ class Platform_timer
|
||||
* This function has to be executed regulary,
|
||||
* at least all max_timeout() usecs.
|
||||
*/
|
||||
unsigned long curr_time()
|
||||
unsigned long curr_time() const
|
||||
{
|
||||
Genode::Lock::Guard lock(_update_curr_time_lock);
|
||||
|
||||
unsigned long curr_counter, passed_ticks;
|
||||
|
||||
/* read PIT count and status */
|
||||
/*
|
||||
* Read PIT count and status
|
||||
*
|
||||
* Reading the PIT registers via port I/O is a non-const operation.
|
||||
* Since 'curr_time' is declared as const, however, we need to
|
||||
* explicitly override the const-ness of the 'this' pointer.
|
||||
*/
|
||||
bool wrapped;
|
||||
curr_counter = _read_counter(&wrapped);
|
||||
curr_counter = const_cast<Platform_timer *>(this)->_read_counter(&wrapped);
|
||||
|
||||
/* determine the time since we looked at the counter */
|
||||
if (wrapped)
|
||||
|
@ -34,7 +34,7 @@ unsigned long Platform_timer::max_timeout()
|
||||
}
|
||||
|
||||
|
||||
unsigned long Platform_timer::curr_time()
|
||||
unsigned long Platform_timer::curr_time() const
|
||||
{
|
||||
struct timeval tv;
|
||||
lx_gettimeofday(&tv, 0);
|
||||
|
@ -1,7 +1,7 @@
|
||||
TARGET = timer
|
||||
SRC_CC = main.cc platform_timer.cc
|
||||
REQUIRES = linux
|
||||
LIBS = cxx server env alarm syscall
|
||||
LIBS = cxx server env alarm syscall signal
|
||||
INC_DIR += $(PRG_DIR)/../include $(PRG_DIR)/../include_periodic
|
||||
|
||||
vpath main.cc $(PRG_DIR)/..
|
||||
|
@ -1,8 +1,8 @@
|
||||
TARGET = timer
|
||||
SRC_CC = main.cc
|
||||
REQUIRES = nova x86
|
||||
LIBS = cxx server env alarm
|
||||
LIBS = cxx server env alarm signal
|
||||
|
||||
INC_DIR = $(PRG_DIR) $(PRG_DIR)/../include_pit
|
||||
INC_DIR = $(PRG_DIR)/../include $(PRG_DIR)/../include_pit
|
||||
|
||||
vpath main.cc $(PRG_DIR)/..
|
||||
|
@ -1,106 +0,0 @@
|
||||
/*
|
||||
* \brief Root interface to timer service
|
||||
* \author Norman Feske
|
||||
* \date 2006-08-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_ROOT_H_
|
||||
#define _TIMER_ROOT_H_
|
||||
|
||||
#include <util/arg_string.h>
|
||||
#include <util/list.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <root/root.h>
|
||||
#include <cap_session/cap_session.h>
|
||||
|
||||
#include "timer_session_component.h"
|
||||
|
||||
|
||||
namespace Timer {
|
||||
|
||||
class Root_component : public Genode::Rpc_object<Genode::Typed_root<Session> >
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Allocator *_md_alloc;
|
||||
Platform_timer _platform_timer;
|
||||
Timeout_scheduler _timeout_scheduler;
|
||||
Genode::Cap_session *_cap_session;
|
||||
Genode::Lock _sessions_lock;
|
||||
Genode::List<Session_component> _sessions;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Root_component(Genode::Rpc_entrypoint *session_ep,
|
||||
Genode::Allocator *md_alloc,
|
||||
Genode::Cap_session *cap)
|
||||
:
|
||||
_md_alloc(md_alloc),
|
||||
_timeout_scheduler(&_platform_timer, session_ep), _cap_session(cap)
|
||||
{ }
|
||||
|
||||
|
||||
/********************
|
||||
** Root interface **
|
||||
********************/
|
||||
|
||||
Genode::Session_capability session(Root::Session_args const &args)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
if (!args.is_valid_string()) throw Invalid_args();
|
||||
|
||||
size_t ram_quota = Arg_string::find_arg(args.string(), "ram_quota").ulong_value(0);
|
||||
size_t require = sizeof(Session_component) + STACK_SIZE;
|
||||
if (ram_quota < require) {
|
||||
PWRN("Insufficient donated ram_quota (%zd bytes), require %zd bytes",
|
||||
ram_quota, require);
|
||||
}
|
||||
|
||||
Lock::Guard guard(_sessions_lock);
|
||||
|
||||
/* create session object */
|
||||
Session_component *sc = new (_md_alloc)
|
||||
Session_component(&_timeout_scheduler, _cap_session);
|
||||
|
||||
_sessions.insert(sc);
|
||||
return sc->cap();
|
||||
}
|
||||
|
||||
void upgrade(Genode::Session_capability, Root::Upgrade_args const &) { }
|
||||
|
||||
void close(Genode::Session_capability session_cap)
|
||||
{
|
||||
Genode::Lock::Guard guard(_sessions_lock);
|
||||
|
||||
/*
|
||||
* Lookup session-component by its capability by asking each
|
||||
* entry point for object belonging to the capability. Only one
|
||||
* entry point is expected to give the right answer.
|
||||
*/
|
||||
Session_component *sc = _sessions.first();
|
||||
for (; sc && !sc->belongs_to(session_cap); sc = sc->next());
|
||||
|
||||
if (!sc) {
|
||||
PWRN("attempted to close non-existing session");
|
||||
return;
|
||||
}
|
||||
|
||||
_sessions.remove(sc);
|
||||
destroy(_md_alloc, sc);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,204 +0,0 @@
|
||||
/*
|
||||
* \brief Instance of the timer session interface
|
||||
* \author Norman Feske
|
||||
* \author Markus Partheymueller
|
||||
* \date 2010-01-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 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 General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_SESSION_COMPONENT_
|
||||
#define _TIMER_SESSION_COMPONENT_
|
||||
|
||||
/* Genode includes */
|
||||
#include <os/alarm.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <timer_session/capability.h>
|
||||
|
||||
/* local includes */
|
||||
#include "platform_timer.h"
|
||||
|
||||
|
||||
namespace Timer {
|
||||
|
||||
enum { STACK_SIZE = sizeof(Genode::addr_t) * 1024 };
|
||||
|
||||
class Wake_up_alarm : public Genode::Alarm
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Cancelable_lock *_barrier;
|
||||
|
||||
public:
|
||||
|
||||
Wake_up_alarm(Genode::Cancelable_lock *barrier)
|
||||
: _barrier(barrier) { }
|
||||
|
||||
|
||||
/*********************
|
||||
** Alarm interface **
|
||||
*********************/
|
||||
|
||||
/**
|
||||
* Dispatch a wakeup alarm
|
||||
*
|
||||
* This function gets called by the 'Alarm_scheduler' thread.
|
||||
*/
|
||||
bool on_alarm()
|
||||
{
|
||||
_barrier->unlock();
|
||||
|
||||
/* do not re-schedule */
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Timeout_scheduler : public Genode::Alarm_scheduler, Genode::Thread<STACK_SIZE>
|
||||
{
|
||||
private:
|
||||
|
||||
Platform_timer *_platform_timer;
|
||||
|
||||
/**
|
||||
* Timer-interrupt thread
|
||||
*/
|
||||
void entry()
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
while (true) {
|
||||
|
||||
_platform_timer->wait_for_timeout(this);
|
||||
|
||||
Alarm::Time now = _platform_timer->curr_time();
|
||||
Alarm::Time sleep_time;
|
||||
|
||||
/* trigger timeout alarms */
|
||||
handle(now);
|
||||
|
||||
/* determine duration for next one-shot timer event */
|
||||
Alarm::Time deadline;
|
||||
if (next_deadline(&deadline))
|
||||
sleep_time = deadline - now;
|
||||
else
|
||||
sleep_time = _platform_timer->max_timeout();
|
||||
|
||||
if (sleep_time == 0)
|
||||
sleep_time = 1;
|
||||
|
||||
_platform_timer->schedule_timeout(sleep_time);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Timeout_scheduler(Platform_timer *pt, Genode::Rpc_entrypoint *ep)
|
||||
: Genode::Thread<STACK_SIZE>("irq"), _platform_timer(pt)
|
||||
{
|
||||
_platform_timer->schedule_timeout(0);
|
||||
PDBG("starting timeout scheduler");
|
||||
start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from the 'msleep' function executed by the server activation
|
||||
*/
|
||||
void schedule_timeout(Genode::Alarm *alarm, Genode::Alarm::Time timeout)
|
||||
{
|
||||
Genode::Alarm::Time now = _platform_timer->curr_time();
|
||||
schedule_absolute(alarm, now + timeout);
|
||||
|
||||
/* interrupt current 'wait_for_timeout' */
|
||||
_platform_timer->schedule_timeout(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Timer session
|
||||
*/
|
||||
class Session_component : public Genode::Rpc_object<Session>,
|
||||
public Genode::List<Session_component>::Element
|
||||
{
|
||||
private:
|
||||
|
||||
Timeout_scheduler *_timeout_scheduler;
|
||||
Genode::Rpc_entrypoint _entrypoint;
|
||||
Session_capability _session_cap;
|
||||
Genode::Cancelable_lock _barrier;
|
||||
Wake_up_alarm _wake_up_alarm;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Session_component(Timeout_scheduler *ts,
|
||||
Genode::Cap_session *cap)
|
||||
:
|
||||
_timeout_scheduler(ts),
|
||||
_entrypoint(cap, STACK_SIZE, "timer_session_ep"),
|
||||
_session_cap(_entrypoint.manage(this)),
|
||||
_barrier(Genode::Cancelable_lock::LOCKED),
|
||||
_wake_up_alarm(&_barrier)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Session_component()
|
||||
{
|
||||
_entrypoint.dissolve(this);
|
||||
_timeout_scheduler->discard(&_wake_up_alarm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if capability belongs to session object
|
||||
*/
|
||||
bool belongs_to(Genode::Session_capability cap)
|
||||
{
|
||||
Genode::Object_pool<Session_component>::Guard
|
||||
lcap(_entrypoint.lookup_and_lock(cap));
|
||||
return lcap == this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return session capability
|
||||
*/
|
||||
Session_capability cap() { return _session_cap; }
|
||||
|
||||
|
||||
/*****************************
|
||||
** Timer session interface **
|
||||
*****************************/
|
||||
|
||||
void msleep(unsigned ms)
|
||||
{
|
||||
usleep(1000*ms);
|
||||
}
|
||||
|
||||
void usleep(unsigned us)
|
||||
{
|
||||
_timeout_scheduler->schedule_timeout(&_wake_up_alarm, us);
|
||||
|
||||
/*
|
||||
* Prevent the server activation from immediately answering the
|
||||
* current call. We will block until the timeout alarm triggers
|
||||
* and unblocks the semaphore.
|
||||
*/
|
||||
_barrier.lock();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* \brief Dummy platform-timer implementation
|
||||
* \author Norman Feske
|
||||
* \date 2009-11-19
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
|
||||
/* local includes */
|
||||
#include "timer_session_component.h"
|
||||
|
||||
/* OKL4 includes */
|
||||
namespace Okl4 { extern "C" {
|
||||
#include <l4/schedule.h>
|
||||
#include <l4/ipc.h>
|
||||
} }
|
||||
|
||||
unsigned long Platform_timer::max_timeout() { return 1000; }
|
||||
|
||||
|
||||
unsigned long Platform_timer::curr_time()
|
||||
{
|
||||
Genode::Lock::Guard lock_guard(_lock);
|
||||
return _curr_time_usec;
|
||||
}
|
||||
|
||||
|
||||
void Platform_timer::_usleep(unsigned long usecs)
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
Okl4::L4_Yield();
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
TARGET = timer
|
||||
SRC_CC = main.cc platform_timer.cc
|
||||
REQUIRES = okl4 arm
|
||||
LIBS = cxx server env alarm
|
||||
|
||||
INC_DIR = $(PRG_DIR)/../include $(PRG_DIR)/../include_periodic
|
||||
|
||||
vpath main.cc $(PRG_DIR)/..
|
@ -1,7 +1,7 @@
|
||||
TARGET = timer
|
||||
SRC_CC = main.cc
|
||||
REQUIRES = okl4 x86
|
||||
LIBS = cxx server env alarm
|
||||
LIBS = cxx server env alarm signal
|
||||
|
||||
INC_DIR = $(PRG_DIR)/../include $(PRG_DIR)/../include_pit
|
||||
|
||||
|
@ -30,7 +30,7 @@ unsigned long Platform_timer::max_timeout()
|
||||
}
|
||||
|
||||
|
||||
unsigned long Platform_timer::curr_time()
|
||||
unsigned long Platform_timer::curr_time() const
|
||||
{
|
||||
Genode::Lock::Guard lock_guard(_lock);
|
||||
return _curr_time_usec;
|
||||
|
@ -1,7 +1,7 @@
|
||||
TARGET = timer
|
||||
SRC_CC = main.cc platform_timer.cc
|
||||
REQUIRES = pistachio
|
||||
LIBS = cxx server env alarm
|
||||
LIBS = cxx server env alarm signal
|
||||
|
||||
INC_DIR = $(PRG_DIR)/../include $(PRG_DIR)/../include_periodic
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
TARGET = nitpicker
|
||||
LIBS = cxx env server blit
|
||||
LIBS = cxx env server blit signal
|
||||
SRC_CC = main.cc \
|
||||
view_stack.cc \
|
||||
view.cc \
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGET = testnit
|
||||
SRC_CC = test.cc
|
||||
LIBS = cxx env
|
||||
LIBS = cxx env signal
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGET = test-timer
|
||||
SRC_CC = main.cc
|
||||
LIBS = cxx env thread
|
||||
LIBS = cxx env thread signal
|
||||
|
@ -1,4 +1,5 @@
|
||||
ldso
|
||||
timer
|
||||
lwip
|
||||
rm_fault
|
||||
rom_blk
|
||||
|
Loading…
x
Reference in New Issue
Block a user