- Added full-featured jumpto command.

- Minor fixes on the gui.


git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@901 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
matrevis 2006-08-18 00:46:38 +00:00
parent d8694b2f5b
commit df4b32f1ba
9 changed files with 339 additions and 68 deletions

View File

@ -187,6 +187,7 @@ src_backend_libbackend_la_SOURCES = \
src/backend/serializer_error.cc \ src/backend/serializer_error.cc \
src/backend/serializers_gatekeeper.cc \ src/backend/serializers_gatekeeper.cc \
src/backend/simulation.cc \ src/backend/simulation.cc \
src/backend/simulation_observer.cc \
src/backend/static_process.cc \ src/backend/static_process.cc \
src/backend/static_request.cc \ src/backend/static_request.cc \
src/backend/static_resource.cc \ src/backend/static_resource.cc \
@ -233,6 +234,7 @@ pkginclude_HEADERS += \
src/backend/serializer_error.hh \ src/backend/serializer_error.hh \
src/backend/serializers_gatekeeper.hh \ src/backend/serializers_gatekeeper.hh \
src/backend/simulation.hh \ src/backend/simulation.hh \
src/backend/simulation_observer.hh \
src/backend/sub_request.hh \ src/backend/sub_request.hh \
src/backend/thread.hh \ src/backend/thread.hh \
src/backend/user_interrupt_exception.hh src/backend/user_interrupt_exception.hh

View File

@ -13,6 +13,7 @@
<property name="default_height">300</property> <property name="default_height">300</property>
<property name="resizable">True</property> <property name="resizable">True</property>
<property name="destroy_with_parent">False</property> <property name="destroy_with_parent">False</property>
<property name="icon_name">gtk-preferences</property>
<property name="decorated">True</property> <property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property> <property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property> <property name="skip_pager_hint">False</property>
@ -551,7 +552,7 @@
<child> <child>
<widget class="GtkVBox" id="Speed.VBox"> <widget class="GtkVBox" id="Speed.VBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="homogeneous">True</property> <property name="homogeneous">False</property>
<property name="spacing">0</property> <property name="spacing">0</property>
<child> <child>
@ -651,31 +652,6 @@
</packing> </packing>
</child> </child>
</widget> </widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="Spacing.Label">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing> <packing>
<property name="padding">0</property> <property name="padding">0</property>
<property name="expand">False</property> <property name="expand">False</property>

View File

@ -92,27 +92,6 @@
</widget> </widget>
</child> </child>
<child>
<widget class="GtkMenuItem" id="MenuItem.Simulation">
<property name="visible">True</property>
<property name="label" translatable="yes">_Simulation</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="MenuItem.Simulation_menu">
<child>
<widget class="GtkImageMenuItem" id="MenuItem.Simulation.Play">
<property name="visible">True</property>
<property name="label">gtk-media-play</property>
<property name="use_stock">True</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child> <child>
<widget class="GtkMenuItem" id="MenuItem.Edit"> <widget class="GtkMenuItem" id="MenuItem.Edit">
<property name="visible">True</property> <property name="visible">True</property>
@ -135,21 +114,38 @@
</child> </child>
<child> <child>
<widget class="GtkMenuItem" id="MenuItem.Help"> <widget class="GtkMenuItem" id="MenuItem.Simulation">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label" translatable="yes">_Help</property> <property name="label" translatable="yes">_Simulation</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<child> <child>
<widget class="GtkMenu" id="MenuItem.Help_menu"> <widget class="GtkMenu" id="MenuItem.Simulation_menu">
<child> <child>
<widget class="GtkImageMenuItem" id="MenuItem.Help.About"> <widget class="GtkImageMenuItem" id="MenuItem.Simulation.Play">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label">gtk-about</property> <property name="label">gtk-media-play</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
</widget> </widget>
</child> </child>
<child>
<widget class="GtkImageMenuItem" id="pause1">
<property name="visible">True</property>
<property name="label">gtk-media-pause</property>
<property name="use_stock">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="stop1">
<property name="visible">True</property>
<property name="label">gtk-media-stop</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_stop1_activate" last_modification_time="Thu, 17 Aug 2006 21:55:39 GMT"/>
</widget>
</child>
</widget> </widget>
</child> </child>
</widget> </widget>
@ -175,6 +171,27 @@
</child> </child>
</widget> </widget>
</child> </child>
<child>
<widget class="GtkMenuItem" id="MenuItem.Help">
<property name="visible">True</property>
<property name="label" translatable="yes">_Help</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="MenuItem.Help_menu">
<child>
<widget class="GtkImageMenuItem" id="MenuItem.Help.About">
<property name="visible">True</property>
<property name="label">gtk-about</property>
<property name="use_stock">True</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget> </widget>
<packing> <packing>
<property name="padding">0</property> <property name="padding">0</property>

View File

@ -19,6 +19,7 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "concrete_simulation.hh" #include "concrete_simulation.hh"
#include "simulation_observer.hh"
#include "scheduler.hh" #include "scheduler.hh"
#include "cpu_policies_gatekeeper.hh" #include "cpu_policies_gatekeeper.hh"
#include <glibmm/timer.h> #include <glibmm/timer.h>
@ -27,6 +28,11 @@
#include "smartp.tcc" #include "smartp.tcc"
#include <algorithm>
#include <cassert>
#include <functional>
#include <iostream>
using namespace std; using namespace std;
using namespace sgpem; using namespace sgpem;
using namespace memory; using namespace memory;
@ -34,7 +40,10 @@ using Glib::usleep;
ConcreteSimulation::ConcreteSimulation() : ConcreteSimulation::ConcreteSimulation() :
_state(state_stopped), _mode(true), _timer_interval(1000), _policy(NULL) _state(state_stopped), _mode(true), _timer_interval(1000), _policy(NULL)
{} {
_notify = false;
_front = 0;
}
void void
ConcreteSimulation::set_timer(unsigned int t) ConcreteSimulation::set_timer(unsigned int t)
@ -60,6 +69,37 @@ ConcreteSimulation::get_mode() const
return _mode; return _mode;
} }
void
ConcreteSimulation::jump_to(History::position p)
{
switch (_state)
{
case state_running:
pause();
break;
case state_stopped:
_history.reset(true);
_front = 0;
break;
default:
;
}
pause();
bool yet_to_finish = true;
while (yet_to_finish && p > _front)
yet_to_finish = step();
if (!yet_to_finish)
stop();
_history.get_size() << std::endl;
_front = p < _front ? p : _front;
notify_change();
}
void void
ConcreteSimulation::pause() ConcreteSimulation::pause()
{ {
@ -81,6 +121,7 @@ ConcreteSimulation::run() throw(UserInterruptException, NullPolicyException, Mal
return; return;
case state_stopped: case state_stopped:
_history.reset(true); _history.reset(true);
_front = 0;
break; break;
default: default:
; ;
@ -102,8 +143,12 @@ ConcreteSimulation::run() throw(UserInterruptException, NullPolicyException, Mal
try try
{ {
//step forward //step forward
bool yet_to_finish = Scheduler::get_instance().step_forward(_history, *get_policy()); bool yet_to_finish = true;
if (_front == get_history().get_size() - 1)
yet_to_finish = Scheduler::get_instance().step_forward(_history, *get_policy());
if (!yet_to_finish) stop(); if (!yet_to_finish) stop();
_front++;
notify_change();
//sleep //sleep
Glib::usleep(_timer_interval*1000); Glib::usleep(_timer_interval*1000);
@ -128,7 +173,11 @@ ConcreteSimulation::run() throw(UserInterruptException, NullPolicyException, Mal
{ {
assert(get_policy() != NULL); assert(get_policy() != NULL);
//step forward //step forward
bool yet_to_finish = Scheduler::get_instance().step_forward(_history, *get_policy()); bool yet_to_finish = true;
if (_front == get_history().get_size() - 1)
yet_to_finish = Scheduler::get_instance().step_forward(_history, *get_policy());
_front++;
notify_change();
if (yet_to_finish) if (yet_to_finish)
pause(); pause();
else else
@ -142,6 +191,34 @@ ConcreteSimulation::run() throw(UserInterruptException, NullPolicyException, Mal
} }
} }
bool
ConcreteSimulation::step()
throw(UserInterruptException, NullPolicyException, MalformedPolicyException)
{
if (get_policy() == NULL)
{
stop();
throw NullPolicyException("no policy selected");
}
try
{
assert(get_policy() != NULL);
//step forward
bool yet_to_finish = true;
if (_front == get_history().get_size() - 1)
yet_to_finish = Scheduler::get_instance().step_forward(_history, *get_policy());
_front++;
return yet_to_finish;
}
catch (const CPUPolicyException& e)
{
stop();
throw;
}
}
Simulation::state Simulation::state
ConcreteSimulation::get_state() const ConcreteSimulation::get_state() const
{ {
@ -154,6 +231,13 @@ ConcreteSimulation::get_history()
return _history; return _history;
} }
const ConcreteHistory&
ConcreteSimulation::get_history() const
{
return _history;
}
void void
ConcreteSimulation::set_policy(CPUPolicy* p) throw(CPUPolicyException) ConcreteSimulation::set_policy(CPUPolicy* p) throw(CPUPolicyException)
{ {

View File

@ -21,9 +21,16 @@
#ifndef CONCRETE_SIMULATION_HH #ifndef CONCRETE_SIMULATION_HH
#define CONCRETE_SIMULATION_HH 1 #define CONCRETE_SIMULATION_HH 1
#include "config.h"
#include "simulation.hh" #include "simulation.hh"
#include "concrete_history.hh" #include "concrete_history.hh"
#include <map>
#include <stdexcept>
#include <utility>
#include <vector>
namespace sgpem namespace sgpem
{ {
class ConcreteSimulation; class ConcreteSimulation;
@ -37,8 +44,12 @@ namespace sgpem
void pause(); void pause();
void jump_to(History::position p);
void stop(); void stop();
bool step() throw(UserInterruptException, NullPolicyException, MalformedPolicyException);
void set_timer(const unsigned int); void set_timer(const unsigned int);
int get_timer() const; int get_timer() const;
@ -56,8 +67,11 @@ namespace sgpem
ConcreteHistory& get_history(); ConcreteHistory& get_history();
const ConcreteHistory& get_history() const;
CPUPolicy* get_policy(); CPUPolicy* get_policy();
private: private:
state _state; state _state;
bool _mode; bool _mode;

View File

@ -18,11 +18,18 @@
// along with SGPEMv2; if not, write to the Free Software // along with SGPEMv2; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "config.h"
#include "simulation.hh" #include "simulation.hh"
#include "simulation_observer.hh"
#include "concrete_simulation.hh" #include "concrete_simulation.hh"
#include <algorithm>
#include <functional>
// Do not include in header file: // Do not include in header file:
#include "singleton.tcc" #include "singleton.tcc"
using namespace sgpem; using namespace sgpem;
// Explicit template instantiation to allow to export symbols from the DSO. // Explicit template instantiation to allow to export symbols from the DSO.
@ -37,3 +44,47 @@ Simulation::get_instance()
{ {
return Singleton<ConcreteSimulation>::get_instance(); return Singleton<ConcreteSimulation>::get_instance();
} }
void
Simulation::attach(SimulationObserver& observer)
{
_observers.push_back(&observer);
}
void
Simulation::detach(const SimulationObserver& observer)
{
_observers.erase(std::find(_observers.begin(),
_observers.end(),
&observer));
}
unsigned int Simulation::get_front() const
{
return _front;
}
void
Simulation::notify_change()
{
//if (!_notify) return; // what's the purpose of this?
for (RegisteredObservers::iterator it = _observers.begin();
it != _observers.end(); it++)
(*it)->update(*this);
}
bool
Simulation::set_notify_enabled(bool enabled)
{
bool old_value = _notify;
_notify = enabled;
// Force notify if we re-enable it
if (old_value == false && _notify == true)
notify_change();
return old_value;
}

View File

@ -25,15 +25,17 @@ namespace sgpem
{ {
class ConcreteSimulation; class ConcreteSimulation;
class CPUPolicy; class CPUPolicy;
class History; class SimulationObserver;
} }
#include "config.h" #include "config.h"
#include "history.hh"
#include "singleton.hh" #include "singleton.hh"
#include "user_interrupt_exception.hh" #include "user_interrupt_exception.hh"
#include "null_policy_exception.hh" #include "null_policy_exception.hh"
#include "malformed_policy_exception.hh" #include "malformed_policy_exception.hh"
#include <stdexcept>
#include <utility>
#include <vector> #include <vector>
namespace sgpem namespace sgpem
@ -97,6 +99,17 @@ namespace sgpem
*/ */
virtual void stop() = 0; virtual void stop() = 0;
/**
\brief Jumps the simulation to the specified instant
Pauses the simulation and jumps to the specified instant
*/
virtual void jump_to(History::position p) = 0;
/** /**
\brief Setter for the attribute timer_interval. \brief Setter for the attribute timer_interval.
@ -142,11 +155,43 @@ namespace sgpem
virtual History& get_history() = 0; virtual History& get_history() = 0;
virtual const History& get_history() const = 0;
virtual unsigned int get_front() const;
/** /**
* Small kludge to avoid the need for declaration of ConcreteSimulation * Small kludge to avoid the need for declaration of ConcreteSimulation
* by the calling code of Simulation::get_instance() * by the calling code of Simulation::get_instance()
*/ */
static Simulation& get_instance(); static Simulation& get_instance();
virtual void attach(SimulationObserver& observer);
virtual void detach(const SimulationObserver& observer);
/** \brief Enable/disable notifications to registered observers
*
* This is quite useful to disable momentarily notification while you
* do a bunch of insertions and/or deletions in one go, in order to
* speed up things.
*
* \return The old value
*/
virtual bool set_notify_enabled(bool enabled = true);
protected:
typedef std::vector<SimulationObserver*> RegisteredObservers;
RegisteredObservers _observers;
// since no constructor is available, these fields must be defined in concrete subclasses.
bool _notify;
History::position _front;
virtual void notify_change();
private:
}; };
} }

View File

@ -23,6 +23,7 @@
#include "backend/cpu_policy_manager.hh" #include "backend/cpu_policy_manager.hh"
#include "backend/policy_parameters.hh" #include "backend/policy_parameters.hh"
#include "backend/history.hh" #include "backend/history.hh"
#include "backend/simulation.hh"
#include "backend/serializers_gatekeeper.hh" #include "backend/serializers_gatekeeper.hh"
#include "backend/serializer.hh" #include "backend/serializer.hh"
#include "backend/static_process.hh" #include "backend/static_process.hh"
@ -31,6 +32,7 @@
#include "backend/static_request.hh" #include "backend/static_request.hh"
#include "backend/static_sub_request.hh" #include "backend/static_sub_request.hh"
#include "backend/concrete_history.hh" #include "backend/concrete_history.hh"
#include "backend/concrete_simulation.hh"
#include "text_simulation.hh" #include "text_simulation.hh"
@ -356,7 +358,7 @@ TextSimulation::on_run(const Tokens& arguments)
check_arguments_num(arguments, 0); check_arguments_num(arguments, 0);
// Listen for updates only during scheduling // Listen for updates only during scheduling
Simulation::get_instance().get_history().attach(*this); Simulation::get_instance().attach(*this);
try try
{ {
@ -393,7 +395,7 @@ TextSimulation::on_run(const Tokens& arguments)
p_stderr(_("\nSimulation is now stopped\n")); p_stderr(_("\nSimulation is now stopped\n"));
} }
Simulation::get_instance().get_history().detach(*this); Simulation::get_instance().detach(*this);
} }
void void
@ -404,6 +406,82 @@ TextSimulation::on_pause(const Tokens& arguments)
Simulation::get_instance().pause(); Simulation::get_instance().pause();
} }
void
TextSimulation::on_jumpto(const Tokens& arguments)
{
if (!check_arguments_num(arguments, 1))
return;
// Listen for updates only during scheduling
ustring _position = arguments[0];
History::position p;
try
{
int pos = string_to<int>(_position) + 1;
if (pos < 0)
{
p_stderr(_("ERROR: provided instant is out of range.\n"));
return;
}
p = static_cast<unsigned int>(pos);
}
catch (domain_error e)
{
p_stderr(_("ERROR: provided instant is not a valid integer\n"));
return;
}
catch (out_of_range e)
{
p_stderr(_("ERROR: the instant is not within range.\n")); // does this make sense?
return;
}
Simulation::get_instance().attach(*this);
try
{
Simulation::get_instance().jump_to(p);
}
catch (const UserInterruptException& e)
{
p_stderr(_("ERROR: "));
p_stderr(e.what());
p_stderr(_("\nSimulation is now stopped\n"));
}
catch (const MalformedPolicyException& e)
{
p_stderr(_("ERROR: "));
p_stderr(e.what());
p_stderr(_("\nSimulation is now stopped, and "
"the current policy will be deactivated\n"));
try
{
Simulation::get_instance().set_policy(NULL);
}
catch(const CPUPolicyException& f)
{
// should never happen
p_stderr(_("FATAL ERROR: unable to deactivate the policy: "));
p_stderr(f.what());
abort();
}
}
catch (const NullPolicyException& e)
{
p_stderr(_("ERROR: "));
p_stderr(e.what());
p_stderr(_("\nSimulation is now stopped\n"));
}
Simulation::get_instance().detach(*this);
}
void void
TextSimulation::on_stop(const Tokens& arguments) TextSimulation::on_stop(const Tokens& arguments)
{ {
@ -524,6 +602,8 @@ TextSimulation::on_help(const Tokens& arguments)
else if (command == "PAUSE") else if (command == "PAUSE")
p_stdout(_("-- PAUSE COMMAND --\nPauses the simulation. The next call to RUN will " p_stdout(_("-- PAUSE COMMAND --\nPauses the simulation. The next call to RUN will "
"continue it.\n")); "continue it.\n"));
else if (command == "JUMPTO")
p_stdout(_("-- JUMPTO COMMAND --\nPauses the simulation and jumps to the specified instant.\n"));
else if (command == "CONFIGURE-CPU-POLICY") else if (command == "CONFIGURE-CPU-POLICY")
p_stdout(_("-- CONFIGURE-CPU-POLICY COMMAND --\nConfigure parameters exposed by " p_stdout(_("-- CONFIGURE-CPU-POLICY COMMAND --\nConfigure parameters exposed by "
"the cpu policy.\n\nThis is currently the only way to control the behaviour of " "the cpu policy.\n\nThis is currently the only way to control the behaviour of "
@ -1458,6 +1538,7 @@ TextSimulation::parse_command(TextSimulation& sim, const ustring& str)
command_handlers["RUN"] = &TextSimulation::on_run; command_handlers["RUN"] = &TextSimulation::on_run;
command_handlers["STOP"] = &TextSimulation::on_stop; command_handlers["STOP"] = &TextSimulation::on_stop;
command_handlers["PAUSE"] = &TextSimulation::on_pause; command_handlers["PAUSE"] = &TextSimulation::on_pause;
command_handlers["JUMPTO"] = &TextSimulation::on_jumpto;
command_handlers["CONFIGURE-CPU-POLICY"] = &TextSimulation::on_configure_cpu_policy; command_handlers["CONFIGURE-CPU-POLICY"] = &TextSimulation::on_configure_cpu_policy;
command_handlers["HELP"] = &TextSimulation::on_help; command_handlers["HELP"] = &TextSimulation::on_help;
command_handlers["GET"] = &TextSimulation::on_get; command_handlers["GET"] = &TextSimulation::on_get;
@ -1553,7 +1634,7 @@ operator<<(ostream& os, Request::state state)
} }
void void
TextSimulation::update(const History& changed_history) TextSimulation::update(const Simulation& changed_simulation)
{ {
ostringstream oss; ostringstream oss;
int printed_instant; int printed_instant;
@ -1561,10 +1642,10 @@ TextSimulation::update(const History& changed_history)
// Print header for each instant: // Print header for each instant:
if (changed_history.get_size() > 1) if (changed_simulation.get_front() > 1)
printed_instant = static_cast<int>(changed_history.get_size()) - 2; printed_instant = static_cast<int>(changed_simulation.get_front()) - 1;
else else
printed_instant = -1; printed_instant = 0;
oss << endl << ">>>> " << printed_instant; oss << endl << ">>>> " << printed_instant;
@ -1572,7 +1653,7 @@ TextSimulation::update(const History& changed_history)
// Print ready queue // Print ready queue
oss << endl << _("READY QUEUE: { "); oss << endl << _("READY QUEUE: { ");
const Environment& env = changed_history.get_last_environment(); const Environment& env = changed_simulation.get_history().get_environment_at(changed_simulation.get_front());
const ReadyQueue& q = env.get_sorted_queue(); const ReadyQueue& q = env.get_sorted_queue();
for (unsigned int i = 0; i < q.size(); ++i) for (unsigned int i = 0; i < q.size(); ++i)

View File

@ -28,7 +28,7 @@
#include "templates/smartp.hh" #include "templates/smartp.hh"
//#include "backend/policy_parameters.hh" //#include "backend/policy_parameters.hh"
#include "backend/string_utils.hh" #include "backend/string_utils.hh"
#include "backend/history_observer.hh" #include "backend/simulation_observer.hh"
#include "smartp.hh" #include "smartp.hh"
@ -53,7 +53,7 @@ namespace sgpem
A command-based interface is used, so methods of the base class can be called with A command-based interface is used, so methods of the base class can be called with
a proper command string obtained from the input device(s). a proper command string obtained from the input device(s).
*/ */
class SG_DLLEXPORT TextSimulation : public HistoryObserver class SG_DLLEXPORT TextSimulation : public SimulationObserver
{ {
public: public:
TextSimulation(); TextSimulation();
@ -71,7 +71,7 @@ namespace sgpem
Prints the actual state of the simulation, with emphasis on the current Prints the actual state of the simulation, with emphasis on the current
status of the scheduling process (ready queue and running process). status of the scheduling process (ready queue and running process).
*/ */
virtual void update(const History& changed_history); virtual void update(const Simulation& changed_simulation);
bool check_arguments_num(const Tokens& arguments, unsigned int num); bool check_arguments_num(const Tokens& arguments, unsigned int num);
bool unsaved_ask_confirm() const; bool unsaved_ask_confirm() const;
@ -81,6 +81,7 @@ namespace sgpem
void get_parameter(CommandParameter<T>& parameter); void get_parameter(CommandParameter<T>& parameter);
void on_run(const Tokens& arguments); void on_run(const Tokens& arguments);
void on_pause(const Tokens& arguments); void on_pause(const Tokens& arguments);
void on_jumpto(const Tokens& arguments);
void on_stop(const Tokens& arguments); void on_stop(const Tokens& arguments);
void on_configure_cpu_policy(const Tokens& arguments); void on_configure_cpu_policy(const Tokens& arguments);
void on_help(const Tokens& arguments); void on_help(const Tokens& arguments);