Create a common base class event_t for packet_t and scheduled_t
This commit is contained in:
parent
49652b9e28
commit
379b2b3701
7 changed files with 102 additions and 108 deletions
|
@ -5,12 +5,12 @@ BISON_TARGET(mmss_config_parse config.y ${CMAKE_CURRENT_BINARY_DIR}/config.yy.cp
|
||||||
|
|
||||||
add_executable(mmss
|
add_executable(mmss
|
||||||
config.cpp
|
config.cpp
|
||||||
|
event.cpp
|
||||||
gmrf.cpp
|
gmrf.cpp
|
||||||
iface.cpp
|
iface.cpp
|
||||||
log.cpp
|
log.cpp
|
||||||
mmss.cpp
|
mmss.cpp
|
||||||
protocol.cpp
|
protocol.cpp
|
||||||
schedule.cpp
|
|
||||||
${FLEX_mmss_config_lex_OUTPUTS}
|
${FLEX_mmss_config_lex_OUTPUTS}
|
||||||
${BISON_mmss_config_parse_OUTPUTS}
|
${BISON_mmss_config_parse_OUTPUTS}
|
||||||
)
|
)
|
||||||
|
|
|
@ -24,13 +24,24 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "event.hpp"
|
||||||
#include "mmss.hpp"
|
#include "mmss.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace MMSS {
|
namespace MMSS {
|
||||||
|
|
||||||
void run_scheduled(const std::shared_ptr<scheduled_t> &scheduled) {
|
void packet_t::handle(context_t *mmss) {
|
||||||
scheduled->f(scheduled->node.get(), scheduled->node->ctx, scheduled->arg);
|
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
65
mmss/event.hpp
Normal 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);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -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) {
|
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();
|
auto src_iface = iface->shared_from_this();
|
||||||
assert(src_iface);
|
|
||||||
|
|
||||||
for (auto dest_iface : src_iface->net->interfaces) {
|
for (auto dest_iface : src_iface->net->interfaces) {
|
||||||
if (gmrf_addr_equal(&dest_iface->address, dest)) {
|
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) {
|
bool gmrf_iface_send_bc(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t len) {
|
||||||
auto src_iface = iface->iface.lock();
|
auto src_iface = iface->shared_from_this();
|
||||||
assert(src_iface);
|
|
||||||
|
|
||||||
for (auto dest_iface : src_iface->net->interfaces) {
|
for (auto dest_iface : src_iface->net->interfaces) {
|
||||||
if (dest_iface != src_iface)
|
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) {
|
void gmrf_schedule(gmrf_t *gmrf, gmrf_scheduled_func f, void *arg, unsigned delay) {
|
||||||
auto node = gmrf->node.lock();
|
auto node = gmrf->shared_from_this();
|
||||||
assert(node);
|
|
||||||
|
|
||||||
std::shared_ptr<MMSS::scheduled_t> scheduled = std::make_shared<MMSS::scheduled_t>();
|
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->f = f;
|
||||||
scheduled->arg = arg;
|
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) {
|
gmrf_time_t gmrf_now(gmrf_t *gmrf) {
|
||||||
|
|
|
@ -31,19 +31,8 @@
|
||||||
|
|
||||||
namespace MMSS {
|
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) {
|
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->name = name;
|
||||||
iface->address = *address;
|
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>();
|
std::shared_ptr<packet_t> packet = std::make_shared<packet_t>();
|
||||||
|
|
||||||
packet->sent = mmss->now();
|
packet->sent = mmss->now();
|
||||||
packet->source = source;
|
packet->source_addr = source->address;
|
||||||
packet->dest = dest;
|
packet->dest = dest;
|
||||||
packet->len = len;
|
packet->len = len;
|
||||||
|
|
||||||
packet->data.reset(new uint8_t[len]);
|
packet->data.reset(new uint8_t[len]);
|
||||||
std::memcpy(packet->data.get(), data, 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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[]) {
|
void main(int argc, char *argv[]) {
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
std::fprintf(stderr, "usage: %s protocol_module\n", argv[0]);
|
std::fprintf(stderr, "usage: %s protocol_module\n", argv[0]);
|
||||||
|
@ -74,9 +60,9 @@ void main(int argc, char *argv[]) {
|
||||||
net0->mtu = 1500;
|
net0->mtu = 1500;
|
||||||
net1->mtu = 1500;
|
net1->mtu = 1500;
|
||||||
|
|
||||||
std::shared_ptr<node_t> node1 = node_t::create(&mmss, "node1", 1, proto);
|
std::shared_ptr<node_t> node1 = std::make_shared<node_t>(&mmss, "node1", 1, proto);
|
||||||
std::shared_ptr<node_t> node2 = node_t::create(&mmss, "node2", 2, proto);
|
std::shared_ptr<node_t> node2 = std::make_shared<node_t>(&mmss, "node2", 2, proto);
|
||||||
std::shared_ptr<node_t> node3 = node_t::create(&mmss, "node3", 3, proto);
|
std::shared_ptr<node_t> node3 = std::make_shared<node_t>(&mmss, "node3", 3, proto);
|
||||||
|
|
||||||
std::list<std::shared_ptr<node_t>> nodes;
|
std::list<std::shared_ptr<node_t>> nodes;
|
||||||
|
|
||||||
|
@ -93,10 +79,10 @@ void main(int argc, char *argv[]) {
|
||||||
add_iface(node3, net1, "mmss1", &addr4);
|
add_iface(node3, net1, "mmss1", &addr4);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (mmss.now() > 1000000000)
|
if (mmss.now() > 10000000)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
int timeout = get_queue_timeout(&mmss);
|
int timeout = mmss.event_queue.timeout();
|
||||||
|
|
||||||
if (timeout < 0) {
|
if (timeout < 0) {
|
||||||
fprintf(stderr, "nothing queued, deadlock occured.\n");
|
fprintf(stderr, "nothing queued, deadlock occured.\n");
|
||||||
|
@ -104,29 +90,15 @@ void main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeout > 0) {
|
if (timeout > 0) {
|
||||||
assert(!mmss.packet_queue.get());
|
assert(!mmss.event_queue.get());
|
||||||
assert(!mmss.scheduled_queue.get());
|
|
||||||
|
|
||||||
mmss.time += timeout;
|
mmss.time += timeout;
|
||||||
timeout = get_queue_timeout(&mmss);
|
timeout = mmss.event_queue.timeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(timeout == 0);
|
assert(timeout == 0);
|
||||||
|
|
||||||
while (timeout == 0) {
|
mmss.event_queue.get()->handle(&mmss);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,30 +26,21 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "event.hpp"
|
||||||
#include "queue.hpp"
|
#include "queue.hpp"
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
struct gmrf {
|
struct gmrf : public std::enable_shared_from_this<MMSS::node_t> {
|
||||||
private:
|
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(gmrf const&) = delete;
|
||||||
gmrf& operator=(gmrf const&) = delete;
|
gmrf& operator=(gmrf const&) = delete;
|
||||||
|
|
||||||
public:
|
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) {
|
gmrf(MMSS::context_t *mmss0, const std::string &name0, unsigned rand_seed0, const std::shared_ptr<const MMSS::protocol_t> &proto0) :
|
||||||
MMSS::node_t *node = new MMSS::node_t(mmss, name, rand_seed, proto);
|
mmss(mmss0), name(name0), rand_seed(rand_seed0), proto(proto0) {}
|
||||||
|
|
||||||
std::shared_ptr<MMSS::node_t> ptr(node);
|
|
||||||
node->node = ptr;
|
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::weak_ptr<MMSS::node_t> node;
|
|
||||||
|
|
||||||
MMSS::context_t *mmss;
|
MMSS::context_t *mmss;
|
||||||
|
|
||||||
|
@ -63,23 +54,13 @@ public:
|
||||||
std::shared_ptr<const MMSS::protocol_t> proto;
|
std::shared_ptr<const MMSS::protocol_t> proto;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gmrf_iface {
|
struct gmrf_iface : public std::enable_shared_from_this<MMSS::iface_t> {
|
||||||
private:
|
private:
|
||||||
gmrf_iface() {}
|
|
||||||
gmrf_iface(gmrf_iface const&) = delete;
|
gmrf_iface(gmrf_iface const&) = delete;
|
||||||
gmrf_iface& operator=(gmrf_iface const&) = delete;
|
gmrf_iface& operator=(gmrf_iface const&) = delete;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static std::shared_ptr<MMSS::iface_t> create() {
|
gmrf_iface() = default;
|
||||||
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;
|
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
gmrf_addr_t address;
|
gmrf_addr_t address;
|
||||||
|
@ -93,10 +74,9 @@ namespace MMSS {
|
||||||
|
|
||||||
class context_t : public now_t {
|
class context_t : public now_t {
|
||||||
public:
|
public:
|
||||||
timeout_queue_t<packet_t> packet_queue;
|
timeout_queue_t<event_t> event_queue;
|
||||||
timeout_queue_t<scheduled_t> scheduled_queue;
|
|
||||||
|
|
||||||
context_t() : packet_queue(this), scheduled_queue(this) {}
|
context_t() : event_queue(this) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class config_t {
|
class config_t {
|
||||||
|
@ -113,24 +93,6 @@ public:
|
||||||
size_t mtu;
|
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);
|
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 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 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, ...);
|
void logf(context_t *mmss, int priority, const char *format, ...);
|
||||||
|
|
Reference in a new issue