diff --git a/demo/lib/mk/launchpad.mk b/demo/lib/mk/launchpad.mk index bb257154d..6b2ded445 100644 --- a/demo/lib/mk/launchpad.mk +++ b/demo/lib/mk/launchpad.mk @@ -1,4 +1,4 @@ -LIBS = child +LIBS = child signal SRC_CC = launchpad.cc vpath launchpad.cc $(REP_DIR)/src/lib/launchpad diff --git a/demo/src/server/liquid_framebuffer/target.mk b/demo/src/server/liquid_framebuffer/target.mk index 567871102..08072028e 100644 --- a/demo/src/server/liquid_framebuffer/target.mk +++ b/demo/src/server/liquid_framebuffer/target.mk @@ -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 \ diff --git a/demo/src/server/nitlog/target.mk b/demo/src/server/nitlog/target.mk index 17eed8e94..44e5cd10b 100644 --- a/demo/src/server/nitlog/target.mk +++ b/demo/src/server/nitlog/target.mk @@ -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 diff --git a/os/include/timer_session/client.h b/os/include/timer_session/client.h index 93add33fa..2e80c96ff 100644 --- a/os/include/timer_session/client.h +++ b/os/include/timer_session/client.h @@ -26,9 +26,11 @@ namespace Timer { explicit Session_client(Session_capability session) : Genode::Rpc_client(session) { } - void msleep(unsigned ms) { call(ms); } + void trigger_once(unsigned us) { call(us); } - void usleep(unsigned us) { call(us); } + void trigger_periodic(unsigned us) { call(us); } + + void sigh(Signal_context_capability sigh) { call(sigh); } unsigned long elapsed_ms() const { return call(); } }; diff --git a/os/include/timer_session/connection.h b/os/include/timer_session/connection.h index e14c438f6..34842857e 100644 --- a/os/include/timer_session/connection.h +++ b/os/include/timer_session/connection.h @@ -19,20 +19,61 @@ namespace Timer { - struct Connection : Genode::Connection, Session_client + class Connection : public Genode::Connection, 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("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("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); + } }; } diff --git a/os/include/timer_session/server.h b/os/include/timer_session/server.h deleted file mode 100644 index 3beeef2f1..000000000 --- a/os/include/timer_session/server.h +++ /dev/null @@ -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 -#include - -namespace Timer { - - struct Session_server : Genode::Rpc_object { }; -} - -#endif /* _INCLUDE__TIMER_SESSION__SERVER_H_ */ diff --git a/os/include/timer_session/timer_session.h b/os/include/timer_session/timer_session.h index 92013ea9f..026b445e3 100644 --- a/os/include/timer_session/timer_session.h +++ b/os/include/timer_session/timer_session.h @@ -16,10 +16,13 @@ #ifndef _INCLUDE__TIMER_SESSION__TIMER_SESSION_H_ #define _INCLUDE__TIMER_SESSION__TIMER_SESSION_H_ +#include #include 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); }; } diff --git a/os/run/timer.run b/os/run/timer.run index 594210ef7..9601ac668 100644 --- a/os/run/timer.run +++ b/os/run/timer.run @@ -24,6 +24,7 @@ install_config { + diff --git a/os/src/drivers/framebuffer/pl11x/pbxa9/target.mk b/os/src/drivers/framebuffer/pl11x/pbxa9/target.mk index dbfeb770d..0c093e933 100644 --- a/os/src/drivers/framebuffer/pl11x/pbxa9/target.mk +++ b/os/src/drivers/framebuffer/pl11x/pbxa9/target.mk @@ -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)/.. diff --git a/os/src/drivers/framebuffer/pl11x/vea9x4/target.mk b/os/src/drivers/framebuffer/pl11x/vea9x4/target.mk index 7c8f2cc05..81cb4a36b 100644 --- a/os/src/drivers/framebuffer/pl11x/vea9x4/target.mk +++ b/os/src/drivers/framebuffer/pl11x/vea9x4/target.mk @@ -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)/.. diff --git a/os/src/drivers/framebuffer/pl11x/vpb926/target.mk b/os/src/drivers/framebuffer/pl11x/vpb926/target.mk index 9a5a97d28..6186a8303 100644 --- a/os/src/drivers/framebuffer/pl11x/vpb926/target.mk +++ b/os/src/drivers/framebuffer/pl11x/vpb926/target.mk @@ -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)/.. diff --git a/os/src/drivers/timer/codezero/platform_timer.cc b/os/src/drivers/timer/codezero/platform_timer.cc index 48e438f31..5efdee5dc 100644 --- a/os/src/drivers/timer/codezero/platform_timer.cc +++ b/os/src/drivers/timer/codezero/platform_timer.cc @@ -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; diff --git a/os/src/drivers/timer/codezero/target.mk b/os/src/drivers/timer/codezero/target.mk index 25295345f..2db57fec8 100644 --- a/os/src/drivers/timer/codezero/target.mk +++ b/os/src/drivers/timer/codezero/target.mk @@ -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 diff --git a/os/src/drivers/timer/fiasco/platform_timer.cc b/os/src/drivers/timer/fiasco/platform_timer.cc index 9c0ba4b6b..a29315144 100644 --- a/os/src/drivers/timer/fiasco/platform_timer.cc +++ b/os/src/drivers/timer/fiasco/platform_timer.cc @@ -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; diff --git a/os/src/drivers/timer/fiasco/target.mk b/os/src/drivers/timer/fiasco/target.mk index 887a0dd13..da3130926 100644 --- a/os/src/drivers/timer/fiasco/target.mk +++ b/os/src/drivers/timer/fiasco/target.mk @@ -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 diff --git a/os/src/drivers/timer/foc/target.mk b/os/src/drivers/timer/foc/target.mk index b8e870cd3..1ca2e01b1 100644 --- a/os/src/drivers/timer/foc/target.mk +++ b/os/src/drivers/timer/foc/target.mk @@ -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 diff --git a/os/src/drivers/timer/foc/timer_root.h b/os/src/drivers/timer/foc/timer_root.h deleted file mode 100644 index b6bd1980f..000000000 --- a/os/src/drivers/timer/foc/timer_root.h +++ /dev/null @@ -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 -#include -#include -#include -#include -#include - -#include "timer_session_component.h" - - -namespace Timer { - - class Root_component : public Genode::Rpc_object > - { - private: - - Genode::Allocator *_md_alloc; - Genode::Cap_session *_cap_session; - Genode::List _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 diff --git a/os/src/drivers/timer/foc/timer_session_component.h b/os/src/drivers/timer/foc/timer_session_component.h deleted file mode 100644 index bba9b3a66..000000000 --- a/os/src/drivers/timer/foc/timer_session_component.h +++ /dev/null @@ -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 -#include -#include - -/* Fiasco.OC includes */ -namespace Fiasco { -#include -#include -} - - -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, - public Genode::List::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()), - _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::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 diff --git a/os/src/drivers/timer/hw/pbxa9/target.mk b/os/src/drivers/timer/hw/pbxa9/target.mk index 7090d75fd..f5be995ec 100755 --- a/os/src/drivers/timer/hw/pbxa9/target.mk +++ b/os/src/drivers/timer/hw/pbxa9/target.mk @@ -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)/../.. diff --git a/os/src/drivers/timer/hw/platform_timer.h b/os/src/drivers/timer/hw/platform_timer.h index dfa680888..a0337475c 100755 --- a/os/src/drivers/timer/hw/platform_timer.h +++ b/os/src/drivers/timer/hw/platform_timer.h @@ -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); } diff --git a/os/src/drivers/timer/hw/vea9x4/target.mk b/os/src/drivers/timer/hw/vea9x4/target.mk index 0b6b36e76..c511aebae 100755 --- a/os/src/drivers/timer/hw/vea9x4/target.mk +++ b/os/src/drivers/timer/hw/vea9x4/target.mk @@ -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)/../.. diff --git a/os/src/drivers/timer/include/timer_root.h b/os/src/drivers/timer/include/timer_root.h index 63e05cdac..b10c416c7 100644 --- a/os/src/drivers/timer/include/timer_root.h +++ b/os/src/drivers/timer/include/timer_root.h @@ -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_ep, md_alloc), - _timeout_scheduler(&_platform_timer, session_ep), - _entrypoint(session_ep) + _timeout_scheduler(&_platform_timer, session_ep) { } }; } diff --git a/os/src/drivers/timer/include/timer_session_component.h b/os/src/drivers/timer/include/timer_session_component.h index eaa351b4e..549c0fdbd 100644 --- a/os/src/drivers/timer/include/timer_session_component.h +++ b/os/src/drivers/timer/include/timer_session_component.h @@ -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 + class Irq_dispatcher_component : public Rpc_object { 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, - public Genode::List::Element + class Session_component : public Rpc_object, + public List::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 */ } }; } diff --git a/os/src/drivers/timer/include_periodic/platform_timer.h b/os/src/drivers/timer/include_periodic/platform_timer.h index c516c8a2e..36c961a8d 100644 --- a/os/src/drivers/timer/include_periodic/platform_timer.h +++ b/os/src/drivers/timer/include_periodic/platform_timer.h @@ -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 diff --git a/os/src/drivers/timer/include_pit/platform_timer.h b/os/src/drivers/timer/include_pit/platform_timer.h index 5541c0dfa..1f153e52c 100644 --- a/os/src/drivers/timer/include_pit/platform_timer.h +++ b/os/src/drivers/timer/include_pit/platform_timer.h @@ -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(this)->_read_counter(&wrapped); /* determine the time since we looked at the counter */ if (wrapped) diff --git a/os/src/drivers/timer/linux/platform_timer.cc b/os/src/drivers/timer/linux/platform_timer.cc index 6bf0ec370..2219536a7 100644 --- a/os/src/drivers/timer/linux/platform_timer.cc +++ b/os/src/drivers/timer/linux/platform_timer.cc @@ -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); diff --git a/os/src/drivers/timer/linux/target.mk b/os/src/drivers/timer/linux/target.mk index 3e9df1d4f..12cf9e45c 100644 --- a/os/src/drivers/timer/linux/target.mk +++ b/os/src/drivers/timer/linux/target.mk @@ -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)/.. diff --git a/os/src/drivers/timer/nova/target.mk b/os/src/drivers/timer/nova/target.mk index 640526f42..2d1930356 100644 --- a/os/src/drivers/timer/nova/target.mk +++ b/os/src/drivers/timer/nova/target.mk @@ -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)/.. diff --git a/os/src/drivers/timer/nova/timer_root.h b/os/src/drivers/timer/nova/timer_root.h deleted file mode 100644 index 08cc79cee..000000000 --- a/os/src/drivers/timer/nova/timer_root.h +++ /dev/null @@ -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 -#include -#include -#include -#include -#include - -#include "timer_session_component.h" - - -namespace Timer { - - class Root_component : public Genode::Rpc_object > - { - private: - - Genode::Allocator *_md_alloc; - Platform_timer _platform_timer; - Timeout_scheduler _timeout_scheduler; - Genode::Cap_session *_cap_session; - Genode::Lock _sessions_lock; - Genode::List _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 diff --git a/os/src/drivers/timer/nova/timer_session_component.h b/os/src/drivers/timer/nova/timer_session_component.h deleted file mode 100644 index 7ed42a9ba..000000000 --- a/os/src/drivers/timer/nova/timer_session_component.h +++ /dev/null @@ -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 -#include -#include - -/* 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 - { - 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("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, - public Genode::List::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::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 diff --git a/os/src/drivers/timer/okl4_arm/platform_timer.cc b/os/src/drivers/timer/okl4_arm/platform_timer.cc deleted file mode 100644 index 2c87c2f63..000000000 --- a/os/src/drivers/timer/okl4_arm/platform_timer.cc +++ /dev/null @@ -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 - -/* local includes */ -#include "timer_session_component.h" - -/* OKL4 includes */ -namespace Okl4 { extern "C" { -#include -#include -} } - -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(); -} diff --git a/os/src/drivers/timer/okl4_arm/target.mk b/os/src/drivers/timer/okl4_arm/target.mk deleted file mode 100644 index 93cfc3916..000000000 --- a/os/src/drivers/timer/okl4_arm/target.mk +++ /dev/null @@ -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)/.. diff --git a/os/src/drivers/timer/okl4_x86/target.mk b/os/src/drivers/timer/okl4_x86/target.mk index 1b7f07807..6d725cad1 100644 --- a/os/src/drivers/timer/okl4_x86/target.mk +++ b/os/src/drivers/timer/okl4_x86/target.mk @@ -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 diff --git a/os/src/drivers/timer/pistachio/platform_timer.cc b/os/src/drivers/timer/pistachio/platform_timer.cc index 330aae3c8..22957f482 100644 --- a/os/src/drivers/timer/pistachio/platform_timer.cc +++ b/os/src/drivers/timer/pistachio/platform_timer.cc @@ -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; diff --git a/os/src/drivers/timer/pistachio/target.mk b/os/src/drivers/timer/pistachio/target.mk index c0589ee7a..d1bf1b328 100644 --- a/os/src/drivers/timer/pistachio/target.mk +++ b/os/src/drivers/timer/pistachio/target.mk @@ -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 diff --git a/os/src/server/nitpicker/genode/target.mk b/os/src/server/nitpicker/genode/target.mk index 694737b33..eaa5b382e 100644 --- a/os/src/server/nitpicker/genode/target.mk +++ b/os/src/server/nitpicker/genode/target.mk @@ -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 \ diff --git a/os/src/test/nitpicker/target.mk b/os/src/test/nitpicker/target.mk index bde367f9b..75abaecb8 100644 --- a/os/src/test/nitpicker/target.mk +++ b/os/src/test/nitpicker/target.mk @@ -1,3 +1,3 @@ TARGET = testnit SRC_CC = test.cc -LIBS = cxx env +LIBS = cxx env signal diff --git a/os/src/test/timer/target.mk b/os/src/test/timer/target.mk index 8c21c33c5..777c9434f 100644 --- a/os/src/test/timer/target.mk +++ b/os/src/test/timer/target.mk @@ -1,3 +1,3 @@ TARGET = test-timer SRC_CC = main.cc -LIBS = cxx env thread +LIBS = cxx env thread signal diff --git a/tool/autopilot.list b/tool/autopilot.list index 3af6df84d..9cf3bd613 100644 --- a/tool/autopilot.list +++ b/tool/autopilot.list @@ -1,4 +1,5 @@ ldso +timer lwip rm_fault rom_blk