vancouver: Timer support

This required usleep to be added to the timer interface.
This commit is contained in:
Markus Partheymueller
2012-11-05 16:48:40 +01:00
committed by Norman Feske
parent aea0a7284f
commit 2d2373a03b
7 changed files with 123 additions and 11 deletions

View File

@ -1,11 +1,13 @@
/* /*
* \brief Client-side timer session interface * \brief Client-side timer session interface
* \author Norman Feske * \author Norman Feske
* \author Markus Partheymueller
* \date 2006-05-31 * \date 2006-05-31
*/ */
/* /*
* Copyright (C) 2006-2013 Genode Labs GmbH * Copyright (C) 2006-2013 Genode Labs GmbH
* Copyright (C) 2012 Intel Corporation
* *
* This file is part of the Genode OS framework, which is distributed * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
@ -26,6 +28,8 @@ namespace Timer {
void msleep(unsigned ms) { call<Rpc_msleep>(ms); } void msleep(unsigned ms) { call<Rpc_msleep>(ms); }
void usleep(unsigned us) { call<Rpc_usleep>(us); }
unsigned long elapsed_ms() const { return call<Rpc_elapsed_ms>(); } unsigned long elapsed_ms() const { return call<Rpc_elapsed_ms>(); }
}; };
} }

View File

@ -1,11 +1,13 @@
/* /*
* \brief Timer session interface * \brief Timer session interface
* \author Norman Feske * \author Norman Feske
* \author Markus Partheymueller
* \date 2006-08-15 * \date 2006-08-15
*/ */
/* /*
* Copyright (C) 2006-2013 Genode Labs GmbH * Copyright (C) 2006-2013 Genode Labs GmbH
* Copyright (C) 2012 Intel Corporation
* *
* This file is part of the Genode OS framework, which is distributed * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
@ -29,6 +31,11 @@ namespace Timer {
*/ */
virtual void msleep(unsigned ms) = 0; virtual void msleep(unsigned ms) = 0;
/**
* Sleep number of microseconds
*/
virtual void usleep(unsigned us) = 0;
/** /**
* Return number of elapsed milliseconds since session creation * Return number of elapsed milliseconds since session creation
*/ */
@ -46,9 +53,10 @@ namespace Timer {
*********************/ *********************/
GENODE_RPC(Rpc_msleep, void, msleep, unsigned); GENODE_RPC(Rpc_msleep, void, msleep, unsigned);
GENODE_RPC(Rpc_usleep, void, usleep, unsigned);
GENODE_RPC(Rpc_elapsed_ms, unsigned long, elapsed_ms); GENODE_RPC(Rpc_elapsed_ms, unsigned long, elapsed_ms);
GENODE_RPC_INTERFACE(Rpc_msleep, Rpc_elapsed_ms); GENODE_RPC_INTERFACE(Rpc_msleep, Rpc_usleep, Rpc_elapsed_ms);
}; };
} }

View File

@ -2,11 +2,13 @@
* \brief Instance of the timer session interface * \brief Instance of the timer session interface
* \author Norman Feske * \author Norman Feske
* \author Stefan Kalkowski * \author Stefan Kalkowski
* \author Markus Partheymueller
* \date 2010-01-30 * \date 2010-01-30
*/ */
/* /*
* Copyright (C) 2010-2013 Genode Labs GmbH * Copyright (C) 2010-2013 Genode Labs GmbH
* Copyright (C) 2012 Intel Corporation
* *
* This file is part of the Genode OS framework, which is distributed * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
@ -120,6 +122,13 @@ namespace Timer {
l4_ipc_sleep(l4_timeout(L4_IPC_TIMEOUT_NEVER, mus_to_timeout(1000*ms))); 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 unsigned long elapsed_ms() const
{ {
return (_kip->clock - _initial_clock_value) / 1000; return (_kip->clock - _initial_clock_value) / 1000;

View File

@ -1,11 +1,13 @@
/* /*
* \brief Instance of the timer session interface * \brief Instance of the timer session interface
* \author Norman Feske * \author Norman Feske
* \author Markus Partheymueller
* \date 2006-08-15 * \date 2006-08-15
*/ */
/* /*
* Copyright (C) 2006-2013 Genode Labs GmbH * Copyright (C) 2006-2013 Genode Labs GmbH
* Copyright (C) 2012 Intel Corporation
* *
* This file is part of the Genode OS framework, which is distributed * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
@ -234,9 +236,14 @@ namespace Timer {
*****************************/ *****************************/
void msleep(unsigned ms) void msleep(unsigned ms)
{
usleep(1000*ms);
}
void usleep(unsigned us)
{ {
_wake_up_alarm.reply_cap(_entrypoint->reply_dst()); _wake_up_alarm.reply_cap(_entrypoint->reply_dst());
_timeout_scheduler->schedule_timeout(&_wake_up_alarm, 1000*ms); _timeout_scheduler->schedule_timeout(&_wake_up_alarm, us);
/* /*
* Prevent the server activation from immediately answering the * Prevent the server activation from immediately answering the

View File

@ -1,11 +1,13 @@
/* /*
* \brief Instance of the timer session interface * \brief Instance of the timer session interface
* \author Norman Feske * \author Norman Feske
* \author Markus Partheymueller
* \date 2010-01-30 * \date 2010-01-30
*/ */
/* /*
* Copyright (C) 2010-2013 Genode Labs GmbH * Copyright (C) 2010-2013 Genode Labs GmbH
* Copyright (C) 2012 Intel Corporation
* *
* This file is part of the Genode OS framework, which is distributed * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
@ -182,7 +184,12 @@ namespace Timer {
void msleep(unsigned ms) void msleep(unsigned ms)
{ {
_timeout_scheduler->schedule_timeout(&_wake_up_alarm, 1000*ms); usleep(1000*ms);
}
void usleep(unsigned us)
{
_timeout_scheduler->schedule_timeout(&_wake_up_alarm, us);
/* /*
* Prevent the server activation from immediately answering the * Prevent the server activation from immediately answering the

View File

@ -44,6 +44,8 @@
#include <rm_session/connection.h> #include <rm_session/connection.h>
#include <cap_session/connection.h> #include <cap_session/connection.h>
#include <os/config.h> #include <os/config.h>
#include <os/alarm.h>
#include <timer_session/connection.h>
#include <nova_cpu_session/connection.h> #include <nova_cpu_session/connection.h>
/* NOVA includes that come with Genode */ /* NOVA includes that come with Genode */
@ -77,6 +79,66 @@ enum { verbose_io = false };
* Used for startup synchronization and coarse-grained locking. * Used for startup synchronization and coarse-grained locking.
*/ */
Genode::Lock global_lock(Genode::Lock::LOCKED); Genode::Lock global_lock(Genode::Lock::LOCKED);
Genode::Lock timeouts_lock(Genode::Lock::UNLOCKED);
/* Timer Service */
using Genode::Thread;
using Genode::Alarm_scheduler;
using Genode::Alarm;
class Alarm_thread : Thread<4096>, public Alarm_scheduler
{
private:
Timer::Connection _timer;
Alarm::Time _curr_time; /* jiffies value */
Motherboard &_motherboard;
TimeoutList<32, void> &_timeouts;
/**
* Thread entry function
*/
void entry()
{
while (true) {
unsigned long long now = _motherboard.clock()->time();
unsigned nr;
timeouts_lock.lock();
while ((nr = _timeouts.trigger(now))) {
MessageTimeout msg(nr, _timeouts.timeout());
if (_timeouts.cancel(nr) < 0)
Logging::printf("Timeout not cancelled.\n");
timeouts_lock.unlock();
_motherboard.bus_timeout.send(msg);
timeouts_lock.lock();
}
timeouts_lock.unlock();
_timer.usleep(1000);
}
}
public:
/**
* Constructor
*/
Alarm_thread(Motherboard &mb, TimeoutList<32, void> &timeouts)
: _curr_time(0), _motherboard(mb), _timeouts(timeouts) { start(); }
Alarm::Time curr_time() { return _curr_time; }
unsigned long long curr_time_long() { return _motherboard.clock()->time(); }
};
/** /**
@ -898,6 +960,7 @@ class Machine : public StaticReceiver<Machine>
TimeoutList<32, void> _timeouts; TimeoutList<32, void> _timeouts;
Guest_memory &_guest_memory; Guest_memory &_guest_memory;
Boot_module_provider &_boot_modules; Boot_module_provider &_boot_modules;
Alarm_thread *_alarm_thread;
public: public:
@ -1086,14 +1149,26 @@ class Machine : public StaticReceiver<Machine>
if (verbose_debug) if (verbose_debug)
Logging::printf("TIMER_NEW\n"); Logging::printf("TIMER_NEW\n");
if (_alarm_thread == NULL) {
Logging::printf("Creating alarm thread\n");
_alarm_thread = new Alarm_thread(_motherboard, _timeouts);
}
timeouts_lock.lock();
msg.nr = _timeouts.alloc(); msg.nr = _timeouts.alloc();
timeouts_lock.unlock();
return true; return true;
case MessageTimer::TIMER_REQUEST_TIMEOUT: case MessageTimer::TIMER_REQUEST_TIMEOUT:
timeouts_lock.lock();
if (_timeouts.request(msg.nr, msg.abstime) < 0)
Logging::printf("Could not program timeout.\n");
timeouts_lock.unlock();
if (verbose_debug)
Logging::printf("TIMER_REQUEST_TIMEOUT\n");
_timeouts.request(msg.nr, msg.abstime);
return true; return true;
default: default:
@ -1103,9 +1178,11 @@ class Machine : public StaticReceiver<Machine>
bool receive(MessageTime &msg) bool receive(MessageTime &msg)
{ {
if (verbose_debug) // XXX: Use RTC time
Logging::printf("MessageTime - not implemented\n"); msg.wallclocktime = 0;
return false; msg.timestamp = 0;
return true;
} }
bool receive(MessageNetwork &msg) bool receive(MessageNetwork &msg)

View File

@ -10,7 +10,7 @@ ifeq ($(wildcard $(VANCOUVER_DIR)),)
REQUIRES += prepare_ports_vancouver REQUIRES += prepare_ports_vancouver
endif endif
LIBS += cxx env thread server LIBS += cxx env thread alarm signal server
SRC_CC = main.cc nova_user_env.cc device_model_registry.cc SRC_CC = main.cc nova_user_env.cc device_model_registry.cc
# #