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
|
||||
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}
|
||||
)
|
||||
|
|
|
@ -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
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) {
|
||||
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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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, ...);
|
||||
|
|
Reference in a new issue