Commit f1ff3ef4 authored by yoogx's avatar yoogx

* Add files for the monitoring API

        For issue #5
parent a3690ef4
#! /bin/sh
# The Boost version needed is the 1.55
# Under Linux, the following installation packages work
sudo apt-get install libboost-all-dev
sudo apt-get install aptitude
aptitude search boost
#Second option
#Needed to get a specific version of Boost
#wget -O boost_1_55_0.tar.gz http://sourceforge.net/projects/boost/files/boost/1.55.0/boost_1_55_0.tar.gz/download
#tar xzvf boost_1_55_0.tar.gz
#cd boost_1_55_0/
#sudo apt-get update
#sudo apt-get install build-essential g++ python-dev autotools-dev libicu-dev build-essential libbz2-dev libboost-all-dev
#./bootstrap.sh --prefix=/usr/local
AUTOMAKE_OPTIONS = no-dependencies
SUBDIRS=
EXTRA_DIST = $(srcdir)/hash.hh $(srcdir)/meta.hh $(srcdir)/state.hh \
$(srcdir)/trace.hh $(srcdir)/local_configuration.hh \
$(srcdir)/remote_configuration.hh $(srcdir)/state_types.hh \
$(srcdir)/trace_manager.hh
CLEANFILES = *~
hsrc = ${shell $(CYGPATH_U) '$(OCARINA_RUNTIME)/polyorb-hi-c/include'}
install-data-local:
$(INSTALL) -d $(DESTDIR)$(hsrc)
for f in $(EXTRA_DIST) $(CONFIG_HEADER); do \
$(INSTALL) -m 444 $$f $(DESTDIR)$(hsrc) ; \
done
uninstall-local:
rm -rf $(DESTDIR)$(hsrc)
#pragma once
#include <algorithm> // copy, equal
#include <array>
#include <cassert>
#include <iosfwd>
#include <iterator>
#include <memory> // unique_ptr
#include <boost/python.hpp>
namespace taste {
/*----------------------------------------------------------------------------*/
template <int tasks>
class schedule
{
public:
static_assert(tasks > 0, "The number of scheduling states must be over 0.");
private:
struct scheduling_data_type
{
unsigned int hyperperiod_length;
unsigned int task_name_matching;
// Should we share this amongst all states?
/* array_type ports_;
data_type() = default;
data_type(const data_type&) = default;
const request_type&
port_value(std::size_t thread_id, std::size_t port_id)
const noexcept
{
return ports_[Ports::jump_table[thread_id] + port_id];
}
request_type&
port_value(std::size_t thread_id, std::size_t port_id)
noexcept
{
return ports_[Ports::jump_table[thread_id] + port_id];
}
};
*/
std::unique_ptr<scheduling_data_type> ptr_;
public:
schedule()
: ptr_{std::make_unique<scheduling_data_type>()}
{}
schedule(const state& other)
: ptr_{std::make_unique<scheduling_data_type>(*other.ptr_)} // deep copy
{}
state&
operator=(const state& other)
{
if (this != &other)
{
ptr_ = std::make_unique<data_type>(*other.ptr_); // deep copy
}
return *this;
}
state(state&&) = default;
state& operator=(state&&) = default;
const request_type&
port_value(std::size_t thread_id, std::size_t port_id)
const noexcept
{
assert(thread_id < Ports::nb_threads && "Incorrect thread id");
assert(port_id < Ports::ports_for_thread[thread_id] && "Incorrect port id for this thread id");
return ptr_->port_value(thread_id, port_id);
}
request_type&
port_value(std::size_t thread_id, std::size_t port_id)
noexcept
{
assert(thread_id < Ports::nb_threads && "Incorrect thread id");
assert(port_id < Ports::ports_for_thread[thread_id] && "Incorrect port id for this thread id");
return ptr_->port_value(thread_id, port_id);
}
step_type
step()
const noexcept
{
return ptr_->step_;
}
step_type&
step()
noexcept
{
return ptr_->step_;
}
hyperperiod_type
hyperperiod()
const noexcept
{
return ptr_->hyperperiod_;
}
hyperperiod_type&
hyperperiod()
noexcept
{
return ptr_->hyperperiod_;
}
thread_event_type
thread_event()
const noexcept
{
return ptr_->thread_event_;
}
thread_event_type&
thread_event()
noexcept
{
return ptr_->thread_event_;
}
port_event_type
port_event()
const noexcept
{
return ptr_->port_event_;
}
port_event_type&
port_event()
noexcept
{
return ptr_->port_event_;
}
const char*
ports_data()
const noexcept
{
return reinterpret_cast<const char*>(ptr_->ports_.data());
}
const request_type&
ports(int index)
const noexcept
{
return ptr_->ports_[index];
}
static int
my_size()
{ int i = (sizeof(port_event_type) + sizeof(thread_event_type) + sizeof(hyperperiod_type) + sizeof(step_type));
// printf ("Progress report display, will be removed: port_event %d, thread_event %d,hpp_occ %d,hpp_step %d,\n",sizeof(port_event_type), sizeof(thread_event_type), sizeof(hyperperiod_type), sizeof(step_type));
// printf ("Progress report display, will be removed: request size %d, constant size %d\n\n*****************************************************************************************************\n", sizeof(request_type),i);
return ports_size*sizeof(request_type) + sizeof(port_event_type) + sizeof(thread_event_type) + sizeof(hyperperiod_type) + sizeof(step_type);
}
friend
bool
operator==(const state& lhs, const state& rhs)
noexcept
{
// Highly dangerous : we directly comparing memory contents, thus relying on correct
// initialization (to 0) of the underlying data.
return lhs.step() == rhs.step() and lhs.hyperperiod() == rhs.hyperperiod()
and std::equal(lhs.ports_data(), lhs.ports_data() + ports_size, rhs.ports_data());
}
};
/*------------------------------------------------------------------------------------------------*/
} // namespace taste
#pragma once
typedef unsigned int step_type;
typedef unsigned int hyperperiod_type;
typedef unsigned int thread_event_type;
typedef unsigned int port_event_type;
#pragma once
#include <algorithm> // for_each
namespace taste {
/*------------------------------------------------------------------------------------------------*/
template <typename T>
inline
void
hash_combine(std::size_t& seed, const T& x)
noexcept(noexcept(std::hash<T>()(x)))
{
seed ^= std::hash<T>()(x) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
/*------------------------------------------------------------------------------------------------*/
/// @brief Hash a range.
template <typename InputIterator>
inline
void
hash_combine(std::size_t& seed, InputIterator cit, InputIterator cend)
{
std::for_each(cit, cend, [&](const auto& v){hash_combine(seed, v);});
}
/*------------------------------------------------------------------------------------------------*/
} // namespace taste
#pragma once
#include <iosfwd>
#include "meta.hh"
#include "request.h"
#include "state.hh"
#include "trace.hh"
/*------------------------------------------------------------------------------------------------*/
// Parameter i in the template parameters list gives the number of ports for thread i.
// >>> TO GENERATE
using ports_type = taste::ports_table<1, 1>;
// <<< END TO GENERATE
using state_type = taste::state<__po_hi_request_t, ports_type>;
using trace_type = taste::trace<state_type>;
/*------------------------------------------------------------------------------------------------*/
inline // < Don't forget!
bool
operator==(const __po_hi_request_t& lhs, const __po_hi_request_t& rhs)
noexcept
{
if (lhs.port != rhs.port)
{
return false;
}
// lhs and rhs have the same port, it's OK to switch on the port of any of them.
switch (lhs.port)
{
// >>> TO GENERATE FOR EACH PORT in ENUM __po_hi_port_t
case producer_global_data_source:
return lhs.vars.producer_global_data_source.producer_global_data_source
== rhs.vars.producer_global_data_source.producer_global_data_source;
case result_consumer_global_data_sink:
return lhs.vars.result_consumer_global_data_sink.result_consumer_global_data_sink
== rhs.vars.result_consumer_global_data_sink.result_consumer_global_data_sink;
case consumer_global_data_sink:
return lhs.vars.consumer_global_data_sink.consumer_global_data_sink
== rhs.vars.consumer_global_data_sink.consumer_global_data_sink;
case result_producer_global_data_source:
return lhs.vars.result_producer_global_data_source.result_producer_global_data_source
== rhs.vars.result_producer_global_data_source.result_producer_global_data_source;
// <<< END TO GENERATE
default:
assert(false && "Should not be here");
__builtin_unreachable();
}
}
/*------------------------------------------------------------------------------------------------*/
namespace std {
template <>
struct hash <__po_hi_request_t>
{
std::size_t
operator()(const __po_hi_request_t& r)
const noexcept
{
// We need to know the underlying type of the port enum. Then, we can cast to this type
// and use the value of the enum to compute its hash value.
using ty = std::underlying_type_t<__po_hi_port_t>;
auto seed = std::hash<ty>()(static_cast<ty>(r.port));
switch (r.port)
{
// >>> TO GENERATE FOR EACH PORT in ENUM __po_hi_port_t
case producer_global_data_source:
taste::hash_combine(seed, r.vars.producer_global_data_source.producer_global_data_source);
break;
case result_consumer_global_data_sink:
taste::hash_combine(seed, r.vars.result_consumer_global_data_sink.result_consumer_global_data_sink);
break;
case consumer_global_data_sink:
taste::hash_combine(seed, r.vars.consumer_global_data_sink.consumer_global_data_sink);
break;
case result_producer_global_data_source:
taste::hash_combine(seed, r.vars.result_producer_global_data_source.result_producer_global_data_source);
break;
// <<< END TO GENERATE
default:
assert(false && "Should not be here");
}
return seed;
}
};
} // namespace std
/*------------------------------------------------------------------------------------------------*/
#pragma once
#include <array>
#include <utility> // integer_sequence
#include <tuple>
namespace taste {
/*----------------------------------------------------------------------------*/
template <std::size_t X, std::size_t... Xs>
struct sum
{
static constexpr auto value = X + sum<Xs...>::value;
};
template <std::size_t X>
struct sum<X>
{
static constexpr auto value = X;
};
/*----------------------------------------------------------------------------*/
template <std::size_t Acc, std::size_t X, std::size_t... Xs>
struct accumulate
{
static constexpr auto recursion = accumulate<Acc + X, Xs...>::value;
static constexpr auto value = std::tuple_cat(std::make_tuple(Acc), recursion);
};
template <std::size_t Acc, std::size_t X>
struct accumulate<Acc, X>
{
static constexpr auto value = std::make_tuple(Acc);
};
/*----------------------------------------------------------------------------*/
template <typename Tuple, std::size_t... Indices>
constexpr
std::array<std::size_t, std::tuple_size<Tuple>::value>
tuple_to_array(const Tuple& t, std::index_sequence<Indices...>)
{
return {{std::get<Indices>(t)...}};
}
/*----------------------------------------------------------------------------*/
template <std::size_t... Ports>
struct ports_table
{
// For assertion purposes.
static constexpr auto nb_threads = sizeof...(Ports);
static constexpr std::size_t ports_for_thread[] = {Ports...};
static constexpr auto size = sum<Ports...>::value;
static constexpr auto tuple = accumulate<0, Ports...>::value;
static constexpr auto tuple_size = std::tuple_size<decltype(tuple)>::value;
using jump_table_type = decltype(tuple_to_array(tuple, std::make_index_sequence<tuple_size>()));
static constexpr jump_table_type jump_table
= tuple_to_array(tuple, std::make_index_sequence<tuple_size>());
};
// Definition of ports.
template<std::size_t... Ports>
constexpr std::size_t ports_table<Ports...>::ports_for_thread[];
// Definition of jump_table.
template<std::size_t... Ports>
typename ports_table<Ports...>::jump_table_type constexpr ports_table<Ports...>::jump_table;
/*----------------------------------------------------------------------------*/
} // namespace taste
#pragma once
#include <meta.hh>
#include <request.h>
#include <state.hh>
#include <trace.hh>
#include <configuration.hh>
// Parameter i in the template parameters list
// gives the number of ports for thread i.
// >>> TO GENERATE
using ports_type = taste::ports_table< PORT_TYPE_CONTENT >;
// <<< END TO GENERATE
using state_type = taste::state<__po_hi_request_t, ports_type>;
using trace_type = taste::trace<state_type>;
//using monitoring_type = taste::state<int, ports_type>;
extern "C" {
void
display_trace_temp(const trace_type* trace);
}
extern "C" {
void
display_state_temp(const state_type* state);
}
#pragma once
#include <algorithm> // copy, equal
#include <array>
#include <cassert>
#include <iosfwd>
#include <iterator>
#include <memory> // unique_ptr
#include "hash.hh"
#include "state_types.hh"
namespace taste {
/*----------------------------------------------------------------------------*/
template <typename Request, typename Ports>
class state
{
public:
static constexpr auto ports_size = Ports::size;
static_assert(Ports::size > 0, "A state's size must be greater than 0.");
using request_type = Request;
using array_type = std::array<request_type, ports_size>;
private:
struct data_type
{
step_type step_;
hyperperiod_type hyperperiod_;
thread_event_type thread_event_;
port_event_type port_event_;
// Should we share this amongst all states?
array_type ports_;
data_type() = default;
data_type(const data_type&) = default;
const request_type&
port_value(std::size_t thread_id, std::size_t port_id)
const noexcept
{
return ports_[Ports::jump_table[thread_id] + port_id];
}
request_type&
port_value(std::size_t thread_id, std::size_t port_id)
noexcept
{
return ports_[Ports::jump_table[thread_id] + port_id];
}
};
std::unique_ptr<data_type> ptr_;
public:
state()
: ptr_{std::make_unique<data_type>()}
{}
state(const state& other)
: ptr_{std::make_unique<data_type>(*other.ptr_)} // deep copy
{}
state&
operator=(const state& other)
{
if (this != &other)
{
ptr_ = std::make_unique<data_type>(*other.ptr_); // deep copy
}
return *this;
}
state(state&&) = default;
state& operator=(state&&) = default;
const request_type&
port_value(std::size_t thread_id, std::size_t port_id)
const noexcept
{
assert(thread_id < Ports::nb_threads && "Incorrect thread id");
assert(port_id < Ports::ports_for_thread[thread_id] && "Incorrect port id for this thread id");
return ptr_->port_value(thread_id, port_id);
}
request_type&
port_value(std::size_t thread_id, std::size_t port_id)
noexcept
{
assert(thread_id < Ports::nb_threads && "Incorrect thread id");
assert(port_id < Ports::ports_for_thread[thread_id] && "Incorrect port id for this thread id");
return ptr_->port_value(thread_id, port_id);
}
step_type
step()
const noexcept
{
return ptr_->step_;
}
step_type&
step()
noexcept
{
return ptr_->step_;
}
hyperperiod_type
hyperperiod()
const noexcept
{
return ptr_->hyperperiod_;
}
hyperperiod_type&
hyperperiod()
noexcept
{
return ptr_->hyperperiod_;
}
thread_event_type
thread_event()
const noexcept
{
return ptr_->thread_event_;
}
thread_event_type&
thread_event()
noexcept
{
return ptr_->thread_event_;
}
port_event_type
port_event()
const noexcept
{
return ptr_->port_event_;
}
port_event_type&
port_event()
noexcept
{
return ptr_->port_event_;
}
const char*
ports_data()
const noexcept
{
return reinterpret_cast<const char*>(ptr_->ports_.data());
}
const request_type&
ports(int index)
const noexcept
{
return ptr_->ports_[index];
}
static int
my_size()
{
return ports_size*sizeof(request_type) + sizeof(port_event_type) + sizeof(thread_event_type) + sizeof(hyperperiod_type) + sizeof(step_type);
}
friend
bool
operator==(const state& lhs, const state& rhs)
noexcept
{
// Highly dangerous : we directly comparing memory contents, thus relying on correct
// initialization (to 0) of the underlying data.
return lhs.step() == rhs.step() and lhs.hyperperiod() == rhs.hyperperiod()
and std::equal(lhs.ports_data(), lhs.ports_data() + ports_size, rhs.ports_data());
}
};
/*----------------------------------------------------------------------------*/
} // namespace taste
namespace std {
/*----------------------------------------------------------------------------*/
template <typename Request, typename Table>
struct hash <taste::state<Request, Table>>
{
using state_type = taste::state<Request, Table>;
std::size_t
operator()(const state_type& s)
const noexcept
{
std::size_t seed = 0;
taste::hash_combine(seed, s.step());
taste::hash_combine(seed, s.hyperperiod());
// Highly dangerous : we directly read memory contents, thus relying on correct
// initialization (to 0) of the underlying data.
taste::hash_combine(seed, s.ports_data(), s.ports_data() + state_type::ports_size);
return seed;
}
};
/*----------------------------------------------------------------------------*/
} // namespace std
#pragma once
typedef unsigned int step_type;
typedef unsigned int hyperperiod_type;
typedef unsigned int thread_event_type;
typedef unsigned int port_event_type;
#pragma once
#include <iosfwd>
#pragma GCC diagnostic push
#if defined(__GNUC__) && !defined(__clang__)
# pragma GCC diagnostic ignored "-Wunused-local-typedefs"