From 1f67abe0f324a226de619ba9de44dbd5eb54ecaa Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 26 Jul 2013 17:45:15 +0200 Subject: Clean up queue implementation, fix namespaces --- mmss/CMakeLists.txt | 1 - mmss/config.cpp | 40 ++++++++++------ mmss/config.l | 2 +- mmss/config.y | 15 +++--- mmss/iface.cpp | 80 ++++++++++++++++--------------- mmss/log.cpp | 17 ++++--- mmss/mmss.cpp | 53 ++++++++++++--------- mmss/mmss.hpp | 133 ++++++++++++++++++++-------------------------------- mmss/protocol.cpp | 8 +++- mmss/queue.cpp | 78 ------------------------------ mmss/queue.hpp | 58 +++++++++++++++++++---- mmss/schedule.cpp | 17 ++++--- mmss/types.hpp | 29 ++++++++---- 13 files changed, 257 insertions(+), 274 deletions(-) delete mode 100644 mmss/queue.cpp diff --git a/mmss/CMakeLists.txt b/mmss/CMakeLists.txt index cd719e0..047e348 100644 --- a/mmss/CMakeLists.txt +++ b/mmss/CMakeLists.txt @@ -9,7 +9,6 @@ add_executable(mmss log.cpp mmss.cpp protocol.cpp - queue.cpp schedule.cpp ${FLEX_mmss_config_lex_OUTPUTS} ${BISON_mmss_config_parse_OUTPUTS} diff --git a/mmss/config.cpp b/mmss/config.cpp index 0be95fb..529e9b1 100644 --- a/mmss/config.cpp +++ b/mmss/config.cpp @@ -28,13 +28,19 @@ #include #include +#include + #include -void mmss_config_add_network(mmss_t *mmss, mmss_config_t *conf, const char *name) { - mmss_logf(mmss, LOG_NOTICE, "Adding network `%s'", name); +namespace MMSS { + +namespace Config { + +void add_network(context_t *mmss, config_t *conf, const char *name) { + logf(mmss, LOG_NOTICE, "adding network `%s'", name); - mmss_network_t *net = new mmss_network_t; + network_t *net = new network_t; net->name = strdup(name); net->mtu = 1500; @@ -43,7 +49,9 @@ void mmss_config_add_network(mmss_t *mmss, mmss_config_t *conf, const char *name conf->networks = net; } -bool mmss_read_config(mmss_t *mmss, mmss_config_t *conf, const char *filename) { +} + +bool read_config(context_t *mmss, config_t *conf, const char *filename) { bool ret = true; char *oldcwd = get_current_dir_name(); char *filename2 = NULL; @@ -51,11 +59,11 @@ bool mmss_read_config(mmss_t *mmss, mmss_config_t *conf, const char *filename) { FILE *file; yyscan_t scanner; mmss_config_pstate *ps; - mmss_string_stack_t *strings = NULL; int token; YYSTYPE token_val; YYLTYPE loc = {1, 0, 1, 0}; int parse_ret; + std::stack strings; mmss_config_yylex_init(&scanner); @@ -67,7 +75,7 @@ bool mmss_read_config(mmss_t *mmss, mmss_config_t *conf, const char *filename) { else { file = fopen(filename, "r"); if (!file) { - mmss_logf(mmss, LOG_ERR, "can't open config file `%s': %s", filename, strerror(errno)); + logf(mmss, LOG_ERR, "can't open config file `%s': %s", filename, strerror(errno)); ret = false; goto end_free; } @@ -80,7 +88,7 @@ bool mmss_read_config(mmss_t *mmss, mmss_config_t *conf, const char *filename) { dir = dirname(filename2); if (chdir(dir)) { - mmss_logf(mmss, LOG_ERR, "change from directory `%s' to `%s' failed", oldcwd, dir); + logf(mmss, LOG_ERR, "change from directory `%s' to `%s' failed", oldcwd, dir); ret = false; goto end_free; } @@ -90,15 +98,14 @@ bool mmss_read_config(mmss_t *mmss, mmss_config_t *conf, const char *filename) { token = mmss_config_yylex(&token_val, &loc, scanner); if (token < 0) { - mmss_logf(mmss, LOG_ERR, "config error: %s at %s:%i:%i", token_val.error, filename, loc.first_line, loc.first_column); + logf(mmss, LOG_ERR, "config error: %s at %s:%i:%i", token_val.error, filename, loc.first_line, loc.first_column); ret = false; goto end_free; } - if (token == TOK_STRING) { - token_val.str->next = strings; - strings = token_val.str; - } + if (token == TOK_STRING) + strings.push(token_val.str); + parse_ret = mmss_config_push_parse(ps, token, &token_val, &loc, mmss, conf, filename); } while (parse_ret == YYPUSH_MORE); @@ -107,13 +114,16 @@ bool mmss_read_config(mmss_t *mmss, mmss_config_t *conf, const char *filename) { ret = false; end_free: - mmss_string_stack_free(strings); + while (!strings.empty()) { + std::free(strings.top()); + strings.pop(); + } mmss_config_pstate_delete(ps); mmss_config_yylex_destroy(scanner); if(chdir(oldcwd)) - mmss_logf(mmss, LOG_ERR, "can't chdir to `%s': %s", oldcwd, strerror(errno)); + logf(mmss, LOG_ERR, "can't chdir to `%s': %s", oldcwd, strerror(errno)); free(filename2); free(oldcwd); @@ -123,3 +133,5 @@ bool mmss_read_config(mmss_t *mmss, mmss_config_t *conf, const char *filename) { return ret; } + +} diff --git a/mmss/config.l b/mmss/config.l index 6f20423..f612613 100644 --- a/mmss/config.l +++ b/mmss/config.l @@ -100,7 +100,7 @@ network { TOKEN(TOK_NETWORK); } } } yytext[yyleng-esc-1] = 0; - yylval->str = mmss_string_stack_dup(yytext); + yylval->str = strdup(yytext); BEGIN(NEEDSPACE); yylloc->last_column++; return TOK_STRING; diff --git a/mmss/config.y b/mmss/config.y index 722ce25..6761d7c 100644 --- a/mmss/config.y +++ b/mmss/config.y @@ -28,8 +28,8 @@ %define api.push-pull push %name-prefix "mmss_config_" %locations -%parse-param {mmss_t *mmss} -%parse-param {mmss_config_t *conf} +%parse-param {MMSS::context_t *mmss} +%parse-param {MMSS::config_t *conf} %parse-param {const char *filename} @@ -37,12 +37,13 @@ #include #include + #include } %union { int num; - mmss_string_stack_t *str; bool boolean; + char *str; const char *error; } @@ -56,7 +57,7 @@ %code { - void mmss_config_error(YYLTYPE *loc, mmss_t *mmss, mmss_config_t *conf, const char *filename, const char *s); + void mmss_config_error(YYLTYPE *loc, MMSS::context_t *mmss, MMSS::config_t *conf, const char *filename, const char *s); } @@ -75,7 +76,7 @@ statement: TOK_NETWORK network '{' network_config '}' ; network: TOK_STRING { - mmss_config_add_network(mmss, conf, $1->str); + MMSS::Config::add_network(mmss, conf, $1); } ; @@ -88,6 +89,6 @@ boolean: TOK_YES { $$ = true; } %% -void mmss_config_error(YYLTYPE *loc, mmss_t *mmss, mmss_config_t *conf, const char *filename, const char *s) { - mmss_logf(mmss, LOG_ERR, "config error: %s at %s:%i:%i", s, filename, loc->first_line, loc->first_column); +void mmss_config_error(YYLTYPE *loc, MMSS::context_t *mmss, MMSS::config_t *conf, const char *filename, const char *s) { + MMSS::logf(mmss, LOG_ERR, "config error: %s at %s:%i:%i", s, filename, loc->first_line, loc->first_column); } diff --git a/mmss/iface.cpp b/mmss/iface.cpp index 441da4a..e25eccd 100644 --- a/mmss/iface.cpp +++ b/mmss/iface.cpp @@ -26,38 +26,68 @@ #include "mmss.hpp" -#include +#include -gmrf_addr_t gmrf_iface_get_addr(gmrf_t *gmrf, gmrf_iface_t *iface) { - return iface->address; -} +namespace MMSS { -const char* gmrf_iface_get_name(gmrf_t *gmrf, gmrf_iface_t *iface) { - return iface->name; +void dispatch(std::shared_ptr packet) { + packet->dest->node->proto->handle_packet(packet->dest->node, packet->dest->node->ctx, packet->dest, + &packet->source->address, packet->data.get(), packet->len); } -size_t gmrf_iface_get_mtu(gmrf_t *gmrf, gmrf_iface_t *iface) { - return iface->net->mtu; +void add_iface(gmrf_t *node, network_t *net, const char *name, const gmrf_addr_t *address) { + gmrf_iface_t *iface = new gmrf_iface_t; + + iface->name = strdup(name); + iface->address = *address; + + iface->node = node; + iface->net = net; + + iface->node_next = node->interfaces; + node->interfaces = iface; + + iface->network_next = net->interfaces; + net->interfaces = iface; + + node->proto->add_iface(node, node->ctx, iface); } -static void enqueue(mmss_t *mmss, gmrf_iface_t *source, gmrf_iface_t *dest, const void *data, size_t len) { - mmss_packet_t *packet = reinterpret_cast(calloc(1, sizeof(mmss_packet_t) + len)); +static void enqueue(context_t *mmss, gmrf_iface_t *source, gmrf_iface_t *dest, const void *data, size_t len) { + std::shared_ptr packet = std::make_shared(); packet->sent = mmss->now; packet->source = source; packet->dest = dest; packet->len = len; - memcpy(packet->data, data, len); - mmss_queue_put(mmss, &mmss->packet_queue, packet, mmss->now+1); + packet->data.reset(new uint8_t[len]); + std::memcpy(packet->data.get(), data, len); + + mmss->packet_queue.put(packet, mmss->now+1); +} + +} + + +gmrf_addr_t gmrf_iface_get_addr(gmrf_t *gmrf, gmrf_iface_t *iface) { + return iface->address; +} + +const char* gmrf_iface_get_name(gmrf_t *gmrf, gmrf_iface_t *iface) { + return iface->name; +} + +size_t gmrf_iface_get_mtu(gmrf_t *gmrf, gmrf_iface_t *iface) { + return iface->net->mtu; } bool gmrf_iface_send(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t len, const gmrf_addr_t *dest) { gmrf_iface_t *dest_iface; for (dest_iface = iface->net->interfaces; dest_iface; dest_iface = dest_iface->network_next) { if (gmrf_addr_equal(&dest_iface->address, dest)) { - enqueue(gmrf->mmss, iface, dest_iface, data, len); + MMSS::enqueue(gmrf->mmss, iface, dest_iface, data, len); break; } } @@ -74,27 +104,3 @@ bool gmrf_iface_send_bc(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, siz return true; } - -void mmss_dispatch(mmss_packet_t *packet) { - packet->dest->node->proto->handle_packet(packet->dest->node, packet->dest->node->ctx, packet->dest, - &packet->source->address, packet->data, packet->len); - free(packet); -} - -void mmss_add_iface(gmrf_t *node, mmss_network_t *net, const char *name, const gmrf_addr_t *address) { - gmrf_iface_t *iface = new gmrf_iface_t; - - iface->name = strdup(name); - iface->address = *address; - - iface->node = node; - iface->net = net; - - iface->node_next = node->interfaces; - node->interfaces = iface; - - iface->network_next = net->interfaces; - net->interfaces = iface; - - node->proto->add_iface(node, node->ctx, iface); -} diff --git a/mmss/log.cpp b/mmss/log.cpp index eb2ce03..029b1d6 100644 --- a/mmss/log.cpp +++ b/mmss/log.cpp @@ -26,13 +26,16 @@ #include "mmss.hpp" +#include #include +namespace MMSS { + static inline int snprintf_safe(char *buffer, size_t size, const char *format, ...) { - va_list ap; + std::va_list ap; va_start(ap, format); - int ret = vsnprintf(buffer, size, format, ap); + int ret = std::vsnprintf(buffer, size, format, ap); va_end(ap); return ret < 0 ? 0 : ret > size ? size : ret; @@ -57,13 +60,13 @@ static inline const char* get_log_prefix(int log_level) { } } -void mmss_logf(mmss_t *mmss, int priority, const char *format, ...) { +void logf(context_t *mmss, int priority, const char *format, ...) { char buf[1024]; size_t pos = 0; pos += snprintf_safe(buf, sizeof(buf), "[% 5u.%03u] ", mmss->now/1000, mmss->now%1000); - va_list ap; + std::va_list ap; va_start(ap, format); vsnprintf(buf+pos, sizeof(buf)-pos, format, ap); va_end(ap); @@ -71,16 +74,18 @@ void mmss_logf(mmss_t *mmss, int priority, const char *format, ...) { fprintf(stderr, "%s\n", buf); } +} + void gmrf_logf(gmrf_t *gmrf, int priority, const char *format, ...) { char buf[1024]; size_t pos = 0; - pos += snprintf_safe(buf, sizeof(buf), "%s: %s", gmrf->name, get_log_prefix(priority)); + pos += MMSS::snprintf_safe(buf, sizeof(buf), "%s: %s", gmrf->name, MMSS::get_log_prefix(priority)); va_list ap; va_start(ap, format); vsnprintf(buf+pos, sizeof(buf)-pos, format, ap); va_end(ap); - mmss_logf(gmrf->mmss, priority, "%s", buf); + MMSS::logf(gmrf->mmss, priority, "%s", buf); } diff --git a/mmss/mmss.cpp b/mmss/mmss.cpp index 8447e5e..cb50329 100644 --- a/mmss/mmss.cpp +++ b/mmss/mmss.cpp @@ -28,7 +28,6 @@ #include #include -#include gmrf_time_t gmrf_now(gmrf_t *gmrf) { @@ -43,6 +42,7 @@ void gmrf_random_bytes(gmrf_t *gmrf, void *buffer, size_t len) { data[i] = rand_r(&gmrf->rand_seed); } +namespace MMSS { static void init_nodes(gmrf_t *nodes) { gmrf_t *node; @@ -62,27 +62,30 @@ static inline int timeout_min(int a, int b) { } -static int get_queue_timeout(const mmss_t *mmss) { - return timeout_min(mmss_queue_timeout(mmss, &mmss->packet_queue), mmss_queue_timeout(mmss, &mmss->scheduled_queue)); +static int get_queue_timeout(const context_t *mmss) { + return timeout_min(mmss->packet_queue.timeout(), mmss->scheduled_queue.timeout()); } +uint64_t now(const context_t *mmss) { + return mmss->now; +} -int main(int argc, char *argv[]) { +void main(int argc, char *argv[]) { if (argc != 2) { - fprintf(stderr, "usage: %s protocol_module\n", argv[0]); - return 1; + std::fprintf(stderr, "usage: %s protocol_module\n", argv[0]); + std::exit(1); } - const mmss_protocol_t *proto = mmss_load_protocol(argv[1]); + const protocol_t *proto = load_protocol(argv[1]); if (!proto) - return 1; + std::exit(1); - mmss_t mmss = { .now = 0 }; - mmss_config_t conf = {}; + context_t mmss; + config_t conf = {}; - mmss_read_config(&mmss, &conf, "babel_test.mmss"); + read_config(&mmss, &conf, "babel_test.mmss"); - mmss_network_t net0 = { .mtu = 1500 }, net1 = { .mtu = 1500 }; + network_t net0 = { .mtu = 1500 }, net1 = { .mtu = 1500 }; gmrf_t node1 = { .name = strdup("node1"), .mmss = &mmss, .rand_seed = 1, .proto = proto }; gmrf_t node2 = { .name = strdup("node2"), .mmss = &mmss, .rand_seed = 2, .proto = proto }; gmrf_t node3 = { .name = strdup("node3"), .mmss = &mmss, .rand_seed = 3, .proto = proto }; @@ -94,10 +97,10 @@ int main(int argc, char *argv[]) { init_nodes(nodes); gmrf_addr_t addr1 = {{1}}, addr2 = {{2}}, addr3 = {{3}}, addr4 = {{4}}; - mmss_add_iface(&node1, &net0, "mmss0", &addr1); - mmss_add_iface(&node2, &net0, "mmss0", &addr2); - mmss_add_iface(&node2, &net1, "mmss1", &addr3); - mmss_add_iface(&node3, &net1, "mmss1", &addr4); + add_iface(&node1, &net0, "mmss0", &addr1); + add_iface(&node2, &net0, "mmss0", &addr2); + add_iface(&node2, &net1, "mmss1", &addr3); + add_iface(&node3, &net1, "mmss1", &addr4); while (true) { int timeout = get_queue_timeout(&mmss); @@ -108,8 +111,8 @@ int main(int argc, char *argv[]) { } if (timeout > 0) { - assert(!mmss_queue_get(&mmss, &mmss.packet_queue)); - assert(!mmss_queue_get(&mmss, &mmss.scheduled_queue)); + assert(!mmss.packet_queue.get()); + assert(!mmss.scheduled_queue.get()); mmss.now += timeout; timeout = get_queue_timeout(&mmss); @@ -118,20 +121,26 @@ int main(int argc, char *argv[]) { assert(timeout == 0); while (timeout == 0) { - mmss_packet_t *packet = reinterpret_cast(mmss_queue_get(&mmss, &mmss.packet_queue)); - mmss_scheduled_t *scheduled = reinterpret_cast(mmss_queue_get(&mmss, &mmss.scheduled_queue)); + std::shared_ptr packet = mmss.packet_queue.get(); + std::shared_ptr scheduled = mmss.scheduled_queue.get(); assert(packet || scheduled); if (packet) - mmss_dispatch(packet); + dispatch(packet); if (scheduled) - mmss_run_scheduled(scheduled); + run_scheduled(scheduled); timeout = get_queue_timeout(&mmss); } } +} + +} + +int main(int argc, char *argv[]) { + MMSS::main(argc, argv); return 0; } diff --git a/mmss/mmss.hpp b/mmss/mmss.hpp index a2c2fe2..78c93be 100644 --- a/mmss/mmss.hpp +++ b/mmss/mmss.hpp @@ -24,34 +24,34 @@ */ -#ifndef _GMRF_MMSS_MMSS_H_ -#define _GMRF_MMSS_MMSS_H_ +#ifndef _GMRF_MMSS_MMSS_HPP_ +#define _GMRF_MMSS_MMSS_HPP_ #include "queue.hpp" -extern "C" { +#include -#include -#include -} - -#include -#include +namespace MMSS { -struct mmss { +class context_t { +public: uint64_t now; - mmss_queue_t packet_queue; - mmss_queue_t scheduled_queue; + timeout_queue_t packet_queue; + timeout_queue_t scheduled_queue; + + context_t() : now(0), packet_queue(this), scheduled_queue(this) {} }; -struct mmss_config { - mmss_network_t *networks; +class config_t { +public: + network_t *networks; gmrf_t *nodes; }; -struct mmss_network { - mmss_network_t *next; +class network_t { +public: + network_t *next; char *name; @@ -59,66 +59,43 @@ struct mmss_network { size_t mtu; }; -struct mmss_packet { +class packet_t { +public: uint64_t sent; gmrf_iface_t *source; gmrf_iface_t *dest; size_t len; - uint8_t data[]; + std::unique_ptr data; }; -struct mmss_scheduled { +class scheduled_t { +public: gmrf_t *node; gmrf_scheduled_func f; void *arg; }; -struct mmss_string_stack { - mmss_string_stack_t *next; - char str[]; -}; - - -struct gmrf { - gmrf_t *next; - - char *name; - mmss_t *mmss; - gmrf_context_t *ctx; - gmrf_iface_t *interfaces; - - unsigned rand_seed; - - const mmss_protocol_t *proto; -}; - -struct gmrf_iface { - gmrf_iface_t *node_next; - gmrf_iface_t *network_next; - - char *name; - gmrf_addr_t address; +const protocol_t* load_protocol(const char *module); - gmrf_t *node; - mmss_network_t *net; -}; +namespace Config { +void add_network(context_t *mmss, config_t *conf, const char *name); -const mmss_protocol_t* mmss_load_protocol(const char *module); +} -void mmss_config_add_network(mmss_t *mmss, mmss_config_t *conf, const char *name); +bool read_config(context_t *mmss, config_t *conf, const char *filename); -bool mmss_read_config(mmss_t *mmss, mmss_config_t *conf, const char *filename); +void add_iface(gmrf_t *node, network_t *net, const char *name, const gmrf_addr_t *address); -void mmss_add_iface(gmrf_t *node, mmss_network_t *net, const char *name, const gmrf_addr_t *address); +uint64_t now(const context_t *mmss); -void mmss_dispatch(mmss_packet_t *packet); -void mmss_run_scheduled(mmss_scheduled_t *scheduled); +void dispatch(std::shared_ptr packet); +void run_scheduled(std::shared_ptr scheduled); -void mmss_logf(mmss_t *mmss, int priority, const char *format, ...); +void logf(context_t *mmss, int priority, const char *format, ...); static inline int max(int a, int b) { @@ -134,39 +111,31 @@ static inline size_t alignto(size_t l, size_t a) { return ((l+a-1)/a)*a; } -static inline mmss_string_stack_t* mmss_string_stack_dup(const char *str) { - mmss_string_stack_t *ret = reinterpret_cast(std::malloc(alignto(sizeof(mmss_string_stack_t) + strlen(str) + 1, 8))); - ret->next = NULL; - std::strcpy(ret->str, str); - - return ret; } -static inline mmss_string_stack_t* mmss_string_stack_dupn(const char *str, size_t len) { - size_t str_len = strnlen(str, len); - mmss_string_stack_t *ret = reinterpret_cast(std::malloc(alignto(sizeof(mmss_string_stack_t) + str_len + 1, 8))); - ret->next = NULL; - std::strncpy(ret->str, str, str_len); - ret->str[str_len] = 0; +struct gmrf { + gmrf_t *next; - return ret; -} + char *name; -static inline mmss_string_stack_t* mmss_string_stack_push(mmss_string_stack_t *stack, const char *str) { - mmss_string_stack_t *ret = reinterpret_cast(std::malloc(alignto(sizeof(mmss_string_stack_t) + strlen(str) + 1, 8))); - ret->next = stack; - std::strcpy(ret->str, str); + MMSS::context_t *mmss; + gmrf_context_t *ctx; + gmrf_iface_t *interfaces; - return ret; -} + unsigned rand_seed; -static inline void mmss_string_stack_free(mmss_string_stack_t *str) { - while(str) { - mmss_string_stack_t *next = str->next; - std::free(str); - str = next; - } -} + const MMSS::protocol_t *proto; +}; + +struct gmrf_iface { + gmrf_iface_t *node_next; + gmrf_iface_t *network_next; + char *name; + gmrf_addr_t address; + + gmrf_t *node; + MMSS::network_t *net; +}; -#endif /* _GMRF_MMSS_MMSS_H_ */ +#endif /* _GMRF_MMSS_MMSS_HPP_ */ diff --git a/mmss/protocol.cpp b/mmss/protocol.cpp index ace3560..f08d13e 100644 --- a/mmss/protocol.cpp +++ b/mmss/protocol.cpp @@ -30,7 +30,9 @@ #include -const mmss_protocol_t* mmss_load_protocol(const char *module) { +namespace MMSS { + +const protocol_t* load_protocol(const char *module) { void *handle = dlopen(module, RTLD_NOW); if (!handle) { fprintf(stderr, "unable to load protocol from `%s': %s\n", module, dlerror()); @@ -38,7 +40,7 @@ const mmss_protocol_t* mmss_load_protocol(const char *module) { } dlerror(); - const mmss_protocol_t *proto = reinterpret_cast(dlsym(handle, "mmss_protocol_info")); + const protocol_t *proto = reinterpret_cast(dlsym(handle, "mmss_protocol_info")); if (!proto) { fprintf(stderr, "unable to load protocol from `%s': %s\n", module, dlerror()); dlclose(handle); @@ -49,3 +51,5 @@ const mmss_protocol_t* mmss_load_protocol(const char *module) { return proto; } + +} diff --git a/mmss/queue.cpp b/mmss/queue.cpp deleted file mode 100644 index a5d2142..0000000 --- a/mmss/queue.cpp +++ /dev/null @@ -1,78 +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 "queue.hpp" -#include "mmss.hpp" - -#include - - -typedef struct mmss_queue_entry mmss_queue_entry_t; - -struct mmss_queue_entry { - mmss_queue_entry_t *next; - uint64_t timeout; - void *data; -}; - - -void mmss_queue_put(mmss_t *mmss, mmss_queue_t *queue, void *data, uint64_t timeout) { - while (*queue && timeout >= (*queue)->timeout) - queue = &(*queue)->next; - - mmss_queue_entry_t *entry = new mmss_queue_entry_t; - - entry->timeout = timeout; - entry->data = data; - - entry->next = *queue; - *queue = entry; -} - -void* mmss_queue_get(mmss_t *mmss, mmss_queue_t *queue) { - mmss_queue_entry_t *entry = *queue; - - if (!entry || entry->timeout > mmss->now) - return NULL; - - *queue = entry->next; - void *data = entry->data; - free(entry); - - return data; -} - -int mmss_queue_timeout(const mmss_t *mmss, const mmss_queue_t *const queue) { - if (!*queue) - return -1; - - int diff = (*queue)->timeout - mmss->now; - - if (diff < 0) - return 0; - else - return diff; -} diff --git a/mmss/queue.hpp b/mmss/queue.hpp index d24bff6..d3f8860 100644 --- a/mmss/queue.hpp +++ b/mmss/queue.hpp @@ -24,19 +24,61 @@ */ -#ifndef _GMRF_MMSS_QUEUE_H_ -#define _GMRF_MMSS_QUEUE_H_ +#ifndef _GMRF_MMSS_QUEUE_HPP_ +#define _GMRF_MMSS_QUEUE_HPP_ #include "types.hpp" -#include +#include +#include +namespace MMSS { -typedef struct mmss_queue_entry *mmss_queue_t; +template class timeout_queue_t { + struct element_t { + std::shared_ptr data; + uint64_t timeout; + element_t(std::shared_ptr data0, uint64_t timeout0) : data(data0), timeout(timeout0) {} -void mmss_queue_put(mmss_t *mmss, mmss_queue_t *queue, void *data, uint64_t timeout); -void* mmss_queue_get(mmss_t *mmss, mmss_queue_t *queue); -int mmss_queue_timeout(const mmss_t *mmss, const mmss_queue_t *const queue); + bool operator<(const element_t &e) const { + return timeout < e.timeout; + } + }; -#endif /* _GMRF_MMSS_QUEUE_H_ */ + context_t *mmss; + + std::priority_queue queue; + +public: + timeout_queue_t(context_t *mmss0) : mmss(mmss0) {} + + void put(std::shared_ptr data, uint64_t timeout) { + queue.push(element_t(data, timeout)); + } + + std::shared_ptr get() { + if (queue.empty() || queue.top().timeout > now(mmss)) + return std::shared_ptr(); + + std::shared_ptr ret = queue.top().data; + queue.pop(); + return ret; + } + + int timeout() const { + if (queue.empty()) + return -1; + + int diff = queue.top().timeout - now(mmss); + + if (diff < 0) + return 0; + else + return diff; + } +}; + +} + +#endif /* _GMRF_MMSS_QUEUE_HPP_ */ diff --git a/mmss/schedule.cpp b/mmss/schedule.cpp index adebf19..88de519 100644 --- a/mmss/schedule.cpp +++ b/mmss/schedule.cpp @@ -27,17 +27,20 @@ #include "mmss.hpp" +namespace MMSS { + +void run_scheduled(std::shared_ptr scheduled) { + scheduled->f(scheduled->node, scheduled->node->ctx, scheduled->arg); +} + +} + void gmrf_schedule(gmrf_t *gmrf, gmrf_scheduled_func f, void *arg, unsigned delay) { - mmss_scheduled_t *scheduled = new mmss_scheduled_t; + std::shared_ptr scheduled = std::make_shared(); scheduled->node = gmrf; scheduled->f = f; scheduled->arg = arg; - mmss_queue_put(gmrf->mmss, &gmrf->mmss->scheduled_queue, scheduled, gmrf->mmss->now+delay); -} - -void mmss_run_scheduled(mmss_scheduled_t *scheduled) { - scheduled->f(scheduled->node, scheduled->node->ctx, scheduled->arg); - delete scheduled; + gmrf->mmss->scheduled_queue.put(scheduled, gmrf->mmss->now+delay); } diff --git a/mmss/types.hpp b/mmss/types.hpp index 52ace0f..e8a63cc 100644 --- a/mmss/types.hpp +++ b/mmss/types.hpp @@ -24,19 +24,30 @@ */ -#ifndef _GMRF_MMSS_TYPES_H_ -#define _GMRF_MMSS_TYPES_H_ +#ifndef _GMRF_MMSS_TYPES_HPP_ +#define _GMRF_MMSS_TYPES_HPP_ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif -typedef struct mmss mmss_t; -typedef struct mmss_config mmss_config_t; -typedef struct mmss_network mmss_network_t; -typedef struct mmss_packet mmss_packet_t; -typedef struct mmss_scheduled mmss_scheduled_t; +extern "C" { -typedef struct mmss_string_stack mmss_string_stack_t; +#include +#include -#endif /* _GMRF_MMSS_TYPES_H_ */ +} + +namespace MMSS { + +class context_t; +class config_t; +class network_t; +class packet_t; +class scheduled_t; + +typedef ::mmss_protocol_t protocol_t; + +} + +#endif /* _GMRF_MMSS_TYPES_HPP_ */ -- cgit v1.2.3