summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2013-07-27 18:31:10 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2013-07-27 18:31:10 +0200
commit379b2b37010cff9343cb9cc468c5c0b17a37ff7e (patch)
tree1b4c3e3cedf45123a7a16084cfeecb5ac234bfbb
parent49652b9e2882a1c3cd5203ea91f90cdd32a090e9 (diff)
downloadgmrf-379b2b37010cff9343cb9cc468c5c0b17a37ff7e.tar
gmrf-379b2b37010cff9343cb9cc468c5c0b17a37ff7e.zip
Create a common base class event_t for packet_t and scheduled_t
-rw-r--r--mmss/CMakeLists.txt2
-rw-r--r--mmss/event.cpp (renamed from mmss/schedule.cpp)15
-rw-r--r--mmss/event.hpp65
-rw-r--r--mmss/gmrf.cpp11
-rw-r--r--mmss/iface.cpp17
-rw-r--r--mmss/mmss.cpp44
-rw-r--r--mmss/mmss.hpp56
7 files changed, 102 insertions, 108 deletions
diff --git a/mmss/CMakeLists.txt b/mmss/CMakeLists.txt
index 04ac405..01e8488 100644
--- a/mmss/CMakeLists.txt
+++ b/mmss/CMakeLists.txt
@@ -5,12 +5,12 @@ BISON_TARGET(mmss_config_parse config.y ${CMAKE_CURRENT_BINARY_DIR}/config.yy.cp
add_executable(mmss
config.cpp
+ event.cpp
gmrf.cpp
iface.cpp
log.cpp
mmss.cpp
protocol.cpp
- schedule.cpp
${FLEX_mmss_config_lex_OUTPUTS}
${BISON_mmss_config_parse_OUTPUTS}
)
diff --git a/mmss/schedule.cpp b/mmss/event.cpp
index 77d766d..6326e98 100644
--- a/mmss/schedule.cpp
+++ b/mmss/event.cpp
@@ -24,13 +24,24 @@
*/
+#include "event.hpp"
#include "mmss.hpp"
namespace MMSS {
-void run_scheduled(const std::shared_ptr<scheduled_t> &scheduled) {
- scheduled->f(scheduled->node.get(), scheduled->node->ctx, scheduled->arg);
+void packet_t::handle(context_t *mmss) {
+ auto dest_ptr = dest.lock();
+ if (!dest_ptr)
+ return;
+
+ node_t *node = dest_ptr->node;
+
+ node->proto->handle_packet(node, node->ctx, dest_ptr.get(), &source_addr, data.get(), len);
+}
+
+void scheduled_t::handle(context_t *mmss) {
+ f(node.get(), node->ctx, arg);
}
}
diff --git a/mmss/event.hpp b/mmss/event.hpp
new file mode 100644
index 0000000..d0fe092
--- /dev/null
+++ b/mmss/event.hpp
@@ -0,0 +1,65 @@
+/*
+ Copyright (c) 2013, Matthias Schiffer <mschiffer@universe-factory.net>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#pragma once
+
+#include "types.hpp"
+
+#include <memory>
+
+
+namespace MMSS {
+
+class event_t {
+public:
+ virtual ~event_t() {}
+
+ virtual void handle(context_t *mmss) = 0;
+};
+
+class packet_t : public event_t {
+public:
+ uint64_t sent;
+
+ gmrf_addr_t source_addr;
+ std::weak_ptr<iface_t> dest;
+
+ size_t len;
+ std::unique_ptr<uint8_t[]> data;
+
+ virtual void handle(context_t *mmss);
+};
+
+class scheduled_t : public event_t {
+public:
+ std::shared_ptr<node_t> node;
+ gmrf_scheduled_func f;
+ void *arg;
+
+ virtual void handle(context_t *mmss);
+};
+
+}
diff --git a/mmss/gmrf.cpp b/mmss/gmrf.cpp
index 3a8a224..9cda413 100644
--- a/mmss/gmrf.cpp
+++ b/mmss/gmrf.cpp
@@ -45,8 +45,7 @@ size_t gmrf_iface_get_mtu(gmrf_t *gmrf, gmrf_iface_t *iface) {
}
bool gmrf_iface_send(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t len, const gmrf_addr_t *dest) {
- auto src_iface = iface->iface.lock();
- assert(src_iface);
+ auto src_iface = iface->shared_from_this();
for (auto dest_iface : src_iface->net->interfaces) {
if (gmrf_addr_equal(&dest_iface->address, dest)) {
@@ -59,8 +58,7 @@ bool gmrf_iface_send(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t
}
bool gmrf_iface_send_bc(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t len) {
- auto src_iface = iface->iface.lock();
- assert(src_iface);
+ auto src_iface = iface->shared_from_this();
for (auto dest_iface : src_iface->net->interfaces) {
if (dest_iface != src_iface)
@@ -71,8 +69,7 @@ bool gmrf_iface_send_bc(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, siz
}
void gmrf_schedule(gmrf_t *gmrf, gmrf_scheduled_func f, void *arg, unsigned delay) {
- auto node = gmrf->node.lock();
- assert(node);
+ auto node = gmrf->shared_from_this();
std::shared_ptr<MMSS::scheduled_t> scheduled = std::make_shared<MMSS::scheduled_t>();
@@ -80,7 +77,7 @@ void gmrf_schedule(gmrf_t *gmrf, gmrf_scheduled_func f, void *arg, unsigned dela
scheduled->f = f;
scheduled->arg = arg;
- gmrf->mmss->scheduled_queue.put(std::move(scheduled), gmrf->mmss->now()+delay);
+ gmrf->mmss->event_queue.put(std::move(scheduled), gmrf->mmss->now()+delay);
}
gmrf_time_t gmrf_now(gmrf_t *gmrf) {
diff --git a/mmss/iface.cpp b/mmss/iface.cpp
index 38808f1..7e43dd2 100644
--- a/mmss/iface.cpp
+++ b/mmss/iface.cpp
@@ -31,19 +31,8 @@
namespace MMSS {
-void dispatch(const std::shared_ptr<packet_t> &packet) {
- auto source = packet->source.lock();
- auto dest = packet->dest.lock();
- if (!source || !dest)
- return;
-
- node_t *node = dest->node;
-
- node->proto->handle_packet(node, node->ctx, dest.get(), &source->address, packet->data.get(), packet->len);
-}
-
void add_iface(const std::shared_ptr<node_t> &node, const std::shared_ptr<network_t> &net, const std::string &name, const gmrf_addr_t *address) {
- std::shared_ptr<iface_t> iface = iface_t::create();
+ std::shared_ptr<iface_t> iface = std::make_shared<iface_t>();
iface->name = name;
iface->address = *address;
@@ -61,14 +50,14 @@ void enqueue(context_t *mmss, const std::shared_ptr<iface_t> &source, const std:
std::shared_ptr<packet_t> packet = std::make_shared<packet_t>();
packet->sent = mmss->now();
- packet->source = source;
+ packet->source_addr = source->address;
packet->dest = dest;
packet->len = len;
packet->data.reset(new uint8_t[len]);
std::memcpy(packet->data.get(), data, len);
- mmss->packet_queue.put(std::move(packet), mmss->now()+1);
+ mmss->event_queue.put(std::move(packet), mmss->now()+1);
}
}
diff --git a/mmss/mmss.cpp b/mmss/mmss.cpp
index bbdb0ca..8b94c20 100644
--- a/mmss/mmss.cpp
+++ b/mmss/mmss.cpp
@@ -39,20 +39,6 @@ static void init_nodes(std::list<std::shared_ptr<node_t>> &nodes) {
}
-static inline int timeout_min(int a, int b) {
- if (a < 0)
- return b;
- else if (b < 0)
- return a;
- else
- return std::min(a, b);
-}
-
-
-static int get_queue_timeout(const context_t *mmss) {
- return timeout_min(mmss->packet_queue.timeout(), mmss->scheduled_queue.timeout());
-}
-
void main(int argc, char *argv[]) {
if (argc != 2) {
std::fprintf(stderr, "usage: %s protocol_module\n", argv[0]);
@@ -74,9 +60,9 @@ void main(int argc, char *argv[]) {
net0->mtu = 1500;
net1->mtu = 1500;
- std::shared_ptr<node_t> node1 = node_t::create(&mmss, "node1", 1, proto);
- std::shared_ptr<node_t> node2 = node_t::create(&mmss, "node2", 2, proto);
- std::shared_ptr<node_t> node3 = node_t::create(&mmss, "node3", 3, proto);
+ std::shared_ptr<node_t> node1 = std::make_shared<node_t>(&mmss, "node1", 1, proto);
+ std::shared_ptr<node_t> node2 = std::make_shared<node_t>(&mmss, "node2", 2, proto);
+ std::shared_ptr<node_t> node3 = std::make_shared<node_t>(&mmss, "node3", 3, proto);
std::list<std::shared_ptr<node_t>> nodes;
@@ -93,10 +79,10 @@ void main(int argc, char *argv[]) {
add_iface(node3, net1, "mmss1", &addr4);
while (true) {
- if (mmss.now() > 1000000000)
+ if (mmss.now() > 10000000)
break;
- int timeout = get_queue_timeout(&mmss);
+ int timeout = mmss.event_queue.timeout();
if (timeout < 0) {
fprintf(stderr, "nothing queued, deadlock occured.\n");
@@ -104,29 +90,15 @@ void main(int argc, char *argv[]) {
}
if (timeout > 0) {
- assert(!mmss.packet_queue.get());
- assert(!mmss.scheduled_queue.get());
+ assert(!mmss.event_queue.get());
mmss.time += timeout;
- timeout = get_queue_timeout(&mmss);
+ timeout = mmss.event_queue.timeout();
}
assert(timeout == 0);
- while (timeout == 0) {
- std::shared_ptr<packet_t> packet = mmss.packet_queue.get();
- std::shared_ptr<scheduled_t> scheduled = mmss.scheduled_queue.get();
-
- assert(packet || scheduled);
-
- if (packet)
- dispatch(packet);
-
- if (scheduled)
- run_scheduled(scheduled);
-
- timeout = get_queue_timeout(&mmss);
- }
+ mmss.event_queue.get()->handle(&mmss);
}
}
diff --git a/mmss/mmss.hpp b/mmss/mmss.hpp
index 723e0d6..c3bb31c 100644
--- a/mmss/mmss.hpp
+++ b/mmss/mmss.hpp
@@ -26,30 +26,21 @@
#pragma once
+#include "event.hpp"
#include "queue.hpp"
#include <list>
#include <memory>
-struct gmrf {
+struct gmrf : public std::enable_shared_from_this<MMSS::node_t> {
private:
- gmrf(MMSS::context_t *mmss0, const std::string &name0, unsigned rand_seed0, const std::shared_ptr<const MMSS::protocol_t> &proto0) :
- mmss(mmss0), name(name0), rand_seed(rand_seed0), proto(proto0) {}
gmrf(gmrf const&) = delete;
gmrf& operator=(gmrf const&) = delete;
public:
- static std::shared_ptr<MMSS::node_t> create(MMSS::context_t *mmss, const std::string &name, unsigned rand_seed, const std::shared_ptr<const MMSS::protocol_t> &proto) {
- MMSS::node_t *node = new MMSS::node_t(mmss, name, rand_seed, proto);
-
- std::shared_ptr<MMSS::node_t> ptr(node);
- node->node = ptr;
-
- return ptr;
- }
-
- std::weak_ptr<MMSS::node_t> node;
+ gmrf(MMSS::context_t *mmss0, const std::string &name0, unsigned rand_seed0, const std::shared_ptr<const MMSS::protocol_t> &proto0) :
+ mmss(mmss0), name(name0), rand_seed(rand_seed0), proto(proto0) {}
MMSS::context_t *mmss;
@@ -63,23 +54,13 @@ public:
std::shared_ptr<const MMSS::protocol_t> proto;
};
-struct gmrf_iface {
+struct gmrf_iface : public std::enable_shared_from_this<MMSS::iface_t> {
private:
- gmrf_iface() {}
gmrf_iface(gmrf_iface const&) = delete;
gmrf_iface& operator=(gmrf_iface const&) = delete;
public:
- static std::shared_ptr<MMSS::iface_t> create() {
- MMSS::iface_t *iface = new MMSS::iface_t;
-
- std::shared_ptr<MMSS::iface_t> ptr(iface);
- iface->iface = ptr;
-
- return ptr;
- }
-
- std::weak_ptr<MMSS::iface_t> iface;
+ gmrf_iface() = default;
std::string name;
gmrf_addr_t address;
@@ -93,10 +74,9 @@ namespace MMSS {
class context_t : public now_t {
public:
- timeout_queue_t<packet_t> packet_queue;
- timeout_queue_t<scheduled_t> scheduled_queue;
+ timeout_queue_t<event_t> event_queue;
- context_t() : packet_queue(this), scheduled_queue(this) {}
+ context_t() : event_queue(this) {}
};
class config_t {
@@ -113,24 +93,6 @@ public:
size_t mtu;
};
-class packet_t {
-public:
- uint64_t sent;
-
- std::weak_ptr<iface_t> source;
- std::weak_ptr<iface_t> dest;
-
- size_t len;
- std::unique_ptr<uint8_t[]> data;
-};
-
-class scheduled_t {
-public:
- std::shared_ptr<node_t> node;
- gmrf_scheduled_func f;
- void *arg;
-};
-
std::shared_ptr<const protocol_t> load_protocol(const char *module);
@@ -138,8 +100,6 @@ bool read_config(context_t *mmss, config_t *conf, const char *filename);
void add_iface(const std::shared_ptr<node_t> &node, const std::shared_ptr<network_t> &net, const std::string &name, const gmrf_addr_t *address);
-void dispatch(const std::shared_ptr<packet_t> &packet);
-void run_scheduled(const std::shared_ptr<scheduled_t> &scheduled);
void enqueue(context_t *mmss, const std::shared_ptr<iface_t> &source, const std::shared_ptr<iface_t> &dest, const void *data, size_t len);
void logf(context_t *mmss, int priority, const char *format, ...);