Create a common base class event_t for packet_t and scheduled_t

This commit is contained in:
Matthias Schiffer 2013-07-27 18:31:10 +02:00
parent 49652b9e28
commit 379b2b3701
7 changed files with 102 additions and 108 deletions

View file

@ -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}
)

View file

@ -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);
}
}

65
mmss/event.hpp Normal file
View file

@ -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);
};
}

View file

@ -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) {

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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, ...);