From 379b2b37010cff9343cb9cc468c5c0b17a37ff7e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 27 Jul 2013 18:31:10 +0200 Subject: Create a common base class event_t for packet_t and scheduled_t --- mmss/CMakeLists.txt | 2 +- mmss/event.cpp | 47 ++++++++++++++++++++++++++++++++++++++ mmss/event.hpp | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ mmss/gmrf.cpp | 11 ++++----- mmss/iface.cpp | 17 +++----------- mmss/mmss.cpp | 44 +++++++----------------------------- mmss/mmss.hpp | 56 +++++++-------------------------------------- mmss/schedule.cpp | 36 ----------------------------- 8 files changed, 136 insertions(+), 142 deletions(-) create mode 100644 mmss/event.cpp create mode 100644 mmss/event.hpp delete mode 100644 mmss/schedule.cpp 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/event.cpp b/mmss/event.cpp new file mode 100644 index 0000000..6326e98 --- /dev/null +++ b/mmss/event.cpp @@ -0,0 +1,47 @@ +/* + Copyright (c) 2013, Matthias Schiffer + 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. +*/ + + +#include "event.hpp" +#include "mmss.hpp" + + +namespace MMSS { + +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 + 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 + + +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 dest; + + size_t len; + std::unique_ptr data; + + virtual void handle(context_t *mmss); +}; + +class scheduled_t : public event_t { +public: + std::shared_ptr 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 scheduled = std::make_shared(); @@ -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) { - 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, const std::shared_ptr &net, const std::string &name, const gmrf_addr_t *address) { - std::shared_ptr iface = iface_t::create(); + std::shared_ptr iface = std::make_shared(); iface->name = name; iface->address = *address; @@ -61,14 +50,14 @@ void enqueue(context_t *mmss, const std::shared_ptr &source, const std: std::shared_ptr packet = std::make_shared(); 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> &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 node1 = node_t::create(&mmss, "node1", 1, proto); - std::shared_ptr node2 = node_t::create(&mmss, "node2", 2, proto); - std::shared_ptr node3 = node_t::create(&mmss, "node3", 3, proto); + std::shared_ptr node1 = std::make_shared(&mmss, "node1", 1, proto); + std::shared_ptr node2 = std::make_shared(&mmss, "node2", 2, proto); + std::shared_ptr node3 = std::make_shared(&mmss, "node3", 3, proto); std::list> 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 = mmss.packet_queue.get(); - std::shared_ptr 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 #include -struct gmrf { +struct gmrf : public std::enable_shared_from_this { private: - gmrf(MMSS::context_t *mmss0, const std::string &name0, unsigned rand_seed0, const std::shared_ptr &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 create(MMSS::context_t *mmss, const std::string &name, unsigned rand_seed, const std::shared_ptr &proto) { - MMSS::node_t *node = new MMSS::node_t(mmss, name, rand_seed, proto); - - std::shared_ptr ptr(node); - node->node = ptr; - - return ptr; - } - - std::weak_ptr node; + gmrf(MMSS::context_t *mmss0, const std::string &name0, unsigned rand_seed0, const std::shared_ptr &proto0) : + mmss(mmss0), name(name0), rand_seed(rand_seed0), proto(proto0) {} MMSS::context_t *mmss; @@ -63,23 +54,13 @@ public: std::shared_ptr proto; }; -struct gmrf_iface { +struct gmrf_iface : public std::enable_shared_from_this { private: - gmrf_iface() {} gmrf_iface(gmrf_iface const&) = delete; gmrf_iface& operator=(gmrf_iface const&) = delete; public: - static std::shared_ptr create() { - MMSS::iface_t *iface = new MMSS::iface_t; - - std::shared_ptr ptr(iface); - iface->iface = ptr; - - return ptr; - } - - std::weak_ptr 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_queue; - timeout_queue_t scheduled_queue; + timeout_queue_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 source; - std::weak_ptr dest; - - size_t len; - std::unique_ptr data; -}; - -class scheduled_t { -public: - std::shared_ptr node; - gmrf_scheduled_func f; - void *arg; -}; - std::shared_ptr 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, const std::shared_ptr &net, const std::string &name, const gmrf_addr_t *address); -void dispatch(const std::shared_ptr &packet); -void run_scheduled(const std::shared_ptr &scheduled); void enqueue(context_t *mmss, const std::shared_ptr &source, const std::shared_ptr &dest, const void *data, size_t len); void logf(context_t *mmss, int priority, const char *format, ...); diff --git a/mmss/schedule.cpp b/mmss/schedule.cpp deleted file mode 100644 index 77d766d..0000000 --- a/mmss/schedule.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (c) 2013, Matthias Schiffer - 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. -*/ - - -#include "mmss.hpp" - - -namespace MMSS { - -void run_scheduled(const std::shared_ptr &scheduled) { - scheduled->f(scheduled->node.get(), scheduled->node->ctx, scheduled->arg); -} - -} -- cgit v1.2.3