summaryrefslogtreecommitdiff
path: root/cesar/maximus/scheduler
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/maximus/scheduler')
-rw-r--r--cesar/maximus/scheduler/Config1
-rw-r--r--cesar/maximus/scheduler/Module1
-rw-r--r--cesar/maximus/scheduler/inc/Scheduler.h96
-rw-r--r--cesar/maximus/scheduler/inc/SchedulerEvent.h80
-rw-r--r--cesar/maximus/scheduler/scheduler.h19
-rw-r--r--cesar/maximus/scheduler/src/Scheduler.cpp299
-rw-r--r--cesar/maximus/scheduler/src/SchedulerEvent.cpp30
-rw-r--r--cesar/maximus/scheduler/utest/Makefile19
-rw-r--r--cesar/maximus/scheduler/utest/inc/EventExpected.h79
-rw-r--r--cesar/maximus/scheduler/utest/inc/TestScheduler.h60
-rw-r--r--cesar/maximus/scheduler/utest/inc/fake_Maximus.h36
-rw-r--r--cesar/maximus/scheduler/utest/src/EventExpected.cpp32
-rw-r--r--cesar/maximus/scheduler/utest/src/TestScheduler.cpp298
-rw-r--r--cesar/maximus/scheduler/utest/src/fake_ClockProcessor.cpp56
-rw-r--r--cesar/maximus/scheduler/utest/src/fake_PhyProcessor.cpp202
-rw-r--r--cesar/maximus/scheduler/utest/src/fake_SciServer.cpp70
16 files changed, 1378 insertions, 0 deletions
diff --git a/cesar/maximus/scheduler/Config b/cesar/maximus/scheduler/Config
new file mode 100644
index 0000000000..5c53022b6d
--- /dev/null
+++ b/cesar/maximus/scheduler/Config
@@ -0,0 +1 @@
+CONFIG_SCHEDULER_FASTER = n
diff --git a/cesar/maximus/scheduler/Module b/cesar/maximus/scheduler/Module
new file mode 100644
index 0000000000..2010eec5c7
--- /dev/null
+++ b/cesar/maximus/scheduler/Module
@@ -0,0 +1 @@
+SOURCES := Scheduler.cpp SchedulerEvent.cpp
diff --git a/cesar/maximus/scheduler/inc/Scheduler.h b/cesar/maximus/scheduler/inc/Scheduler.h
new file mode 100644
index 0000000000..a3424239ad
--- /dev/null
+++ b/cesar/maximus/scheduler/inc/Scheduler.h
@@ -0,0 +1,96 @@
+#ifndef maximus_scheduler_inc_scheduler_h
+#define maximus_scheduler_inc_scheduler_h
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/scheduler/inc/Scheduler.h
+ * \ingroup maximus_scheduler
+ *
+ */
+
+#include "maximus/common/types/networkclock_types.h"
+#include "maximus/common/types/sci_types.h"
+#include "maximus/processors/processors.h"
+#include "maximus/sci/sci_msg.h"
+#include <map>
+
+class SchedulerEvent;
+typedef std::multimap <Network_Clock_Tick, SchedulerEvent> calendar_t;
+
+class Scheduler
+{
+private:
+
+ PhyProcessor &phy_proc;
+ ClockProcessor &netclock_proc;
+
+ calendar_t calendar;
+ Network_Clock_Tick current_tick;
+ Network_Clock_Tick max_tick;
+ bool is_max_tick_actived;
+
+public:
+
+ Scheduler (PhyProcessor &a, ClockProcessor &b);
+
+ virtual ~Scheduler ();
+
+ void set_max_tick (Network_Clock_Tick val);
+
+ inline void reset_time ()
+ {
+ current_tick = 0;
+ }
+
+ inline Network_Clock_Tick get_current_tick () const
+ {
+ return current_tick;
+ }
+
+ inline const Network_Clock_Tick *get_time_pointer () const
+ {
+ return &current_tick;
+ }
+
+ void add_phy_event (
+ Network_Clock_Tick tick,
+ Sci_Msg_Station_Id sta_id,
+ Network_Clock_Id clock_id,
+ SciMsg *msg);
+
+ void add_event (
+ Network_Clock_Tick tick,
+ Sci_Msg_Station_Id sta_id,
+ Network_Clock_Id clock_id,
+ Network_Clock_Type evt_type);
+
+ void process_next_event ();
+
+ void remove_event (
+ Network_Clock_Tick tick,
+ Sci_Msg_Station_Id sta_id,
+ Network_Clock_Id clock_id);
+
+ void remove_sta_events (
+ Sci_Msg_Station_Id sta_id);
+
+private:
+
+ void add_generic_event (
+ Network_Clock_Tick tick,
+ Sci_Msg_Station_Id sta_id,
+ Network_Clock_Id clock_id,
+ Network_Clock_Type evt_type,
+ SciMsg *msg);
+
+ void remove_generic_event (SchedulerEvent &evt);
+
+ void display_calendar () const;
+};
+
+#endif // maximus_scheduler_inc_scheduler_h
diff --git a/cesar/maximus/scheduler/inc/SchedulerEvent.h b/cesar/maximus/scheduler/inc/SchedulerEvent.h
new file mode 100644
index 0000000000..99b7597175
--- /dev/null
+++ b/cesar/maximus/scheduler/inc/SchedulerEvent.h
@@ -0,0 +1,80 @@
+#ifndef maximus_scheduler_inc_schedulerevent_h
+#define maximus_scheduler_inc_schedulerevent_h
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/scheduler/inc/SchedulerEvent.h
+ * \ingroup maximus_scheduler
+ *
+ */
+
+#include "maximus/common/types/sci_types.h"
+#include "maximus/common/types/networkclock_types.h"
+#include "maximus/sci/sci_msg.h"
+
+
+class SchedulerEvent
+{
+private:
+ Sci_Msg_Station_Id sta_id;
+ Network_Clock_Id id;
+ Network_Clock_Type type;
+ SciMsg *msg;
+
+public:
+
+ SchedulerEvent (
+ Sci_Msg_Station_Id arg1,
+ Network_Clock_Id arg2,
+ Network_Clock_Type arg3,
+ SciMsg *arg4);
+
+ virtual ~SchedulerEvent ();
+
+ inline void set_sta_id (Sci_Msg_Station_Id val)
+ {
+ sta_id = val;
+ }
+
+ inline Sci_Msg_Station_Id get_sta_id () const
+ {
+ return sta_id;
+ }
+
+ inline void set_clock_id (Network_Clock_Id val)
+ {
+ id = val;
+ }
+
+ inline Network_Clock_Id get_clock_id () const
+ {
+ return id;
+ }
+
+ inline void set_clock_type (Network_Clock_Type val)
+ {
+ type = val;
+ }
+
+ inline Network_Clock_Type get_clock_type () const
+ {
+ return type;
+ }
+
+ inline void set_sci_msg (SciMsg *val)
+ {
+ msg = val;
+ }
+
+ inline SciMsg *get_sci_msg () const
+ {
+ return msg;
+ }
+};
+
+#endif // maximus_scheduler_inc_schedulerevent_h
diff --git a/cesar/maximus/scheduler/scheduler.h b/cesar/maximus/scheduler/scheduler.h
new file mode 100644
index 0000000000..aa949dd4ae
--- /dev/null
+++ b/cesar/maximus/scheduler/scheduler.h
@@ -0,0 +1,19 @@
+#ifndef maximus_scheduler_scheduler_h
+#define maximus_scheduler_scheduler_h
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/scheduler/scheduler.h
+ * \ingroup maximus_scheduler
+ *
+ */
+
+/* Forward declaration. */
+class Scheduler;
+
+#endif /* maximus_scheduler_scheduler_h */
diff --git a/cesar/maximus/scheduler/src/Scheduler.cpp b/cesar/maximus/scheduler/src/Scheduler.cpp
new file mode 100644
index 0000000000..4a3e47ed90
--- /dev/null
+++ b/cesar/maximus/scheduler/src/Scheduler.cpp
@@ -0,0 +1,299 @@
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/scheduler/src/Scheduler.cpp
+ * \ingroup maximus_scheduler
+ *
+ */
+#include "maximus/scheduler/inc/Scheduler.h"
+#include "maximus/scheduler/inc/SchedulerEvent.h"
+#include "maximus/processors/inc/PhyProcessor.h"
+#include "maximus/processors/inc/ClockProcessor.h"
+#include "maximus/utils/inc/Error.h"
+#include "maximus/utils/inc/Logger.h"
+#include "config/scheduler.h"
+#include <list>
+#include <assert.h>
+
+Scheduler::Scheduler (PhyProcessor &a, ClockProcessor &b):
+ phy_proc (a),
+ netclock_proc (b),
+ is_max_tick_actived (false)
+{
+ logFunction ();
+
+ current_tick = 0;
+}
+
+Scheduler::~Scheduler ()
+{
+ logFunction ();
+
+ calendar_t::iterator it;
+
+ while (!calendar.empty ())
+ {
+ it = calendar.begin ();
+ remove_generic_event (it->second);
+ calendar.erase (it);
+ }
+}
+
+inline void
+Scheduler::remove_generic_event (SchedulerEvent &evt)
+{
+ /* Note :
+ * Polymorphism possible on 'scheduler_drop_event ()'.
+ * */
+ if (evt.get_clock_type () == NETWORK_CLOCK_TYPE_PHY)
+ phy_proc.scheduler_drop_event (evt.get_sci_msg ());
+}
+
+inline void
+Scheduler::add_generic_event (
+ Network_Clock_Tick tick,
+ Sci_Msg_Station_Id sta_id,
+ Network_Clock_Id clock_id,
+ Network_Clock_Type evt_type,
+ SciMsg *msg)
+{
+ logFunction ();
+
+ assert (current_tick <= tick);
+
+ bool is_event_already_exist = false;
+ static calendar_t::iterator it;
+ static std::pair <calendar_t::iterator, calendar_t::iterator> range;
+ range = calendar.equal_range (tick);
+
+ for (it = range.first ; it != range.second; ++it)
+ {
+ if ((it->second.get_sta_id () == sta_id)
+ && (it->second.get_clock_id () == clock_id))
+ {
+ is_event_already_exist = true;
+ break;
+ }
+ }
+
+ assert (!is_event_already_exist);
+
+ calendar.insert (
+#if CONFIG_SCHEDULER_FASTER
+ range.first,
+#endif
+ std::pair <Network_Clock_Tick, SchedulerEvent>
+ (tick, SchedulerEvent (sta_id, clock_id,
+ evt_type, msg)));
+}
+
+void
+Scheduler::set_max_tick (Network_Clock_Tick val)
+{
+ logFunction ();
+
+ if (val != 0)
+ {
+ is_max_tick_actived = true;
+ maximus_log (LOG_INFO, "max_tick is " << val);
+ assert (val >= current_tick);
+ }
+ else
+ {
+ is_max_tick_actived = false;;
+ maximus_log (LOG_INFO, "max_tick is unlimited");
+ }
+
+ max_tick = val;
+}
+
+void
+Scheduler::add_phy_event (
+ Network_Clock_Tick tick,
+ Sci_Msg_Station_Id sta_id,
+ Network_Clock_Id clock_id,
+ SciMsg *msg)
+{
+ logFunction ();
+
+ if (msg)
+ add_generic_event (
+ tick, sta_id, clock_id, NETWORK_CLOCK_TYPE_PHY, msg);
+ else
+ maximus_log (LOG_ERROR, "pointer SciMsg is null");
+}
+
+void
+Scheduler::add_event (
+ Network_Clock_Tick tick,
+ Sci_Msg_Station_Id sta_id,
+ Network_Clock_Id clock_id,
+ Network_Clock_Type evt_type)
+{
+ logFunction ();
+
+ if (evt_type != NETWORK_CLOCK_TYPE_PHY)
+ {
+ add_generic_event (
+ tick, sta_id, clock_id, evt_type, NULL);
+ }
+ else
+ maximus_log (LOG_ERROR, "add_event refuse PHY event");
+}
+
+void
+Scheduler::remove_event (
+ Network_Clock_Tick tick,
+ Sci_Msg_Station_Id sta_id,
+ Network_Clock_Id clock_id)
+{
+ logFunction ();
+
+ static calendar_t::iterator it;
+ static std::pair <calendar_t::iterator, calendar_t::iterator> range;
+ range = calendar.equal_range (tick);
+
+ for (it = range.first ; it != range.second; ++it)
+ {
+ if ((it->second.get_sta_id () == sta_id)
+ && (it->second.get_clock_id () == clock_id))
+ {
+ remove_generic_event (it->second);
+ calendar.erase (it);
+ maximus_log (LOG_INFO, "event erased");
+ break;
+ }
+ }
+}
+
+void
+Scheduler::remove_sta_events (
+ Sci_Msg_Station_Id sta_id)
+{
+ logFunction ();
+
+ static calendar_t::iterator it;
+ static std::list <calendar_t::iterator> todel;
+
+ for (it = calendar.begin (); it != calendar.end (); ++it)
+ {
+ if (it->second.get_sta_id () == sta_id)
+ {
+ remove_generic_event (it->second);
+ todel.push_back (it);
+ }
+ }
+
+ while (!todel.empty ())
+ {
+ it = todel.back ();
+ calendar.erase (it);
+ todel.pop_back ();
+ }
+}
+
+void
+Scheduler::process_next_event ()
+{
+ logFunction ();
+
+ bool is_calendar_empty = calendar.empty ();
+ bool is_max_tick_reach = false;
+ static Sci_Msg_Station_Id clock_staid;
+ static Network_Clock_Id clock_id;
+ static Network_Clock_Type clock_type;
+ static SciMsg *clock_msg;
+ static calendar_t::iterator next;
+
+ if (is_calendar_empty)
+ {
+ /* The user have requested to schedule, but there is nothing
+ * in the calendar. That could be the case, when no station exist.
+ * It's quite stupid, but it's like that. */
+ if (is_max_tick_actived && max_tick > current_tick)
+ {
+ is_max_tick_reach = true;
+ current_tick = max_tick;
+ }
+ }
+ else
+ {
+ next = calendar.begin ();
+ assert (current_tick <= next->first);
+
+ if (is_max_tick_actived && max_tick <= next->first)
+ {
+ is_max_tick_reach = true;
+ current_tick = max_tick;
+ }
+ else
+ current_tick = next->first;
+ }
+
+#if CONFIG_LOG
+ logger.updateTickValue (current_tick);
+ display_calendar ();
+#endif
+
+ if (is_max_tick_reach)
+ {
+ maximus_log (LOG_INFO, "Max tick reached");
+ }
+ else if (!is_calendar_empty)
+ {
+ clock_staid = next->second.get_sta_id ();
+ clock_id = next->second.get_clock_id ();
+ clock_type = next->second.get_clock_type ();
+ clock_msg = next->second.get_sci_msg ();
+ calendar.erase (next);
+
+ maximus_log (
+ LOG_INFO,
+ "Processing event at tick " << current_tick);
+
+ /* Note :
+ * Polymorphism possible on 'scheduler_send_event ()'.
+ * */
+ switch (clock_type)
+ {
+ case NETWORK_CLOCK_TYPE_STATION:
+ netclock_proc.scheduler_send_event (
+ clock_staid, clock_id, clock_msg);
+ break;
+
+ case NETWORK_CLOCK_TYPE_PHY:
+ phy_proc.scheduler_send_event (
+ clock_staid, clock_id, clock_msg);
+ break;
+
+ default:
+ /* Type not supported. */
+ assert (false);
+ break;
+ }
+ }
+}
+
+inline void
+Scheduler::display_calendar () const
+{
+#if CONFIG_LOG
+ maximus_log (LOG_INFO, "Calendar content :");
+
+ calendar_t::const_iterator it;
+ for (it = calendar.begin (); it != calendar.end (); ++it)
+ {
+ maximus_log (LOG_INFO, " ["
+ << std::hex << it->first << "] = {"
+ << "staid (" << std::hex << it->second.get_sta_id () << "), "
+ << "id (" << std::hex << it->second.get_clock_id () << "), "
+ << "type (" << std::hex << it->second.get_clock_type () << "), "
+ << "scimsg* (" << std::hex << it->second.get_sci_msg () << ")},");
+ }
+#endif
+}
diff --git a/cesar/maximus/scheduler/src/SchedulerEvent.cpp b/cesar/maximus/scheduler/src/SchedulerEvent.cpp
new file mode 100644
index 0000000000..35ddbf1a49
--- /dev/null
+++ b/cesar/maximus/scheduler/src/SchedulerEvent.cpp
@@ -0,0 +1,30 @@
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/scheduler/src/SchedulerEvent.cpp
+ * \ingroup maximus_scheduler
+ *
+ */
+
+#include "maximus/scheduler/inc/SchedulerEvent.h"
+
+SchedulerEvent::SchedulerEvent (
+ Sci_Msg_Station_Id arg1,
+ Network_Clock_Id arg2,
+ Network_Clock_Type arg3,
+ SciMsg *arg4):
+ sta_id (arg1),
+ id (arg2),
+ type (arg3),
+ msg (arg4)
+{
+}
+
+SchedulerEvent::~SchedulerEvent ()
+{
+}
diff --git a/cesar/maximus/scheduler/utest/Makefile b/cesar/maximus/scheduler/utest/Makefile
new file mode 100644
index 0000000000..4d5db916fa
--- /dev/null
+++ b/cesar/maximus/scheduler/utest/Makefile
@@ -0,0 +1,19 @@
+BASE = ../../..
+
+HOST_PROGRAMS = scheduler_test
+
+scheduler_test_SOURCES = TestScheduler.cpp EventExpected.cpp
+scheduler_test_MODULES = lib maximus/lib/test maximus/utils maximus/scheduler \
+ maximus/processors maximus/sci
+
+# Modules stubbed for this unit test
+scheduler_test_SOURCES += fake_PhyProcessor.cpp fake_ClockProcessor.cpp \
+ fake_SciServer.cpp
+
+maximus_processors_MODULE_SOURCES = Processor.cpp
+maximus_sci_MODULE_SOURCES = ClockSciMsg.cpp PhySciMsg.cpp SciMsg.cpp
+
+EXTRA_HOST_CFLAGS := $(shell cppunit-config --cflags)
+EXTRA_HOST_LDLIBS := $(shell cppunit-config --libs)
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/maximus/scheduler/utest/inc/EventExpected.h b/cesar/maximus/scheduler/utest/inc/EventExpected.h
new file mode 100644
index 0000000000..cc91aa0657
--- /dev/null
+++ b/cesar/maximus/scheduler/utest/inc/EventExpected.h
@@ -0,0 +1,79 @@
+#ifndef maximus_scheduler_utest_inc_eventexpected_h
+#define maximus_scheduler_utest_inc_eventexpected_h
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/scheduler/utest/inc/EventExpected.h
+ * \ingroup maximus_scheduler_utest
+ *
+ */
+#include "maximus/common/types/networkclock_types.h"
+#include "maximus/common/types/sci_types.h"
+#include "maximus/sci/sci_msg.h"
+#include <list>
+
+class EventExpected
+{
+private:
+ Network_Clock_Tick tick;
+ Sci_Msg_Station_Id sta_id;
+ Network_Clock_Id clock_id;
+ Network_Clock_Type evt_type;
+ SciMsg *msg;
+
+public:
+ EventExpected (
+ Network_Clock_Tick a,
+ Sci_Msg_Station_Id b,
+ Network_Clock_Id c,
+ Network_Clock_Type d,
+ SciMsg *e);
+
+ ~EventExpected ();
+
+ inline bool operator == (EventExpected &comp) const
+ {
+ if (tick == comp.get_tick ()
+ && sta_id == comp.get_sta_id ()
+ && clock_id == comp.get_clock_id ()
+ && evt_type == comp.get_evt_type ()
+ && msg == comp.get_msg ())
+ return true;
+ else
+ return false;
+ }
+
+ inline Network_Clock_Tick get_tick () const
+ {
+ return tick;
+ }
+
+ inline Sci_Msg_Station_Id get_sta_id () const
+ {
+ return sta_id;
+ }
+
+ inline Network_Clock_Id get_clock_id () const
+ {
+ return clock_id;
+ }
+
+ inline Network_Clock_Type get_evt_type () const
+ {
+ return evt_type;
+ }
+
+ inline SciMsg *get_msg () const
+ {
+ return msg;
+ };
+};
+
+typedef std::list <EventExpected> list_event_t;
+
+#endif /* maximus_scheduler_utest_inc_eventexpected_h */
diff --git a/cesar/maximus/scheduler/utest/inc/TestScheduler.h b/cesar/maximus/scheduler/utest/inc/TestScheduler.h
new file mode 100644
index 0000000000..e29a0f6e5f
--- /dev/null
+++ b/cesar/maximus/scheduler/utest/inc/TestScheduler.h
@@ -0,0 +1,60 @@
+#ifndef maximus_scheduler_utest_inc_testscheduler_h
+#define maximus_scheduler_utest_inc_testscheduler_h
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/scheduler/utest/inc/TestScheduler.h
+ * \ingroup maximus_scheduler_utest
+ *
+ */
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "maximus/scheduler/scheduler.h"
+#include "maximus/interface/station/station.h"
+#include "maximus/processors/processors.h"
+#include "maximus/sci/sci_msg.h"
+#include "maximus/interface/maximus.h"
+#include "inc/EventExpected.h"
+
+class TestScheduler : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE (TestScheduler);
+ CPPUNIT_TEST (test_add_events_ok);
+ CPPUNIT_TEST (test_max_tick);
+ CPPUNIT_TEST (test_remove_event);
+ CPPUNIT_TEST (test_remove_event_past);
+ CPPUNIT_TEST (test_remove_sta_events);
+ CPPUNIT_TEST_SUITE_END ();
+
+public:
+
+ void setUp ();
+ void tearDown ();
+
+private:
+
+ stations_list_t sta_list;
+ SciServer *fake_server;
+ Maximus *fake_maximus;
+ PhyProcessor *fake_phy_proc;
+ ClockProcessor *fake_clock_proc;
+ Scheduler *sched;
+
+ void init_procs (Scheduler *p);
+ void add_wanted_list (list_event_t &list);
+ void check_schedule (list_event_t &list);
+
+ void test_add_events_ok ();
+ void test_max_tick ();
+ void test_remove_event ();
+ void test_remove_event_past ();
+ void test_remove_sta_events ();
+};
+
+#endif /* maximus_scheduler_utest_inc_testscheduler_h */
diff --git a/cesar/maximus/scheduler/utest/inc/fake_Maximus.h b/cesar/maximus/scheduler/utest/inc/fake_Maximus.h
new file mode 100644
index 0000000000..b63ab5ef41
--- /dev/null
+++ b/cesar/maximus/scheduler/utest/inc/fake_Maximus.h
@@ -0,0 +1,36 @@
+#ifndef maximus_scheduler_utest_inc_fake_maximus_h
+#define maximus_scheduler_utest_inc_fake_maximus_h
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/scheduler/utest/inc/fake_scheduler.h
+ * \ingroup maximus_scheduler_utest
+ *
+ */
+#include "maximus/interface/inc/MaximusCallBack.h"
+
+class Maximus : public MaximusCallBack
+{
+public:
+ Maximus () {}
+
+ virtual ~Maximus () {}
+
+ void recv_ether_cb (
+ char *pdata,
+ int data_length,
+ Ethernet_Type type,
+ Sci_Msg_Station_Id sta_id) {}
+
+ void recv_phy_mpdu_cb (
+ unsigned long fc_10,
+ unsigned long *fc_av,
+ PhySciMsg &msg) {}
+};
+
+#endif /* maximus_scheduler_utest_inc_fake_maximus_h */
diff --git a/cesar/maximus/scheduler/utest/src/EventExpected.cpp b/cesar/maximus/scheduler/utest/src/EventExpected.cpp
new file mode 100644
index 0000000000..3d8d492071
--- /dev/null
+++ b/cesar/maximus/scheduler/utest/src/EventExpected.cpp
@@ -0,0 +1,32 @@
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/scheduler/utest/src/EventExpected.cpp
+ * \ingroup maximus_scheduler_utest
+ *
+ */
+
+#include "inc/EventExpected.h"
+
+EventExpected::EventExpected (
+ Network_Clock_Tick a,
+ Sci_Msg_Station_Id b,
+ Network_Clock_Id c,
+ Network_Clock_Type d,
+ SciMsg *e):
+ tick (a),
+ sta_id (b),
+ clock_id (c),
+ evt_type (d),
+ msg (e)
+{
+}
+
+EventExpected::~EventExpected ()
+{
+}
diff --git a/cesar/maximus/scheduler/utest/src/TestScheduler.cpp b/cesar/maximus/scheduler/utest/src/TestScheduler.cpp
new file mode 100644
index 0000000000..8bfbea5ff8
--- /dev/null
+++ b/cesar/maximus/scheduler/utest/src/TestScheduler.cpp
@@ -0,0 +1,298 @@
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/scheduler/utest/src/TestScheduler.cpp
+ * \ingroup maximus_scheduler_utest
+ *
+ */
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include "maximus/scheduler/inc/Scheduler.h"
+#include "maximus/sci/inc/SciServer.h"
+#include "maximus/processors/inc/PhyProcessor.h"
+#include "maximus/processors/inc/ClockProcessor.h"
+#include "maximus/utils/inc/Error.h"
+#include "inc/TestScheduler.h"
+#include "inc/fake_Maximus.h"
+#include "inc/EventExpected.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION (TestScheduler);
+list_event_t received;
+
+void
+TestScheduler::setUp ()
+{
+ fake_maximus = new Maximus ();
+ fake_server = new SciServer (sta_list);
+ fake_phy_proc = new PhyProcessor (*fake_server,
+ *fake_maximus);
+ fake_clock_proc = new ClockProcessor (*fake_server,
+ *fake_maximus);
+ sched = NULL;
+}
+
+void
+TestScheduler::tearDown ()
+{
+ delete fake_clock_proc;
+ delete fake_phy_proc;
+ delete fake_server;
+}
+
+inline void
+TestScheduler::init_procs (Scheduler *p)
+{
+ received.clear ();
+ fake_phy_proc->register_scheduler (sched);
+ fake_clock_proc->register_scheduler (sched);
+}
+
+inline void
+TestScheduler::add_wanted_list (list_event_t &list)
+{
+ list_event_t::iterator it;
+
+ for (it = list.begin (); it != list.end (); ++it)
+ {
+ if (it->get_evt_type () == NETWORK_CLOCK_TYPE_PHY)
+ sched->add_phy_event (
+ it->get_tick (),
+ it->get_sta_id (),
+ it->get_clock_id (),
+ it->get_msg ());
+ else
+ sched->add_event (
+ it->get_tick (),
+ it->get_sta_id (),
+ it->get_clock_id (),
+ it->get_evt_type ());
+ }
+}
+
+inline void
+TestScheduler::check_schedule (list_event_t &list)
+{
+ list_event_t::iterator it;
+ list_event_t::iterator it_rcv;
+ bool is_found;
+ uint id;
+ uint nb_event_expected;
+ Network_Clock_Tick prev_time;
+
+ prev_time = sched->get_current_tick ();
+ nb_event_expected = list.size ();
+
+ for (uint i = list.size (); i != 0; --i)
+ {
+ sched->process_next_event ();
+ CPPUNIT_ASSERT (prev_time <= sched->get_current_tick ());
+ }
+
+ CPPUNIT_ASSERT (nb_event_expected == received.size ());
+
+ id = 0;
+ for (it = list.begin (); it != list.end (); ++it)
+ {
+ ++id;
+ is_found = false;
+
+ for (it_rcv = received.begin ();
+ it_rcv != received.end ();
+ ++it_rcv)
+ {
+ if (*it == *it_rcv)
+ {
+ is_found = true;
+ break;
+ }
+ }
+
+ if (is_found)
+ received.erase (it_rcv);
+ else
+ {
+ std::ostringstream oss;
+ oss << "Event requested not received (" << id << ")";
+ CPPUNIT_FAIL (oss.str ());
+ }
+ }
+
+ sched->process_next_event ();
+ CPPUNIT_ASSERT (0 == received.size ());
+}
+
+void
+TestScheduler::test_add_events_ok ()
+{
+ std::cout << __func__ << std::endl;
+ sched = new Scheduler (*fake_phy_proc, *fake_clock_proc);
+ list_event_t wanted;
+ init_procs (sched);
+
+
+ /* With this list of events, we will test to received:
+ * - events sorted by tick,
+ * - on same tick, there is not sort mandatory,
+ * - all events must be received as there key are different.
+ */
+ wanted.push_back (
+ EventExpected (
+ 0, 25, 30, NETWORK_CLOCK_TYPE_STATION, NULL));
+ wanted.push_back (
+ EventExpected (
+ 2, 25, 30, NETWORK_CLOCK_TYPE_STATION, NULL));
+ wanted.push_back (
+ EventExpected (
+ 5, 25, 30, NETWORK_CLOCK_TYPE_STATION, NULL));
+ wanted.push_back (
+ EventExpected (
+ 5, 25, 31, NETWORK_CLOCK_TYPE_PHY, (SciMsg *)0xDEADBEEF));
+ wanted.push_back (
+ EventExpected (
+ 5, 29, 31, NETWORK_CLOCK_TYPE_STATION, NULL));
+ wanted.push_back (
+ EventExpected (
+ 6, 29, 31, NETWORK_CLOCK_TYPE_STATION, NULL));
+ wanted.push_back (
+ EventExpected (
+ 30, 30, 31, NETWORK_CLOCK_TYPE_PHY, (SciMsg *)0xDEADBEEF));
+ wanted.push_back (
+ EventExpected (
+ 10, 40, 31, NETWORK_CLOCK_TYPE_PHY, (SciMsg *)0xDEADBEEF));
+
+ add_wanted_list (wanted);
+
+ CPPUNIT_ASSERT (sched->get_current_tick () == 0);
+ check_schedule (wanted);
+
+ delete sched;
+}
+
+void
+TestScheduler::test_max_tick ()
+{
+ std::cout << __func__ << std::endl;
+ sched = new Scheduler (*fake_phy_proc, *fake_clock_proc);
+ list_event_t wanted;
+ init_procs (sched);
+
+ sched->set_max_tick (200);
+
+ wanted.push_back (
+ EventExpected (
+ 600, 0, 0, NETWORK_CLOCK_TYPE_STATION, NULL));
+ add_wanted_list (wanted);
+ sched->process_next_event ();
+ CPPUNIT_ASSERT (200 == sched->get_current_tick ());
+ CPPUNIT_ASSERT (received.empty ());
+
+ sched->set_max_tick (0);
+ sched->process_next_event ();
+ CPPUNIT_ASSERT (600 == sched->get_current_tick ());
+ CPPUNIT_ASSERT (!received.empty ());
+ CPPUNIT_ASSERT (*received.begin () == *wanted.begin ());
+
+ delete sched;
+}
+
+void
+TestScheduler::test_remove_event ()
+{
+ std::cout << __func__ << std::endl;
+ list_event_t::iterator it;
+ sched = new Scheduler (*fake_phy_proc, *fake_clock_proc);
+ init_procs (sched);
+ list_event_t unwanted, wanted;
+
+ unwanted.push_back (
+ EventExpected (
+ 13, 14, 15, NETWORK_CLOCK_TYPE_STATION, NULL));
+ wanted.push_back (
+ EventExpected (
+ 35, 15, 31, NETWORK_CLOCK_TYPE_PHY, (SciMsg *)0xBEEF));
+ unwanted.push_back (
+ EventExpected (
+ 35, 26, 40, NETWORK_CLOCK_TYPE_STATION, NULL));
+ wanted.push_back (
+ EventExpected (
+ 45, 26, 40, NETWORK_CLOCK_TYPE_STATION, NULL));
+
+ add_wanted_list (wanted);
+ add_wanted_list (unwanted);
+
+ for (it = unwanted.begin (); it != unwanted.end (); ++it)
+ {
+ sched->remove_event (
+ it->get_tick (),
+ it->get_sta_id (),
+ it->get_clock_id ());
+ }
+ check_schedule (wanted);
+ delete sched;
+}
+
+void
+TestScheduler::test_remove_event_past ()
+{
+ std::cout << __func__ << std::endl;
+ list_event_t::iterator it;
+ sched = new Scheduler (*fake_phy_proc, *fake_clock_proc);
+ init_procs (sched);
+ list_event_t wanted_1, wanted_2;
+
+ wanted_1.push_back (
+ EventExpected (
+ 100, 14, 15, NETWORK_CLOCK_TYPE_STATION, NULL));
+ wanted_2.push_back (
+ EventExpected (
+ 200, 15, 31, NETWORK_CLOCK_TYPE_PHY, (SciMsg *)0xBEEF));
+
+ add_wanted_list (wanted_1);
+ add_wanted_list (wanted_2);
+
+ sched->set_max_tick (150);
+ check_schedule (wanted_1);
+
+ /* should we have an error on this request ? */
+ sched->remove_event (40, 11, 12);
+
+ sched->set_max_tick (0);
+ check_schedule (wanted_2);
+ delete sched;
+}
+
+void
+TestScheduler::test_remove_sta_events ()
+{
+ std::cout << __func__ << std::endl;
+ list_event_t::iterator it;
+ sched = new Scheduler (*fake_phy_proc, *fake_clock_proc);
+ init_procs (sched);
+ Sci_Msg_Station_Id staid = 18;
+
+ list_event_t unwanted, wanted;
+
+ unwanted.push_back (
+ EventExpected (
+ 13, staid, 15, NETWORK_CLOCK_TYPE_STATION, NULL));
+ wanted.push_back (
+ EventExpected (
+ 35, 15, 31, NETWORK_CLOCK_TYPE_PHY, (SciMsg *)0xBEEF));
+ unwanted.push_back (
+ EventExpected (
+ 35, staid, 40, NETWORK_CLOCK_TYPE_STATION, NULL));
+ wanted.push_back (
+ EventExpected (
+ 45, 26, 40, NETWORK_CLOCK_TYPE_STATION, NULL));
+
+ add_wanted_list (wanted);
+ add_wanted_list (unwanted);
+
+ sched->remove_sta_events (staid);
+ check_schedule (wanted);
+ delete sched;
+}
diff --git a/cesar/maximus/scheduler/utest/src/fake_ClockProcessor.cpp b/cesar/maximus/scheduler/utest/src/fake_ClockProcessor.cpp
new file mode 100644
index 0000000000..894196d0f8
--- /dev/null
+++ b/cesar/maximus/scheduler/utest/src/fake_ClockProcessor.cpp
@@ -0,0 +1,56 @@
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/scheduler/utest/src/fake_clock_proc.cpp
+ * \ingroup maximus_scheduler_utest
+ *
+ */
+#include "maximus/processors/inc/ClockProcessor.h"
+#include "maximus/sci/sci_msg.h"
+#include "maximus/scheduler/inc/Scheduler.h"
+#include "inc/EventExpected.h"
+
+extern list_event_t received;
+
+ClockProcessor::ClockProcessor (SciServer &ref1,
+ MaximusCallBack &ref2):
+ Processor (ref1, ref2, SCI_MSG_TYPE_NETWORK_CLOCK),
+ msg_to_send (0)
+
+{
+}
+
+ClockProcessor::~ClockProcessor ( )
+{
+}
+
+SciMsg *
+ClockProcessor::create_sci_msg (
+ struct Sci_Msg_Header &header,
+ unsigned char *buffer)
+{
+ return NULL;
+}
+
+void
+ClockProcessor::dispatchMsgProc (SciMsg *msg_rx)
+{
+}
+
+void
+ClockProcessor::scheduler_send_event (
+ Sci_Msg_Station_Id clock_staid,
+ Network_Clock_Id clock_id,
+ SciMsg *msg)
+{
+ received.push_back (EventExpected (
+ p_scheduler->get_current_tick (),
+ clock_staid, clock_id,
+ NETWORK_CLOCK_TYPE_STATION,
+ msg));
+}
diff --git a/cesar/maximus/scheduler/utest/src/fake_PhyProcessor.cpp b/cesar/maximus/scheduler/utest/src/fake_PhyProcessor.cpp
new file mode 100644
index 0000000000..9ee39e455d
--- /dev/null
+++ b/cesar/maximus/scheduler/utest/src/fake_PhyProcessor.cpp
@@ -0,0 +1,202 @@
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/scheduler/utest/src/fake_phy_proc.cpp
+ * \ingroup maximus_scheduler_utest
+ *
+ */
+#include "maximus/processors/inc/PhyProcessor.h"
+#include "maximus/sci/sci_msg.h"
+#include "maximus/scheduler/inc/Scheduler.h"
+#include "inc/EventExpected.h"
+
+extern list_event_t received;
+
+PhyProcessor::PhyProcessor (SciServer &ref1,
+ MaximusCallBack &ref2):
+ Processor (ref1, ref2, SCI_MSG_TYPE_PHY),
+ PhySciMsg_ZeroCross (0),
+ PhySciMsg_WrongPre (0)
+{
+}
+
+PhyProcessor::~PhyProcessor ()
+{
+}
+
+SciMsg *
+PhyProcessor::create_sci_msg (
+ struct Sci_Msg_Header &header,
+ unsigned char *buffer)
+{
+ return NULL;
+}
+
+void
+PhyProcessor::scheduler_drop_event (SciMsg *msg)
+{
+}
+
+void
+PhyProcessor::mpdu_schedule (
+ MsgMpdu *msg,
+ PhySciMsg *preamble,
+ PhySciMsg *fc,
+ PhySciMsg *payload)
+{
+}
+
+void
+PhyProcessor::dispatchMsgProc (SciMsg *msg_rx)
+{
+}
+
+void
+PhyProcessor::scheduler_send_event (
+ Sci_Msg_Station_Id clock_staid,
+ Network_Clock_Id clock_id,
+ SciMsg *msg)
+{
+ received.push_back (EventExpected (
+ p_scheduler->get_current_tick (),
+ clock_staid, clock_id,
+ NETWORK_CLOCK_TYPE_PHY,
+ msg));
+}
+
+void
+PhyProcessor::receiveInvalid (PhySciMsg &sci)
+{
+}
+
+void
+PhyProcessor::receivePre (PhySciMsg &sci)
+{
+}
+
+void
+PhyProcessor::receiveFc (PhySciMsg &sci)
+{
+}
+
+void
+PhyProcessor::receivePrs (PhySciMsg &sci)
+{
+}
+
+void
+PhyProcessor::receive_payload (PhySciMsg &sci)
+{
+}
+
+void
+PhyProcessor::receiveTonemask (PhySciMsg &sci)
+{
+}
+
+void
+PhyProcessor::receiveTonemap (PhySciMsg & sci)
+{
+}
+
+void
+PhyProcessor::receive_rx (PhySciMsg &sci)
+{
+}
+
+void
+PhyProcessor::activateFalseAlarm (
+ const Network_Clock_Tick avg_interval,
+ const float deviation)
+{
+}
+
+void
+PhyProcessor::deactivateFalseAlarm ()
+{
+}
+
+void
+PhyProcessor::set_zerocross_freq (const float frequency)
+{
+}
+
+bool
+PhyProcessor::setChannel (
+ ChannelComputer * p_channel)
+{
+ return false;
+}
+
+ChannelComputer *
+PhyProcessor::getChannel () const
+{
+ return NULL;
+}
+
+bool
+PhyProcessor::setIsChannelEnabled (
+ const bool is_channel_enabled)
+{
+ return false;
+}
+
+bool
+PhyProcessor::isChannelEnabled () const
+{
+ return false;
+}
+
+unsigned int
+PhyProcessor::getNbOfCarriers () const
+{
+ return 0;
+}
+
+bool
+PhyProcessor::setNbOfCarriers (
+ const unsigned int nb_of_carriers)
+{
+ return false;
+}
+
+const uint8_t *
+PhyProcessor::getTonemask () const
+{
+ return NULL;
+}
+
+void
+PhyProcessor::setTonemask (
+ const unsigned int length,
+ const uint8_t * p_tonemask)
+{
+}
+
+void
+PhyProcessor::schedule_next_zero_cross ()
+{
+}
+
+inline void
+PhyProcessor::send_mpdu_and_noise (PhySciMsg &sci_payload)
+{
+}
+
+Network_Clock_Tick
+PhyProcessor::roll_die_next_interval () const
+{
+ return 0;
+}
+
+bool
+PhyProcessor::scheduleNextWrongPre (
+ const Network_Clock_Tick next_interval)
+{
+ return false;
+}
diff --git a/cesar/maximus/scheduler/utest/src/fake_SciServer.cpp b/cesar/maximus/scheduler/utest/src/fake_SciServer.cpp
new file mode 100644
index 0000000000..d557856180
--- /dev/null
+++ b/cesar/maximus/scheduler/utest/src/fake_SciServer.cpp
@@ -0,0 +1,70 @@
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/scheduler/utest/src/fake_server.cpp
+ * \ingroup maximus_scheduler_utest
+ *
+ */
+#include "maximus/sci/inc/SciServer.h"
+
+SciServer::SciServer (stations_list_t &ref1):
+ sta_list (ref1)
+{
+}
+
+SciServer::~SciServer ()
+{
+}
+
+void
+SciServer::process () const
+{
+}
+
+void
+SciServer::log () const
+{
+}
+
+inline void
+SciServer::send_SciMsg_to_Station (
+ const SciMsg &sci_msg,
+ Station &dsta) const
+{
+}
+
+void
+SciServer::sendSciMsg (
+ const SciMsg &sci_msg_to_send, const Sci_Msg_Station_Id station_id) const
+{
+}
+
+bool
+SciServer::sendSciMsgToAllActiveStations (
+ SciMsg &sci_msg_to_send) const
+{
+ return false;
+}
+
+void
+SciServer::register_processor (
+ const Sci_Msg_Type sci_msg_type,
+ Processor *client)
+{
+}
+
+void
+SciServer::unregister_processor (
+ const Sci_Msg_Type sci_msg_type)
+{
+}
+
+void
+SciServer::check_if_server_ready ()
+{
+}