mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-10 23:13:01 +00:00
eba9c15746
The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
249 lines
5.7 KiB
C++
249 lines
5.7 KiB
C++
/*
|
|
* \brief Multiplexing one time source amongst different timeouts
|
|
* \author Martin Stein
|
|
* \date 2016-11-04
|
|
*
|
|
* These classes are not meant to be used directly. They merely exist to share
|
|
* the generic parts of timeout-scheduling between the Timer::Connection and the
|
|
* Timer driver. For user-level timeout-scheduling you should use the interface
|
|
* in timer_session/connection.h instead.
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2016-2017 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU Affero General Public License version 3.
|
|
*/
|
|
|
|
#ifndef _TIMER__TIMEOUT_H_
|
|
#define _TIMER__TIMEOUT_H_
|
|
|
|
/* Genode includes */
|
|
#include <util/noncopyable.h>
|
|
#include <os/alarm.h>
|
|
#include <base/log.h>
|
|
#include <os/duration.h>
|
|
|
|
namespace Genode {
|
|
|
|
class Time_source;
|
|
class Timeout_scheduler;
|
|
class Timeout;
|
|
class Alarm_timeout_scheduler;
|
|
}
|
|
|
|
namespace Timer
|
|
{
|
|
class Connection;
|
|
class Root_component;
|
|
}
|
|
|
|
|
|
/**
|
|
* Interface of a time source that can handle one timeout at a time
|
|
*/
|
|
struct Genode::Time_source : Interface
|
|
{
|
|
/**
|
|
* Interface of a timeout callback
|
|
*/
|
|
struct Timeout_handler : Interface
|
|
{
|
|
virtual void handle_timeout(Duration curr_time) = 0;
|
|
};
|
|
|
|
/**
|
|
* Return the current time of the source
|
|
*/
|
|
virtual Duration curr_time() = 0;
|
|
|
|
/**
|
|
* Return the maximum timeout duration that the source can handle
|
|
*/
|
|
virtual Microseconds max_timeout() const = 0;
|
|
|
|
/**
|
|
* Install a timeout, overrides the last timeout if any
|
|
*
|
|
* \param duration timeout duration
|
|
* \param handler timeout callback
|
|
*/
|
|
virtual void schedule_timeout(Microseconds duration,
|
|
Timeout_handler &handler) = 0;
|
|
|
|
/**
|
|
* Tell the time source which scheduler to use for its own timeouts
|
|
*
|
|
* This method enables a time source for example to synchronize with an
|
|
* accurate but expensive timer only on a periodic basis while using a
|
|
* cheaper interpolation in general.
|
|
*/
|
|
virtual void scheduler(Timeout_scheduler &) { };
|
|
};
|
|
|
|
|
|
/**
|
|
* Interface of a time-source multiplexer
|
|
*
|
|
* Beside 'curr_time()', this abstract interface is used by the Timeout
|
|
* implementation only. Users of the timeout framework must schedule and
|
|
* discard timeouts via methods of the timeout.
|
|
*/
|
|
class Genode::Timeout_scheduler : Interface
|
|
{
|
|
private:
|
|
|
|
friend Timeout;
|
|
|
|
/**
|
|
* Add a one-shot timeout to the schedule
|
|
*
|
|
* \param timeout timeout callback object
|
|
* \param duration timeout trigger delay
|
|
*/
|
|
virtual void _schedule_one_shot(Timeout &timeout, Microseconds duration) = 0;
|
|
|
|
/**
|
|
* Add a periodic timeout to the schedule
|
|
*
|
|
* \param timeout timeout callback object
|
|
* \param duration timeout trigger period
|
|
*/
|
|
virtual void _schedule_periodic(Timeout &timeout, Microseconds duration) = 0;
|
|
|
|
/**
|
|
* Remove timeout from the scheduler
|
|
*
|
|
* \param timeout corresponding timeout callback object
|
|
*/
|
|
virtual void _discard(Timeout &timeout) = 0;
|
|
|
|
public:
|
|
|
|
/**
|
|
* Read out the now time of the scheduler
|
|
*/
|
|
virtual Duration curr_time() = 0;
|
|
};
|
|
|
|
|
|
/**
|
|
* Timeout callback that can be used for both one-shot and periodic timeouts
|
|
*
|
|
* This class should be used only if it is necessary to use one timeout
|
|
* callback for both periodic and one-shot timeouts. This is the case, for
|
|
* example, in a Timer-session server. If this is not the case, the classes
|
|
* Periodic_timeout and One_shot_timeout are the better choice.
|
|
*/
|
|
class Genode::Timeout : private Noncopyable
|
|
{
|
|
friend class Alarm_timeout_scheduler;
|
|
|
|
public:
|
|
|
|
/**
|
|
* Interface of a timeout handler
|
|
*/
|
|
struct Handler : Interface
|
|
{
|
|
virtual void handle_timeout(Duration curr_time) = 0;
|
|
};
|
|
|
|
private:
|
|
|
|
class Alarm : public Genode::Alarm
|
|
{
|
|
private:
|
|
|
|
/*
|
|
* Noncopyable
|
|
*/
|
|
Alarm(Alarm const &);
|
|
Alarm &operator = (Alarm const &);
|
|
|
|
public:
|
|
|
|
Timeout_scheduler &timeout_scheduler;
|
|
Handler *handler = nullptr;
|
|
bool periodic = false;
|
|
|
|
Alarm(Timeout_scheduler &timeout_scheduler)
|
|
: timeout_scheduler(timeout_scheduler) { }
|
|
|
|
|
|
/*******************
|
|
** Genode::Alarm **
|
|
*******************/
|
|
|
|
bool on_alarm(unsigned) override;
|
|
|
|
} _alarm;
|
|
|
|
public:
|
|
|
|
Timeout(Timeout_scheduler &timeout_scheduler)
|
|
: _alarm(timeout_scheduler) { }
|
|
|
|
~Timeout() { discard(); }
|
|
|
|
void schedule_periodic(Microseconds duration, Handler &handler);
|
|
|
|
void schedule_one_shot(Microseconds duration, Handler &handler);
|
|
|
|
void discard();
|
|
|
|
bool scheduled() { return _alarm.handler != nullptr; }
|
|
};
|
|
|
|
|
|
/**
|
|
* Timeout-scheduler implementation using the Alarm framework
|
|
*/
|
|
class Genode::Alarm_timeout_scheduler : private Noncopyable,
|
|
public Timeout_scheduler,
|
|
public Time_source::Timeout_handler
|
|
{
|
|
friend class Timer::Connection;
|
|
friend class Timer::Root_component;
|
|
|
|
private:
|
|
|
|
Time_source &_time_source;
|
|
Alarm_scheduler _alarm_scheduler;
|
|
|
|
void _enable();
|
|
|
|
|
|
/**********************************
|
|
** Time_source::Timeout_handler **
|
|
**********************************/
|
|
|
|
void handle_timeout(Duration curr_time) override;
|
|
|
|
|
|
/***********************
|
|
** Timeout_scheduler **
|
|
***********************/
|
|
|
|
void _schedule_one_shot(Timeout &timeout, Microseconds duration) override;
|
|
void _schedule_periodic(Timeout &timeout, Microseconds duration) override;
|
|
|
|
void _discard(Timeout &timeout) override {
|
|
_alarm_scheduler.discard(&timeout._alarm); }
|
|
|
|
public:
|
|
|
|
Alarm_timeout_scheduler(Time_source &time_source,
|
|
Microseconds min_handle_period = Microseconds(1));
|
|
|
|
|
|
/***********************
|
|
** Timeout_scheduler **
|
|
***********************/
|
|
|
|
Duration curr_time() override { return _time_source.curr_time(); }
|
|
};
|
|
|
|
#endif /* _TIMER__TIMEOUT_H_ */
|