mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-05 02:03:07 +00:00
* get rid of alarm abstraction * get rid of Timeout::Time type * get rid of pointer arguments * get rid of _discard_timeout indirection * get rid of 65th bit in stored time values * get rid of Timeout_scheduler interface * get rid of uninitialized deadlines * get rid of default arguments * get rid of Timeout::_periodic * get rid of Timeout::Raw * use list abstraction * only one interface for timeout handlers * rework locking scheme to be smp safe * move all method definitions to CC file * name mutexes more accurate * fix when & how to set time-source timeout * fix deadlocks Fixes #3884
69 lines
1.6 KiB
C++
69 lines
1.6 KiB
C++
/*
|
|
* \brief Time source using Nova timed semaphore down
|
|
* \author Alexander Boettcher
|
|
* \author Martin Stein
|
|
* \date 2014-06-24
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2014-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.
|
|
*/
|
|
|
|
/* NOVA includes */
|
|
#include <nova/native_thread.h>
|
|
|
|
/* local includes */
|
|
#include <time_source.h>
|
|
|
|
using namespace Genode;
|
|
using namespace Nova;
|
|
|
|
|
|
void Timer::Time_source::set_timeout(Microseconds duration,
|
|
Timeout_handler &handler)
|
|
{
|
|
/* set new timeout parameters and wake up the blocking thread */
|
|
Threaded_time_source::handler(handler);
|
|
_timeout_us = duration.value;
|
|
if (_sem) {
|
|
if (Nova::sm_ctrl(_sem, Nova::SEMAPHORE_UP) != Nova::NOVA_OK) {
|
|
nova_die();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
Timer::Time_source::Result_of_wait_for_irq
|
|
Timer::Time_source::_wait_for_irq()
|
|
{
|
|
/* initialize semaphore if not done yet */
|
|
if (!_sem) {
|
|
auto const &exc_base = Thread::native_thread().exc_pt_sel;
|
|
request_signal_sm_cap(exc_base + Nova::PT_SEL_PAGE_FAULT,
|
|
exc_base + Nova::SM_SEL_SIGNAL);
|
|
|
|
_sem = Thread::native_thread().exc_pt_sel + SM_SEL_SIGNAL;
|
|
}
|
|
/* calculate absolute timeout */
|
|
unsigned long long const deadline_timestamp {
|
|
_timeout_us <= max_timeout().value ?
|
|
Trace::timestamp() + _timeout_us * (_tsc_khz / TSC_FACTOR) : 0 };
|
|
|
|
/* block until timeout fires or it gets canceled */
|
|
switch (sm_ctrl(_sem, SEMAPHORE_DOWN, deadline_timestamp)) {
|
|
|
|
case Nova::NOVA_TIMEOUT:
|
|
return IRQ_TRIGGERED;
|
|
|
|
case Nova::NOVA_OK:
|
|
return CANCELLED;
|
|
|
|
default:
|
|
nova_die();
|
|
return CANCELLED;
|
|
}
|
|
}
|