From 4ec3cf030b9bfa6495dc19c7a5dda771ee5c66b0 Mon Sep 17 00:00:00 2001 From: Sonja Kolen Date: Thu, 28 Jun 2018 13:42:50 +0200 Subject: [PATCH 01/18] Added extern "C" wrapper in all headers of libvillas to use it in C++ code --- include/villas/advio.h | 8 +++ include/villas/api.h | 8 +++ include/villas/api/session.h | 8 +++ include/villas/atomic.h | 1 + include/villas/bitset.h | 10 +++- include/villas/buffer.h | 14 +++-- include/villas/common.h | 8 +++ include/villas/compat.h | 16 ++++++ include/villas/config.h | 69 ++++++++++++++++++++++++ include/villas/config.h.in | 11 ++++ include/villas/config_helper.h | 12 ++++- include/villas/crypt.h | 8 +++ include/villas/format_type.h | 8 +++ include/villas/formats/csv.h | 7 +++ include/villas/formats/json-reserve.h | 8 +++ include/villas/formats/json.h | 8 +++ include/villas/formats/msg.h | 8 +++ include/villas/formats/msg_format.h | 67 ++++++++++++----------- include/villas/formats/protobuf.h | 8 +++ include/villas/formats/raw.h | 29 ++++++---- include/villas/formats/villas_binary.h | 13 ++++- include/villas/formats/villas_human.h | 8 +++ include/villas/hist.h | 50 ++++++++++-------- include/villas/hook.h | 22 +++++--- include/villas/hook_type.h | 7 +++ include/villas/io.h | 22 +++++--- include/villas/kernel/if.h | 8 +++ include/villas/kernel/kernel.h | 10 +++- include/villas/kernel/nl-private.h | 63 +++++++++++----------- include/villas/kernel/nl.h | 10 +++- include/villas/kernel/rt.h | 8 +++ include/villas/kernel/tc.h | 8 +++ include/villas/kernel/tc_netem.h | 8 +++ include/villas/list.h | 8 +++ include/villas/log_config.h | 9 ++++ include/villas/mapping.h | 17 ++++-- include/villas/memory.h | 30 +++++++---- include/villas/node.h | 9 ++++ include/villas/node_type.h | 8 +++ include/villas/nodes/amqp.h | 10 +++- include/villas/nodes/cbuilder.h | 8 +++ include/villas/nodes/comedi.h | 52 ++++++++++-------- include/villas/nodes/file.h | 39 ++++++++------ include/villas/nodes/iec61850.h | 8 +++ include/villas/nodes/iec61850_sv.h | 8 +++ include/villas/nodes/influxdb.h | 10 +++- include/villas/nodes/loopback.h | 10 +++- include/villas/nodes/mqtt.h | 8 +++ include/villas/nodes/nanomsg.h | 10 +++- include/villas/nodes/ngsi.h | 32 ++++++----- include/villas/nodes/opal.h | 10 +++- include/villas/nodes/shmem.h | 20 ++++--- include/villas/nodes/signal_generator.h | 36 ++++++++----- include/villas/nodes/socket.h | 36 ++++++++----- include/villas/nodes/stats.h | 10 +++- include/villas/nodes/test_rtt.h | 26 +++++---- include/villas/nodes/websocket.h | 70 ++++++++++++++----------- include/villas/nodes/zeromq.h | 16 ++++-- include/villas/path.h | 50 ++++++++++-------- include/villas/plugin.h | 8 +++ include/villas/pool.h | 28 +++++----- include/villas/queue.h | 10 ++++ include/villas/queue_signalled.h | 8 +++ include/villas/sample.h | 10 ++-- include/villas/signal.h | 10 +++- include/villas/stats.h | 26 +++++---- include/villas/super_node.h | 38 ++++++++------ include/villas/table.h | 18 +++++-- include/villas/task.h | 29 ++++++---- include/villas/timing.h | 8 +++ include/villas/utils.h | 10 ++++ include/villas/web.h | 20 ++++--- 72 files changed, 977 insertions(+), 349 deletions(-) create mode 100644 include/villas/config.h diff --git a/include/villas/advio.h b/include/villas/advio.h index afbf3b14b..d9eb904cf 100644 --- a/include/villas/advio.h +++ b/include/villas/advio.h @@ -28,6 +28,10 @@ #include "crypt.h" +#ifdef __cplusplus +extern "C"{ +#endif + struct advio { CURL *curl; FILE *file; @@ -81,3 +85,7 @@ void arewind(AFILE *file); int adownload(AFILE *af, int resume); int aupload(AFILE *af, int resume); + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/api.h b/include/villas/api.h index b56627306..6a9a1a37b 100644 --- a/include/villas/api.h +++ b/include/villas/api.h @@ -33,6 +33,10 @@ #include "api/session.h" +#ifdef __cplusplus +extern "C"{ +#endif + /* Forward declarations */ struct lws; struct super_node; @@ -81,3 +85,7 @@ int api_stop(struct api *a); int api_ws_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); int api_http_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/api/session.h b/include/villas/api/session.h index 55835a8b4..65dfac659 100644 --- a/include/villas/api/session.h +++ b/include/villas/api/session.h @@ -30,6 +30,10 @@ #include #include +#ifdef __cplusplus +extern "C"{ +#endif + enum api_version { API_VERSION_UNKOWN = 0, API_VERSION_1 = 1 @@ -70,3 +74,7 @@ int api_session_destroy(struct api_session *s); int api_session_run_command(struct api_session *s, json_t *req, json_t **resp); char * api_session_name(struct api_session *s); + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/atomic.h b/include/villas/atomic.h index 0eba94d48..ea3a7f8a4 100644 --- a/include/villas/atomic.h +++ b/include/villas/atomic.h @@ -21,6 +21,7 @@ * along with this program. If not, see . *********************************************************************************/ + #include "common.h" #ifdef __cplusplus diff --git a/include/villas/bitset.h b/include/villas/bitset.h index 757774361..7e61147cd 100644 --- a/include/villas/bitset.h +++ b/include/villas/bitset.h @@ -26,6 +26,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + struct bitset { char *set; size_t dimension; @@ -62,4 +66,8 @@ int bitset_test(struct bitset *b, size_t bit); int bitset_cmp(struct bitset *a, struct bitset *b); /** Return an human readable representation of the bit set */ -char * bitset_dump(struct bitset *b); +char *bitset_dump(struct bitset *b); + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/buffer.h b/include/villas/buffer.h index 8899f5fb0..77f679d67 100644 --- a/include/villas/buffer.h +++ b/include/villas/buffer.h @@ -29,9 +29,13 @@ #include "common.h" +#ifdef __cplusplus +extern "C" { +#endif + struct buffer { enum state state; - + char *buf; size_t len; size_t size; @@ -40,11 +44,15 @@ struct buffer { int buffer_init(struct buffer *b, size_t size); int buffer_destroy(struct buffer *b); - + void buffer_clear(struct buffer *b); int buffer_append(struct buffer *b, const char *data, size_t len); int buffer_parse_json(struct buffer *b, json_t **j); -int buffer_append_json(struct buffer *b, json_t *j); \ No newline at end of file +int buffer_append_json(struct buffer *b, json_t *j); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/common.h b/include/villas/common.h index 41457b2e7..d6ac417a2 100644 --- a/include/villas/common.h +++ b/include/villas/common.h @@ -23,6 +23,10 @@ #pragma once +#ifdef __cplusplus +extern "C"{ +#endif + /* Common states for most objects in VILLASnode (paths, nodes, hooks, plugins) */ enum state { STATE_DESTROYED = 0, @@ -36,3 +40,7 @@ enum state { STATE_UNLOADED = 5, /* alias for STATE_STARTED used by struct plugin */ STATE_CLOSED = 5 /* alias for STATE_STARTED used by struct io */ }; + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/compat.h b/include/villas/compat.h index ad574fda2..c5a2275d5 100644 --- a/include/villas/compat.h +++ b/include/villas/compat.h @@ -22,13 +22,25 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + #if JANSSON_VERSION_HEX < 0x020A00 size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags); #endif +#ifdef __cplusplus +} +#endif + #ifdef __MACH__ #include + #ifdef __cplusplus + extern "C"{ + #endif + #define le16toh(x) OSSwapLittleToHostInt16(x) #define le32toh(x) OSSwapLittleToHostInt32(x) #define le64toh(x) OSSwapLittleToHostInt64(x) @@ -42,4 +54,8 @@ size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags); #define htobe16(x) OSSwapHostToBigInt16(x) #define htobe32(x) OSSwapHostToBigInt32(x) #define htobe64(x) OSSwapHostToBigInt64(x) + + #ifdef __cplusplus + } + #endif #endif /* __MACH__ */ diff --git a/include/villas/config.h b/include/villas/config.h new file mode 100644 index 000000000..082579cd8 --- /dev/null +++ b/include/villas/config.h @@ -0,0 +1,69 @@ +/** Static server configuration + * + * This file contains some compiled-in settings. + * This settings are not part of the configuration file. + * + * @file + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + + + +#pragma once + +#ifdef __cplusplus +extern "C"{ +#endif + +/* Paths */ +#define PLUGIN_PATH PREFIX "/share/villas/node/plugins" +#define WEB_PATH PREFIX "/share/villas/node/web" +#define SYSFS_PATH "/sys" +#define PROCFS_PATH "/proc" + +/** Default number of values in a sample */ +#define DEFAULT_SAMPLELEN 64 +#define DEFAULT_QUEUELEN 1024 + +/** Number of hugepages which are requested from the the kernel. + * @see https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt */ +#define DEFAULT_NR_HUGEPAGES 100 + +/** Width of log output in characters */ +#define LOG_WIDTH 80 +#define LOG_HEIGHT 25 + +/** Socket priority */ +#define SOCKET_PRIO 7 + +/* Protocol numbers */ +#define IPPROTO_VILLAS 137 +#define ETH_P_VILLAS 0xBABE + +#define USER_AGENT "VILLASnode (" BUILDID ")" + +/* Required kernel version */ +#define KERNEL_VERSION_MAJ 3 +#define KERNEL_VERSION_MIN 6 + + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/config.h.in b/include/villas/config.h.in index 68d56ee8c..082579cd8 100644 --- a/include/villas/config.h.in +++ b/include/villas/config.h.in @@ -24,8 +24,14 @@ * along with this program. If not, see . *********************************************************************************/ + + #pragma once +#ifdef __cplusplus +extern "C"{ +#endif + /* Paths */ #define PLUGIN_PATH PREFIX "/share/villas/node/plugins" #define WEB_PATH PREFIX "/share/villas/node/web" @@ -56,3 +62,8 @@ /* Required kernel version */ #define KERNEL_VERSION_MAJ 3 #define KERNEL_VERSION_MIN 6 + + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/config_helper.h b/include/villas/config_helper.h index 6be9afe4b..abed550f7 100644 --- a/include/villas/config_helper.h +++ b/include/villas/config_helper.h @@ -27,14 +27,18 @@ #include "sample.h" +#ifdef __cplusplus +extern "C" { +#endif + /* Convert a libconfig object to a jansson object */ -json_t * config_to_json(config_setting_t *cfg); +json_t *config_to_json(config_setting_t *cfg); /* Convert a jansson object into a libconfig object. */ int json_to_config(json_t *json, config_setting_t *parent); /* Create a JSON object from command line parameters. */ -json_t * json_load_cli(int argc, char *argv[]); +json_t *json_load_cli(int argc, char *argv[]); int json_object_extend_str(json_t *orig, const char *str); @@ -42,3 +46,7 @@ void json_object_extend_key_value(json_t *obj, const char *key, const char *valu /* Merge two JSON objects recursively. */ int json_object_extend(json_t *orig, json_t *merge); + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/crypt.h b/include/villas/crypt.h index 9b5c7843b..29b99410e 100644 --- a/include/villas/crypt.h +++ b/include/villas/crypt.h @@ -25,9 +25,17 @@ #include #include +#ifdef __cplusplus +extern "C"{ +#endif + /** Calculate SHA1 hash of complete file \p f and place it into \p sha1. * * @param sha1[out] Must be SHA_DIGEST_LENGTH (20) in size. * @retval 0 Everything was okay. */ int sha1sum(FILE *f, unsigned char *sha1); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/format_type.h b/include/villas/format_type.h index 805b930a3..d1a4a7cb5 100644 --- a/include/villas/format_type.h +++ b/include/villas/format_type.h @@ -25,6 +25,10 @@ #include +#ifdef __cplusplus +extern "C"{ +#endif + /* Forward declarations */ struct sample; struct io; @@ -104,3 +108,7 @@ struct format_type { }; struct format_type * format_type_lookup(const char *name); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/formats/csv.h b/include/villas/formats/csv.h index d32c93f52..f9f944131 100644 --- a/include/villas/formats/csv.h +++ b/include/villas/formats/csv.h @@ -25,6 +25,9 @@ #include +#ifdef __cplusplus +extern "C" { +#endif /* Forward declarations. */ struct sample; @@ -32,3 +35,7 @@ void csv_header(struct io *io); int csv_sscan(struct io *io, char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt); int csv_sprint(struct io *io, char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt); + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/formats/json-reserve.h b/include/villas/formats/json-reserve.h index 71280af59..c715bc659 100644 --- a/include/villas/formats/json-reserve.h +++ b/include/villas/formats/json-reserve.h @@ -24,6 +24,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct sample; struct io; @@ -33,3 +37,7 @@ int json_reserve_sscan(struct io *io, char *buf, size_t len, size_t *rbytes, str int json_reserve_print(struct io *io, struct sample *smps[], unsigned cnt); int json_reserve_scan(struct io *io, struct sample *smps[], unsigned cnt); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/formats/json.h b/include/villas/formats/json.h index 50fb60aee..ea73e0ff6 100644 --- a/include/villas/formats/json.h +++ b/include/villas/formats/json.h @@ -24,6 +24,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct sample; @@ -32,3 +36,7 @@ int json_sscan(struct io *io, char *buf, size_t len, size_t *wbytes, struct samp int json_print(struct io *io, struct sample *smps[], unsigned cnt); int json_scan(struct io *io, struct sample *smps[], unsigned cnt); + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/formats/msg.h b/include/villas/formats/msg.h index c10498c12..2d88ec92a 100644 --- a/include/villas/formats/msg.h +++ b/include/villas/formats/msg.h @@ -22,6 +22,10 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declaration */ struct msg; struct sample; @@ -53,3 +57,7 @@ int msg_to_sample(struct msg *msg, struct sample *smp); /** Copy fields form \p smp into \p msg. */ int msg_from_sample(struct msg *msg, struct sample *smp); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/formats/msg_format.h b/include/villas/formats/msg_format.h index 45930fae8..99069089a 100644 --- a/include/villas/formats/msg_format.h +++ b/include/villas/formats/msg_format.h @@ -25,68 +25,73 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /** The current version number for the message format */ -#define MSG_VERSION 2 +#define MSG_VERSION 2 /** @todo Implement more message types */ -#define MSG_TYPE_DATA 0 /**< Message contains float / integer values */ -#define MSG_TYPE_START 1 /**< Message marks the beginning of a new simulation case */ -#define MSG_TYPE_STOP 2 /**< Message marks the end of a simulation case */ +#define MSG_TYPE_DATA 0 /**< Message contains float / integer values */ +#define MSG_TYPE_START 1 /**< Message marks the beginning of a new simulation case */ +#define MSG_TYPE_STOP 2 /**< Message marks the end of a simulation case */ /** The total size in bytes of a message */ -#define MSG_LEN(values) (sizeof(struct msg) + MSG_DATA_LEN(values)) +#define MSG_LEN(values) (sizeof(struct msg) + MSG_DATA_LEN(values)) /** The length of \p values values in bytes. */ -#define MSG_DATA_LEN(values) (sizeof(float) * (values)) +#define MSG_DATA_LEN(values) (sizeof(float) * (values)) /** The offset to the first data value in a message. */ -#define MSG_DATA_OFFSET(msg) ((char *) (msg) + offsetof(struct msg, data)) +#define MSG_DATA_OFFSET(msg) ((char *) (msg) + offsetof(struct msg, data)) /** Initialize a message with default values */ #define MSG_INIT(len, seq) (struct msg) {\ - .version = MSG_VERSION, \ - .type = MSG_TYPE_DATA, \ - .length = len, \ - .sequence = seq, \ + .version = MSG_VERSION, \ + .type = MSG_TYPE_DATA, \ + .length = len, \ + .sequence = seq, \ } /** The timestamp of a message in struct timespec format */ -#define MSG_TS(msg) (struct timespec) { \ - .tv_sec = (msg)->ts.sec, \ - .tv_nsec = (msg)->ts.nsec \ +#define MSG_TS(msg) (struct timespec) { \ + .tv_sec = (msg)->ts.sec, \ + .tv_nsec = (msg)->ts.nsec \ } /** This message format is used by all clients * * @diafile msg_format.dia **/ -struct msg -{ +struct msg { #if BYTE_ORDER == BIG_ENDIAN - unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ - unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ - unsigned rsvd1 : 2; /**< Reserved bits */ + unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ + unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ + unsigned rsvd1 : 2; /**< Reserved bits */ #elif BYTE_ORDER == LITTLE_ENDIAN - unsigned rsvd1 : 2; /**< Reserved bits */ - unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ - unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ -#else - #error Invalid byte-order + unsigned rsvd1 : 2; /**< Reserved bits */ + unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ + unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ #endif - uint8_t resv2; /**< An id which identifies the source of this sample. */ - uint16_t length; /**< The number of values in msg::data[]. */ - uint32_t sequence; /**< The sequence number is incremented by one for consecutive messages. */ + uint8_t resv2; /**< An id which identifies the source of this sample. */ + uint16_t length; /**< The number of values in msg::data[]. */ + uint32_t sequence; /**< The sequence number is incremented by one for consecutive messages. */ /** A timestamp per message. */ struct { - uint32_t sec; /**< Seconds since 1970-01-01 00:00:00 */ - uint32_t nsec; /**< Nanoseconds of the current second. */ + uint32_t sec; /**< Seconds since 1970-01-01 00:00:00 */ + uint32_t nsec; /**< Nanoseconds of the current second. */ } ts; /** The message payload. */ union { - float f; /**< Floating point values. */ - uint32_t i; /**< Integer values. */ + float f; /**< Floating point values. */ + uint32_t i; /**< Integer values. */ } data[]; } __attribute__((packed)); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/formats/protobuf.h b/include/villas/formats/protobuf.h index 49f171555..343920189 100644 --- a/include/villas/formats/protobuf.h +++ b/include/villas/formats/protobuf.h @@ -25,6 +25,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct sample; @@ -33,3 +37,7 @@ int protobuf_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct /** Read struct sample's from buffer \p buf into samples \p smps. */ int protobuf_sscan(struct io *io, char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/formats/raw.h b/include/villas/formats/raw.h index 7d0b1e3b9..d10eea879 100644 --- a/include/villas/formats/raw.h +++ b/include/villas/formats/raw.h @@ -25,32 +25,36 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct sample; enum raw_flags { - RAW_FAKE = (1 << 16), /**< Treat the first three values as: sequenceno, seconds, nanoseconds */ + RAW_FAKE = (1 << 16), /**< Treat the first three values as: sequenceno, seconds, nanoseconds */ - RAW_BE_INT = (1 << 17), /**< Byte-order for integer data: big-endian if set. */ - RAW_BE_FLT = (1 << 18), /**< Byte-order for floating point data: big-endian if set. */ - RAW_BE_HDR = (1 << 19), /**< Byte-order for fake header fields: big-endian if set. */ + RAW_BE_INT = (1 << 17), /**< Byte-order for integer data: big-endian if set. */ + RAW_BE_FLT = (1 << 18), /**< Byte-order for floating point data: big-endian if set. */ + RAW_BE_HDR = (1 << 19), /**< Byte-order for fake header fields: big-endian if set. */ /** Byte-order for all fields: big-endian if set. */ - RAW_BE = RAW_BE_INT | RAW_BE_FLT | RAW_BE_HDR, + RAW_BE = RAW_BE_INT | RAW_BE_FLT | RAW_BE_HDR, /** Mix floating and integer types. * * io_raw_sscan() parses all values as single / double precission fp. * io_raw_sprint() uses sample::format to determine the type. */ - RAW_AUTO = (1 << 22), - RAW_FLT = (1 << 23), /**< Data-type: floating point otherwise integer. */ + RAW_AUTO = (1 << 22), + RAW_FLT = (1 << 23), /**< Data-type: floating point otherwise integer. */ //RAW_1 = (0 << 24), /**< Pack each value as a single bit. */ - RAW_8 = (3 << 24), /**< Pack each value as a byte. */ - RAW_16 = (4 << 24), /**< Pack each value as a word. */ - RAW_32 = (5 << 24), /**< Pack each value as a double word. */ - RAW_64 = (6 << 24) /**< Pack each value as a quad word. */ + RAW_8 = (3 << 24), /**< Pack each value as a byte. */ + RAW_16 = (4 << 24), /**< Pack each value as a word. */ + RAW_32 = (5 << 24), /**< Pack each value as a double word. */ + RAW_64 = (6 << 24) /**< Pack each value as a quad word. */ }; /** Copy / read struct msg's from buffer \p buf to / fram samples \p smps. */ @@ -58,3 +62,6 @@ int raw_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct samp /** Read struct sample's from buffer \p buf into samples \p smps. */ int raw_sscan(struct io *io, char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt); +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/formats/villas_binary.h b/include/villas/formats/villas_binary.h index 79dd248e4..ff520919f 100644 --- a/include/villas/formats/villas_binary.h +++ b/include/villas/formats/villas_binary.h @@ -25,17 +25,26 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations. */ struct sample; struct msg; struct io; enum villas_binary_flags { - VILLAS_BINARY_WEB = (1 << 16) /**< Use webmsg format (everying little endian) */ + VILLAS_BINARY_WEB = (1 << 16) /**< Use webmsg format (everying little endian) */ }; /** Copy / read struct msg's from buffer \p buf to / fram samples \p smps. */ -int villas_binary_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct sample *smps[], unsigned cnt); +int +villas_binary_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct sample *smps[], unsigned cnt); /** Read struct sample's from buffer \p buf into samples \p smps. */ int villas_binary_sscan(struct io *io, char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt); + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/formats/villas_human.h b/include/villas/formats/villas_human.h index 01ced6032..c372b14ef 100644 --- a/include/villas/formats/villas_human.h +++ b/include/villas/formats/villas_human.h @@ -25,6 +25,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct io; struct sample; @@ -33,3 +37,7 @@ void villas_human_header(struct io *io); int villas_human_print(struct io *io, struct sample *smps[], unsigned cnt); int villas_human_scan(struct io *io, struct sample *smps[], unsigned cnt); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/hist.h b/include/villas/hist.h index 935908576..ca8a4d10a 100644 --- a/include/villas/hist.h +++ b/include/villas/hist.h @@ -28,39 +28,43 @@ #include -#define HIST_HEIGHT (LOG_WIDTH - 55) -#define HIST_SEQ 17 +#ifdef __cplusplus +extern "C" { +#endif + +#define HIST_HEIGHT (LOG_WIDTH - 55) +#define HIST_SEQ 17 typedef uintmax_t hist_cnt_t; /** Histogram structure used to collect statistics. */ struct hist { - double resolution; /**< The distance between two adjacent buckets. */ + double resolution; /**< The distance between two adjacent buckets. */ - double high; /**< The value of the highest bucket. */ - double low; /**< The value of the lowest bucket. */ + double high; /**< The value of the highest bucket. */ + double low; /**< The value of the lowest bucket. */ - double highest; /**< The highest value observed (may be higher than #high). */ - double lowest; /**< The lowest value observed (may be lower than #low). */ - double last; /**< The last value which has been put into the buckets */ + double highest; /**< The highest value observed (may be higher than #high). */ + double lowest; /**< The lowest value observed (may be lower than #low). */ + double last; /**< The last value which has been put into the buckets */ - int length; /**< The number of buckets in #data. */ + int length; /**< The number of buckets in #data. */ - hist_cnt_t total; /**< Total number of counted values. */ - hist_cnt_t warmup; /**< Number of values which are used during warmup phase. */ + hist_cnt_t total; /**< Total number of counted values. */ + hist_cnt_t warmup; /**< Number of values which are used during warmup phase. */ - hist_cnt_t higher; /**< The number of values which are higher than #high. */ - hist_cnt_t lower; /**< The number of values which are lower than #low. */ + hist_cnt_t higher; /**< The number of values which are higher than #high. */ + hist_cnt_t lower; /**< The number of values which are lower than #low. */ - hist_cnt_t *data; /**< Pointer to dynamically allocated array of size length. */ + hist_cnt_t *data; /**< Pointer to dynamically allocated array of size length. */ - double _m[2], _s[2]; /**< Private variables for online variance calculation */ + double _m[2], _s[2]; /**< Private variables for online variance calculation */ }; -#define hist_last(h) ((h)->last) -#define hist_highest(h) ((h)->highest) -#define hist_lowest(h) ((h)->lowest) -#define hist_total(h) ((h)->total) +#define hist_last(h) ((h)->last) +#define hist_highest(h) ((h)->highest) +#define hist_lowest(h) ((h)->lowest) +#define hist_total(h) ((h)->total) /** Initialize struct hist with supplied values and allocate memory for buckets. */ int hist_init(struct hist *h, int buckets, hist_cnt_t warmup); @@ -93,7 +97,7 @@ void hist_plot(struct hist *h); * * @return The string containing the dump. The caller is responsible to free() the buffer. */ -char * hist_dump(struct hist *h); +char *hist_dump(struct hist *h); /** Prints Matlab struct containing all infos to file. */ int hist_dump_matlab(struct hist *h, FILE *f); @@ -102,4 +106,8 @@ int hist_dump_matlab(struct hist *h, FILE *f); int hist_dump_json(struct hist *h, FILE *f); /** Build a libjansson / JSON object of the histogram. */ -json_t * hist_json(struct hist *h); +json_t *hist_json(struct hist *h); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/hook.h b/include/villas/hook.h index eadd4c281..66ec85e8d 100644 --- a/include/villas/hook.h +++ b/include/villas/hook.h @@ -37,6 +37,10 @@ #include "hook_type.h" #include "common.h" +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct path; struct sample; @@ -44,17 +48,17 @@ struct list; /** Descriptor for user defined hooks. See hooks[]. */ struct hook { - enum state state; + enum state state; - struct path *path; - struct node *node; + struct path *path; + struct node *node; - struct hook_type *_vt; /**< C++ like Vtable pointer. */ - void *_vd; /**< Private data for this hook. This pointer can be used to pass data between consecutive calls of the callback. */ + struct hook_type *_vt; /**< C++ like Vtable pointer. */ + void *_vd; /**< Private data for this hook. This pointer can be used to pass data between consecutive calls of the callback. */ - int priority; /**< A priority to change the order of execution within one type of hook. */ + int priority; /**< A priority to change the order of execution within one type of hook. */ - json_t *cfg; /**< A JSON object containing the configuration of the hook. */ + json_t *cfg; /**< A JSON object containing the configuration of the hook. */ }; int hook_init(struct hook *h, struct hook_type *vt, struct path *p, struct node *n); @@ -96,3 +100,7 @@ int hook_cmp_priority(const void *a, const void *b); * } */ int hook_parse_list(struct list *list, json_t *cfg, struct path *p, struct node *n); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/hook_type.h b/include/villas/hook_type.h index 6c6d7ec70..de1331a2e 100644 --- a/include/villas/hook_type.h +++ b/include/villas/hook_type.h @@ -39,6 +39,10 @@ #include +#ifdef __cplusplus +extern "C"{ +#endif + /* Forward declarations */ struct hook; struct sample; @@ -74,3 +78,6 @@ struct hook_type { struct hook_type * hook_type_lookup(const char *name); +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/io.h b/include/villas/io.h index d24705a61..b471a0764 100644 --- a/include/villas/io.h +++ b/include/villas/io.h @@ -27,21 +27,25 @@ #include "common.h" #include "node.h" +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct sample; struct format_type; enum io_flags { - IO_FLUSH = (1 << 8), /**< Flush the output stream after each chunk of samples. */ - IO_NONBLOCK = (1 << 9), /**< Dont block io_read() while waiting for new samples. */ - IO_NEWLINES = (1 << 10) /**< The samples of this format are newline delimited. */ + IO_FLUSH = (1 << 8), /**< Flush the output stream after each chunk of samples. */ + IO_NONBLOCK = (1 << 9), /**< Dont block io_read() while waiting for new samples. */ + IO_NEWLINES = (1 << 10) /**< The samples of this format are newline delimited. */ }; struct io { enum state state; int flags; - char delimiter; /**< Newline delimiter. */ - char separator; /**< Column separator (used by csv and villas.human formats only) */ + char delimiter; /**< Newline delimiter. */ + char separator; /**< Column separator (used by csv and villas.human formats only) */ struct { /** A format type can use this file handle or overwrite the @@ -106,8 +110,8 @@ int io_stream_fd(struct io *io); int io_stream_flush(struct io *io); -FILE * io_stream_input(struct io *io); -FILE * io_stream_output(struct io *io); +FILE *io_stream_input(struct io *io); +FILE *io_stream_output(struct io *io); /** Parse samples from the buffer \p buf with a length of \p len bytes. * @@ -134,3 +138,7 @@ int io_sscan(struct io *io, char *buf, size_t len, size_t *rbytes, struct sample * @retval <0 Something went wrong. */ int io_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct sample *smps[], unsigned cnt); + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/kernel/if.h b/include/villas/kernel/if.h index 4a6068ad5..1d6420098 100644 --- a/include/villas/kernel/if.h +++ b/include/villas/kernel/if.h @@ -33,6 +33,10 @@ #include +#ifdef __cplusplus +extern "C"{ +#endif + #define IF_IRQ_MAX 3 /**< Maxmimal number of IRQs of an interface */ #ifndef SO_MARK @@ -121,4 +125,8 @@ int if_get_irqs(struct interface *i); */ int if_set_affinity(struct interface *i, int affinity); + +#ifdef __cplusplus +} +#endif /** @} */ diff --git a/include/villas/kernel/kernel.h b/include/villas/kernel/kernel.h index 6b39dc40c..60ceb4312 100644 --- a/include/villas/kernel/kernel.h +++ b/include/villas/kernel/kernel.h @@ -28,6 +28,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct version; @@ -85,6 +89,10 @@ int kernel_get_page_size(); int kernel_get_hugepage_size(); /** Set SMP affinity of IRQ */ -int kernel_irq_setaffinity(unsigned irq, uintmax_t new, uintmax_t *old); +int kernel_irq_setaffinity(unsigned irq, uintmax_t new , uintmax_t *old ) ; + +#ifdef __cplusplus +} +#endif /** @} */ diff --git a/include/villas/kernel/nl-private.h b/include/villas/kernel/nl-private.h index 968cdb209..f67051dc7 100644 --- a/include/villas/kernel/nl-private.h +++ b/include/villas/kernel/nl-private.h @@ -1,45 +1,48 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + #define SCH_NETEM_ATTR_DIST 0x2000 -struct rtnl_netem_corr -{ - uint32_t nmc_delay; - uint32_t nmc_loss; - uint32_t nmc_duplicate; +struct rtnl_netem_corr { + uint32_t nmc_delay; + uint32_t nmc_loss; + uint32_t nmc_duplicate; }; -struct rtnl_netem_reo -{ - uint32_t nmro_probability; - uint32_t nmro_correlation; +struct rtnl_netem_reo { + uint32_t nmro_probability; + uint32_t nmro_correlation; }; -struct rtnl_netem_crpt -{ - uint32_t nmcr_probability; - uint32_t nmcr_correlation; +struct rtnl_netem_crpt { + uint32_t nmcr_probability; + uint32_t nmcr_correlation; }; -struct rtnl_netem_dist -{ - int16_t * dist_data; - size_t dist_size; +struct rtnl_netem_dist { + int16_t *dist_data; + size_t dist_size; }; -struct rtnl_netem -{ - uint32_t qnm_latency; - uint32_t qnm_limit; - uint32_t qnm_loss; - uint32_t qnm_gap; - uint32_t qnm_duplicate; - uint32_t qnm_jitter; - uint32_t qnm_mask; - struct rtnl_netem_corr qnm_corr; - struct rtnl_netem_reo qnm_ro; - struct rtnl_netem_crpt qnm_crpt; - struct rtnl_netem_dist qnm_dist; +struct rtnl_netem { + uint32_t qnm_latency; + uint32_t qnm_limit; + uint32_t qnm_loss; + uint32_t qnm_gap; + uint32_t qnm_duplicate; + uint32_t qnm_jitter; + uint32_t qnm_mask; + struct rtnl_netem_corr qnm_corr; + struct rtnl_netem_reo qnm_ro; + struct rtnl_netem_crpt qnm_crpt; + struct rtnl_netem_dist qnm_dist; }; void *rtnl_tc_data(struct rtnl_tc *tc); + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/kernel/nl.h b/include/villas/kernel/nl.h index 879312cd9..894df4f9f 100644 --- a/include/villas/kernel/nl.h +++ b/include/villas/kernel/nl.h @@ -29,6 +29,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** Get index of outgoing interface for given destination address. * * @retval >=0 Interface index of outgoing interface. @@ -37,9 +41,13 @@ int nl_get_egress(struct nl_addr *addr); /** Get or create global netlink socket. */ -struct nl_sock * nl_init(); +struct nl_sock *nl_init(); /** Close and free global netlink socket. */ void nl_shutdown(); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/kernel/rt.h b/include/villas/kernel/rt.h index f1c8b5bc6..c6c5c0e9b 100644 --- a/include/villas/kernel/rt.h +++ b/include/villas/kernel/rt.h @@ -26,6 +26,10 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + int rt_init(int priority, int affinity); int rt_set_affinity(int affinity); @@ -43,4 +47,8 @@ int rt_lock_memory(); */ int rt_is_preemptible(); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/kernel/tc.h b/include/villas/kernel/tc.h index a64439be8..0b5afbbc3 100644 --- a/include/villas/kernel/tc.h +++ b/include/villas/kernel/tc.h @@ -37,6 +37,10 @@ #include +#ifdef __cplusplus +extern "C"{ +#endif + typedef uint32_t tc_hdl_t; struct interface; @@ -72,4 +76,8 @@ int tc_prio(struct interface *i, struct rtnl_qdisc **qd, tc_hdl_t handle, tc_hdl */ int tc_mark(struct interface *i, struct rtnl_cls **cls, tc_hdl_t flowid, uint32_t mark); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/kernel/tc_netem.h b/include/villas/kernel/tc_netem.h index 78dc10951..b6d0a86c4 100644 --- a/include/villas/kernel/tc_netem.h +++ b/include/villas/kernel/tc_netem.h @@ -37,6 +37,10 @@ #include +#ifdef __cplusplus +extern "C"{ +#endif + typedef uint32_t tc_hdl_t; struct interface; @@ -70,4 +74,8 @@ int tc_netem(struct interface *i, struct rtnl_qdisc **qd, tc_hdl_t handle, tc_hd int tc_netem_set_delay_distribution(struct rtnl_qdisc *qdisc, json_t *json); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/list.h b/include/villas/list.h index f3dd82bc8..e1d796628 100644 --- a/include/villas/list.h +++ b/include/villas/list.h @@ -19,6 +19,10 @@ #include "common.h" +#ifdef __cplusplus +extern "C"{ +#endif + #define LIST_CHUNKSIZE 16 /** Static list initialization */ @@ -120,3 +124,7 @@ int list_set(struct list *l, int index, void *value); * @retval >=0 Entry \p value was found at returned index. */ ssize_t list_index(struct list *l, void *value); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/log_config.h b/include/villas/log_config.h index 86c2281ba..d7322fd0a 100644 --- a/include/villas/log_config.h +++ b/include/villas/log_config.h @@ -29,9 +29,18 @@ struct log; #include "log.h" +#ifdef __cplusplus +extern "C"{ +#endif + /** Parse logging configuration. */ int log_parse(struct log *l, json_t *cfg); /** Print configuration error and exit. */ void jerror(json_error_t *err, const char *fmt, ...) __attribute__ ((format(printf, 2, 3))); + + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/mapping.h b/include/villas/mapping.h index 498d0e455..af26b3918 100644 --- a/include/villas/mapping.h +++ b/include/villas/mapping.h @@ -29,6 +29,10 @@ #include "common.h" #include "list.h" +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct stats; struct node; @@ -38,8 +42,8 @@ struct list; struct mapping_entry { struct node *node; - int offset; /**< Offset of this mapping entry within sample::data */ - int length; /**< The number of values which is covered by this mapping entry. */ + int offset; /**< Offset of this mapping entry within sample::data */ + int length; /**< The number of values which is covered by this mapping entry. */ enum { MAPPING_TYPE_DATA, @@ -84,12 +88,17 @@ struct mapping_entry { }; }; -int mapping_remap(struct list *m, struct sample *remapped, struct sample *original, struct stats *s); +int +mapping_remap(struct list *m, struct sample *remapped, struct sample *original, struct stats *s); -int mapping_update(struct mapping_entry *e, struct sample *remapped, struct sample *new, struct stats *s); +int mapping_update(struct mapping_entry *e, struct sample *remapped, struct sample * new , struct stats *s ) ; int mapping_parse(struct mapping_entry *e, json_t *cfg, struct list *nodes); int mapping_parse_str(struct mapping_entry *e, const char *str, struct list *nodes); int mapping_parse_list(struct list *l, json_t *cfg, struct list *nodes); + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/memory.h b/include/villas/memory.h index 9514d748d..a680b65ff 100644 --- a/include/villas/memory.h +++ b/include/villas/memory.h @@ -26,7 +26,11 @@ #pragma once -#define HUGEPAGESIZE (1 << 21) +#ifdef __cplusplus +extern "C" { +#endif + +#define HUGEPAGESIZE (1 << 21) struct memtype; @@ -34,10 +38,10 @@ typedef void *(*memzone_allocator_t)(struct memtype *mem, size_t len, size_t ali typedef int (*memzone_deallocator_t)(struct memtype *mem, void *ptr, size_t len); enum memtype_flags { - MEMORY_MMAP = (1 << 0), - MEMORY_DMA = (1 << 1), - MEMORY_HUGEPAGE = (1 << 2), - MEMORY_HEAP = (1 << 3) + MEMORY_MMAP = (1 << 0), + MEMORY_DMA = (1 << 1), + MEMORY_HUGEPAGE = (1 << 2), + MEMORY_HEAP = (1 << 3) }; struct memtype { @@ -59,15 +63,15 @@ enum memblock_flags { /** Descriptor of a memory block. Associated block always starts at * &m + sizeof(struct memblock). */ struct memblock { - struct memblock* prev; - struct memblock* next; + struct memblock *prev; + struct memblock *next; size_t len; /**0 If allocation was successful. */ -void * memory_alloc(struct memtype *m, size_t len); +void *memory_alloc(struct memtype *m, size_t len); -void * memory_alloc_aligned(struct memtype *m, size_t len, size_t alignment); +void *memory_alloc_aligned(struct memtype *m, size_t len, size_t alignment); int memory_free(struct memtype *m, void *ptr, size_t len); -struct memtype * memtype_managed_init(void *ptr, size_t len); +struct memtype *memtype_managed_init(void *ptr, size_t len); extern struct memtype memtype_heap; extern struct memtype memtype_hugepage; + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/node.h b/include/villas/node.h index 06c0dcc09..8ec6f7523 100644 --- a/include/villas/node.h +++ b/include/villas/node.h @@ -26,6 +26,7 @@ * @{ */ + #pragma once #include @@ -38,6 +39,10 @@ #include "queue.h" #include "common.h" +#ifdef __cplusplus +extern "C"{ +#endif + struct node_direction { int enabled; int builtin; /**< This node should use built-in hooks by default. */ @@ -158,4 +163,8 @@ int node_write(struct node *n, struct sample *smps[], unsigned cnt); int node_fd(struct node *n); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/node_type.h b/include/villas/node_type.h index 5e6a47d4f..dcee596d0 100644 --- a/include/villas/node_type.h +++ b/include/villas/node_type.h @@ -24,6 +24,10 @@ * @{ *********************************************************************************/ +#ifdef __cplusplus +extern "C"{ +#endif + #pragma once #include @@ -168,4 +172,8 @@ const char * node_type_name(struct node_type *vt); struct node_type * node_type_lookup(const char *name); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/amqp.h b/include/villas/nodes/amqp.h index e23154108..aa453ec75 100644 --- a/include/villas/nodes/amqp.h +++ b/include/villas/nodes/amqp.h @@ -35,6 +35,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct format_type; @@ -64,7 +68,7 @@ struct amqp { }; /** @see node_type::print */ -char * amqp_print(struct node *n); +char *amqp_print(struct node *n); /** @see node_type::parse */ int amqp_parse(struct node *n, json_t *json); @@ -81,4 +85,8 @@ int amqp_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int amqp_write(struct node *n, struct sample *smps[], unsigned cnt); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/cbuilder.h b/include/villas/nodes/cbuilder.h index c90e73db1..2513fb94e 100644 --- a/include/villas/nodes/cbuilder.h +++ b/include/villas/nodes/cbuilder.h @@ -33,6 +33,10 @@ #include +#ifdef __cplusplus +extern "C"{ +#endif + /* Forward declaration */ struct cbuilder; @@ -65,4 +69,8 @@ struct cbuilder { int eventfd; /**< Eventfd for synchronizing cbuilder_read() / cbuilder_write() access. */ }; +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/comedi.h b/include/villas/nodes/comedi.h index 311874ca6..6cc282b64 100644 --- a/include/villas/nodes/comedi.h +++ b/include/villas/nodes/comedi.h @@ -35,6 +35,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + // whether to use read() or mmap() kernel interface #define COMEDI_USE_READ (1) //#define COMEDI_USE_READ (0) @@ -45,23 +49,23 @@ struct comedi_chanspec { }; struct comedi_direction { - int subdevice; ///< Comedi subdevice - int buffer_size; ///< Comedi's kernel buffer size in kB - int sample_size; ///< Size of a single measurement sample - int sample_rate_hz; ///< Sample rate in Hz - bool present; ///< Config present - bool enabled; ///< Card is started successfully - bool running; ///< Card is actively transfering samples - struct timespec started; ///< Timestamp when sampling started - struct timespec last_debug; ///< Timestamp of last debug output - size_t counter; ///< Number of villas samples transfered - struct comedi_chanspec *chanspecs; ///< Range and maxdata config of channels - unsigned *chanlist; ///< Channel list in comedi's packed format - size_t chanlist_len; ///< Number of channels for this direction + int subdevice; ///< Comedi subdevice + int buffer_size; ///< Comedi's kernel buffer size in kB + int sample_size; ///< Size of a single measurement sample + int sample_rate_hz; ///< Sample rate in Hz + bool present; ///< Config present + bool enabled; ///< Card is started successfully + bool running; ///< Card is actively transfering samples + struct timespec started; ///< Timestamp when sampling started + struct timespec last_debug; ///< Timestamp of last debug output + size_t counter; ///< Number of villas samples transfered + struct comedi_chanspec *chanspecs; ///< Range and maxdata config of channels + unsigned *chanlist; ///< Channel list in comedi's packed format + size_t chanlist_len; ///< Number of channels for this direction - char* buffer; - char* bufptr; + char *buffer; + char *bufptr; }; struct comedi { @@ -70,19 +74,19 @@ struct comedi { comedi_t *dev; #if COMEDI_USE_READ - char* buf; - char* bufptr; + char *buf; + char *bufptr; #else - char *map; - size_t bufpos; - size_t front; - size_t back; + char *map; + size_t bufpos; + size_t front; + size_t back; #endif }; /** @see node_type::print */ -char * comedi_print(struct node *n); +char *comedi_print(struct node *n); /** @see node_type::parse */ int comedi_parse(struct node *n, json_t *cfg); @@ -99,4 +103,8 @@ int comedi_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int comedi_write(struct node *n, struct sample *smps[], unsigned cnt); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/file.h b/include/villas/nodes/file.h index da105b0b8..aa13409f8 100644 --- a/include/villas/nodes/file.h +++ b/include/villas/nodes/file.h @@ -33,19 +33,23 @@ #include #include -#define FILE_MAX_PATHLEN 512 +#ifdef __cplusplus +extern "C" { +#endif + +#define FILE_MAX_PATHLEN 512 struct file { - struct io io; /**< Format and file IO */ + struct io io; /**< Format and file IO */ struct format_type *format; - char *uri_tmpl; /**< Format string for file name. */ - char *uri; /**< Real file name. */ - char *mode; /**< File access mode. */ + char *uri_tmpl; /**< Format string for file name. */ + char *uri; /**< Real file name. */ + char *mode; /**< File access mode. */ - int flush; /**< Flush / upload file contents after each write. */ - struct task task; /**< Timer file descriptor. Blocks until 1 / rate seconds are elapsed. */ - double rate; /**< The read rate. */ + int flush; /**< Flush / upload file contents after each write. */ + struct task task; /**< Timer file descriptor. Blocks until 1 / rate seconds are elapsed. */ + double rate; /**< The read rate. */ enum epoch_mode { FILE_EPOCH_DIRECT, @@ -53,21 +57,21 @@ struct file { FILE_EPOCH_RELATIVE, FILE_EPOCH_ABSOLUTE, FILE_EPOCH_ORIGINAL - } epoch_mode; /**< Specifies how file::offset is calculated. */ + } epoch_mode; /**< Specifies how file::offset is calculated. */ enum { - FILE_EOF_EXIT, /**< Terminate when EOF is reached. */ - FILE_EOF_REWIND, /**< Rewind the file when EOF is reached. */ - FILE_EOF_WAIT /**< Blocking wait when EOF is reached. */ + FILE_EOF_EXIT, /**< Terminate when EOF is reached. */ + FILE_EOF_REWIND, /**< Rewind the file when EOF is reached. */ + FILE_EOF_WAIT /**< Blocking wait when EOF is reached. */ } eof; - struct timespec first; /**< The first timestamp in the file file::{read,write}::uri */ - struct timespec epoch; /**< The epoch timestamp from the configuration. */ - struct timespec offset; /**< An offset between the timestamp in the input file and the current time */ + struct timespec first; /**< The first timestamp in the file file::{read,write}::uri */ + struct timespec epoch; /**< The epoch timestamp from the configuration. */ + struct timespec offset; /**< An offset between the timestamp in the input file and the current time */ }; /** @see node_type::print */ -char * file_print(struct node *n); +char *file_print(struct node *n); /** @see node_type::parse */ int file_parse(struct node *n, json_t *cfg); @@ -84,4 +88,7 @@ int file_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int file_write(struct node *n, struct sample *smps[], unsigned cnt); +#ifdef __cplusplus +} +#endif /** @} */ diff --git a/include/villas/nodes/iec61850.h b/include/villas/nodes/iec61850.h index 7dd31e4c2..9f7944b4b 100644 --- a/include/villas/nodes/iec61850.h +++ b/include/villas/nodes/iec61850.h @@ -38,6 +38,10 @@ #include #include +#ifdef __cplusplus +extern "C"{ +#endif + enum iec61850_type { /* According to IEC 61850-7-2 */ IEC61850_TYPE_BOOLEAN, @@ -107,4 +111,8 @@ int iec61850_receiver_stop(struct iec61850_receiver *r); int iec61850_receiver_destroy(struct iec61850_receiver *r); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/iec61850_sv.h b/include/villas/nodes/iec61850_sv.h index 8b43644e1..7213c20fb 100644 --- a/include/villas/nodes/iec61850_sv.h +++ b/include/villas/nodes/iec61850_sv.h @@ -40,6 +40,10 @@ #include #include +#ifdef __cplusplus +extern "C"{ +#endif + struct iec61850_sv { char *interface; int app_id; @@ -97,4 +101,8 @@ int iec61850_sv_write(struct node *n, struct sample *smps[], unsigned cnt); int iec61850_sv_fd(struct node *n); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/influxdb.h b/include/villas/nodes/influxdb.h index 919725b55..7eb4ea9b2 100644 --- a/include/villas/nodes/influxdb.h +++ b/include/villas/nodes/influxdb.h @@ -31,6 +31,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct node; struct sample; @@ -49,7 +53,7 @@ struct influxdb { }; /** @see node_type::print */ -char * influxdb_print(struct node *n); +char *influxdb_print(struct node *n); /** @see node_type::parse */ int influxdb_parse(struct node *n, json_t *cfg); @@ -63,4 +67,8 @@ int influxdb_close(struct node *n); /** @see node_type::write */ int influxdb_write(struct node *n, struct sample *smps[], unsigned cnt); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/loopback.h b/include/villas/nodes/loopback.h index cfbb5d33a..4560928c8 100644 --- a/include/villas/nodes/loopback.h +++ b/include/villas/nodes/loopback.h @@ -32,6 +32,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct node; struct sample; @@ -47,7 +51,7 @@ struct loopback { }; /** @see node_type::print */ -char * loopback_print(struct node *n); +char *loopback_print(struct node *n); /** @see node_type::parse */ int loopback_parse(struct node *n, json_t *cfg); @@ -64,4 +68,8 @@ int loopback_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int loopback_write(struct node *n, struct sample *smps[], unsigned cnt); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/mqtt.h b/include/villas/nodes/mqtt.h index 22d12dd61..40713c8b2 100644 --- a/include/villas/nodes/mqtt.h +++ b/include/villas/nodes/mqtt.h @@ -34,6 +34,10 @@ #include #include +#ifdef __cplusplus +extern "C"{ +#endif + /* Forward declarations */ struct format_type; struct mosquitto; @@ -96,4 +100,8 @@ int mqtt_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int mqtt_write(struct node *n, struct sample *smps[], unsigned cnt); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/nanomsg.h b/include/villas/nodes/nanomsg.h index 81feb12bf..e2c775d6a 100644 --- a/include/villas/nodes/nanomsg.h +++ b/include/villas/nodes/nanomsg.h @@ -33,6 +33,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** The maximum length of a packet which contains stuct msg. */ #define NANOMSG_MAX_PACKET_LEN 1500 @@ -55,7 +59,7 @@ struct nanomsg { }; /** @see node_type::print */ -char * nanomsg_print(struct node *n); +char *nanomsg_print(struct node *n); /** @see node_type::parse */ int nanomsg_parse(struct node *n, json_t *cfg); @@ -72,4 +76,8 @@ int nanomsg_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int nanomsg_write(struct node *n, struct sample *smps[], unsigned cnt); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/ngsi.h b/include/villas/nodes/ngsi.h index 67c9bc766..486d3f3e4 100644 --- a/include/villas/nodes/ngsi.h +++ b/include/villas/nodes/ngsi.h @@ -43,25 +43,29 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + struct node; struct ngsi { - const char *endpoint; /**< The NGSI context broker endpoint URL. */ - const char *entity_id; /**< The context broker entity id related to this node */ - const char *entity_type; /**< The type of the entity */ - const char *access_token; /**< An optional authentication token which will be sent as HTTP header. */ + const char *endpoint; /**< The NGSI context broker endpoint URL. */ + const char *entity_id; /**< The context broker entity id related to this node */ + const char *entity_type; /**< The type of the entity */ + const char *access_token; /**< An optional authentication token which will be sent as HTTP header. */ - double timeout; /**< HTTP timeout in seconds */ - double rate; /**< Rate used for polling. */ + double timeout; /**< HTTP timeout in seconds */ + double rate; /**< Rate used for polling. */ - struct task task; /**< Timer for periodic events. */ - int ssl_verify; /**< Boolean flag whether SSL server certificates should be verified or not. */ + struct task task; /**< Timer for periodic events. */ + int ssl_verify; /**< Boolean flag whether SSL server certificates should be verified or not. */ - struct curl_slist *headers; /**< List of HTTP request headers for libcurl */ + struct curl_slist *headers; /**< List of HTTP request headers for libcurl */ - CURL *curl; /**< libcurl: handle */ + CURL *curl; /**< libcurl: handle */ - struct list mapping; /**< A mapping between indices of the VILLASnode samples and the attributes in ngsi::context */ + struct list mapping; /**< A mapping between indices of the VILLASnode samples and the attributes in ngsi::context */ }; /** Initialize global NGSI settings and maps shared memory regions. @@ -80,7 +84,7 @@ int ngsi_deinit(); int ngsi_parse(struct node *n, json_t *cfg); /** @see node_type::print */ -char * ngsi_print(struct node *n); +char *ngsi_print(struct node *n); /** @see node_type::open */ int ngsi_start(struct node *n); @@ -94,4 +98,8 @@ int ngsi_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int ngsi_write(struct node *n, struct sample *smps[], unsigned cnt); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/opal.h b/include/villas/nodes/opal.h index f39668e9e..4584e270d 100644 --- a/include/villas/nodes/opal.h +++ b/include/villas/nodes/opal.h @@ -41,6 +41,10 @@ #include "AsyncApi.h" #include "OpalGenAsyncParamCtrl.h" +#ifdef __cplusplus +extern "C" { +#endif + struct opal { int reply; int mode; @@ -68,7 +72,7 @@ int opal_deinit(); int opal_parse(struct node *n, json_t *cfg); /** @see node_type::print */ -char * opal_print(struct node *n); +char *opal_print(struct node *n); /** Print global settings of the OPAL node type. */ int opal_print_global(); @@ -85,4 +89,8 @@ int opal_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int opal_write(struct node *n, struct sample *smps[], unsigned cnt); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/shmem.h b/include/villas/nodes/shmem.h index dc156064f..00225b2b8 100644 --- a/include/villas/nodes/shmem.h +++ b/include/villas/nodes/shmem.h @@ -36,19 +36,23 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** Node-type for shared memory communication. * @see node_type */ struct shmem { - const char* out_name; /**< Name of the shm object for the output queue. */ - const char* in_name; /**< Name of the shm object for the input queue. */ - struct shmem_conf conf; /**< Interface configuration struct. */ - char **exec; /**< External program to execute on start. */ - struct shmem_int intf; /**< Shmem interface */ + const char *out_name; /**< Name of the shm object for the output queue. */ + const char *in_name; /**< Name of the shm object for the input queue. */ + struct shmem_conf conf; /**< Interface configuration struct. */ + char **exec; /**< External program to execute on start. */ + struct shmem_int intf; /**< Shmem interface */ }; /** @see node_type::print */ -char * shmem_print(struct node *n); +char *shmem_print(struct node *n); /** @see node_type::parse */ int shmem_parse(struct node *n, json_t *cfg); @@ -65,4 +69,8 @@ int shmem_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int shmem_write(struct node *n, struct sample *smps[], unsigned cnt); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/signal_generator.h b/include/villas/nodes/signal_generator.h index 7c669aa16..6c08b99d4 100644 --- a/include/villas/nodes/signal_generator.h +++ b/include/villas/nodes/signal_generator.h @@ -32,6 +32,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct node; struct sample; @@ -51,29 +55,29 @@ enum signal_generator_type { * @see node_type */ struct signal_generator { - struct task task; /**< Timer for periodic events. */ - int rt; /**< Real-time mode? */ + struct task task; /**< Timer for periodic events. */ + int rt; /**< Real-time mode? */ enum signal_generator_type type; /**< Signal type */ - double rate; /**< Sampling rate. */ - double frequency; /**< Frequency of the generated signals. */ - double amplitude; /**< Amplitude of the generated signals. */ - double stddev; /**< Standard deviation of random signals (normal distributed). */ - double offset; /**< A constant bias. */ + double rate; /**< Sampling rate. */ + double frequency; /**< Frequency of the generated signals. */ + double amplitude; /**< Amplitude of the generated signals. */ + double stddev; /**< Standard deviation of random signals (normal distributed). */ + double offset; /**< A constant bias. */ - double *last; /**< The values from the previous period which are required for random walk. */ + double *last; /**< The values from the previous period which are required for random walk. */ - int values; /**< The number of values which will be emitted by this node. */ - int limit; /**< The number of values which should be generated by this node. <0 for infinitve. */ + int values; /**< The number of values which will be emitted by this node. */ + int limit; /**< The number of values which should be generated by this node. <0 for infinitve. */ - struct timespec started; /**< Point in time when this node was started. */ - int counter; /**< The number of packets already emitted. */ - int missed_steps; /**< Total number of missed steps. */ + struct timespec started; /**< Point in time when this node was started. */ + int counter; /**< The number of packets already emitted. */ + int missed_steps; /**< Total number of missed steps. */ }; /** @see node_type::print */ -char * signal_generator_print(struct node *n); +char *signal_generator_print(struct node *n); /** @see node_type::parse */ int signal_generator_parse(struct node *n, json_t *cfg); @@ -89,4 +93,8 @@ int signal_generator_read(struct node *n, struct sample *smps[], unsigned cnt); enum signal_generator_type signal_generator_lookup_type(const char *type); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/socket.h b/include/villas/nodes/socket.h index 345792823..3499c7329 100644 --- a/include/villas/nodes/socket.h +++ b/include/villas/nodes/socket.h @@ -50,6 +50,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct format_type; @@ -75,29 +79,29 @@ union sockaddr_union { }; struct socket { - int sd; /**< The socket descriptor */ - int mark; /**< Socket mark for netem, routing and filtering */ - int verify_source; /**< Verify the source address of incoming packets against socket::remote. */ + int sd; /**< The socket descriptor */ + int mark; /**< Socket mark for netem, routing and filtering */ + int verify_source; /**< Verify the source address of incoming packets against socket::remote. */ - enum socket_layer layer; /**< The OSI / IP layer which should be used for this socket */ + enum socket_layer layer; /**< The OSI / IP layer which should be used for this socket */ - union sockaddr_union local; /**< Local address of the socket */ - union sockaddr_union remote; /**< Remote address of the socket */ + union sockaddr_union local; /**< Local address of the socket */ + union sockaddr_union remote; /**< Remote address of the socket */ struct format_type *format; struct io io; /* Multicast options */ struct multicast { - int enabled; /**< Is multicast enabled? */ - unsigned char loop; /** Loopback multicast packets to local host? */ - unsigned char ttl; /**< The time to live for multicast packets. */ - struct ip_mreq mreq; /**< A multicast group to join. */ + int enabled; /**< Is multicast enabled? */ + unsigned char loop; /** Loopback multicast packets to local host? */ + unsigned char ttl; /**< The time to live for multicast packets. */ + struct ip_mreq mreq; /**< A multicast group to join. */ } multicast; #ifdef WITH_NETEM - struct rtnl_qdisc *tc_qdisc; /**< libnl3: Network emulator queuing discipline */ - struct rtnl_cls *tc_classifier; /**< libnl3: Firewall mark classifier */ + struct rtnl_qdisc *tc_qdisc; /**< libnl3: Network emulator queuing discipline */ + struct rtnl_cls *tc_classifier; /**< libnl3: Firewall mark classifier */ #endif /* WITH_NETEM */ }; @@ -124,7 +128,7 @@ int socket_read(struct node *n, struct sample *smps[], unsigned cnt); int socket_parse(struct node *n, json_t *cfg); /** @see node_type::print */ -char * socket_print(struct node *n); +char *socket_print(struct node *n); /** Generate printable socket address depending on the address family * @@ -134,7 +138,7 @@ char * socket_print(struct node *n); * @param sa A pointer to the socket address. * @return The buffer containing the textual representation of the address. The caller is responsible to free() this buffer! */ -char * socket_print_addr(struct sockaddr *saddr); +char *socket_print_addr(struct sockaddr *saddr); /** Parse a socket address depending on the address family * @@ -154,4 +158,8 @@ int socket_parse_addr(const char *str, struct sockaddr *sa, enum socket_layer la int socket_compare_addr(struct sockaddr *x, struct sockaddr *y); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/stats.h b/include/villas/nodes/stats.h index 27caf6621..89a161656 100644 --- a/include/villas/nodes/stats.h +++ b/include/villas/nodes/stats.h @@ -33,6 +33,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct node; struct sample; @@ -51,7 +55,7 @@ struct stats_node { int stats_node_init(struct super_node *sn); /** @see node_type::print */ -char * stats_node_print(struct node *n); +char *stats_node_print(struct node *n); /** @see node_type::parse */ int stats_node_parse(struct node *n, json_t *cfg); @@ -65,4 +69,8 @@ int stats_node_stop(struct node *n); /** @see node_type::read */ int stats_node_read(struct node *n, struct sample *smps[], unsigned cnt); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/test_rtt.h b/include/villas/nodes/test_rtt.h index a0e14e533..97b615a26 100644 --- a/include/villas/nodes/test_rtt.h +++ b/include/villas/nodes/test_rtt.h @@ -33,6 +33,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct test_rtt; struct node; @@ -41,29 +45,29 @@ struct sample; struct test_rtt_case { double rate; int values; - int limit; /**< The number of samples we take per test. */ + int limit; /**< The number of samples we take per test. */ char *filename; }; struct test_rtt { - struct task task; /**< The periodic task for test_rtt_read() */ - struct io io; /**< The format of the output file */ + struct task task; /**< The periodic task for test_rtt_read() */ + struct io io; /**< The format of the output file */ struct format_type *format; - double cooldown; /**< Number of seconds to wait beween tests. */ + double cooldown; /**< Number of seconds to wait beween tests. */ - int current; /**< Index of current test in test_rtt::cases */ + int current; /**< Index of current test in test_rtt::cases */ int counter; - struct list cases; /**< List of test cases */ + struct list cases; /**< List of test cases */ - char *output; /**< The directory where we place the results. */ - char *prefix; /**< An optional prefix in the filename. */ + char *output; /**< The directory where we place the results. */ + char *prefix; /**< An optional prefix in the filename. */ }; /** @see node_type::print */ -char * test_rtt_print(struct node *n); +char *test_rtt_print(struct node *n); /** @see node_type::parse */ int test_rtt_parse(struct node *n, json_t *cfg); @@ -80,4 +84,8 @@ int test_rtt_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int test_rtt_write(struct node *n, struct sample *smps[], unsigned cnt); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/websocket.h b/include/villas/nodes/websocket.h index 6c61053b1..7ea510d4b 100644 --- a/include/villas/nodes/websocket.h +++ b/include/villas/nodes/websocket.h @@ -38,56 +38,60 @@ #include #include -#define DEFAULT_WEBSOCKET_QUEUELEN (DEFAULT_QUEUELEN * 64) -#define DEFAULT_WEBSOCKET_SAMPLELEN DEFAULT_SAMPLELEN +#ifdef __cplusplus +extern "C" { +#endif + +#define DEFAULT_WEBSOCKET_QUEUELEN (DEFAULT_QUEUELEN * 64) +#define DEFAULT_WEBSOCKET_SAMPLELEN DEFAULT_SAMPLELEN /* Forward declaration */ struct lws; /** Internal data per websocket node */ struct websocket { - struct list destinations; /**< List of websocket servers connect to in client mode (struct websocket_destination). */ + struct list destinations; /**< List of websocket servers connect to in client mode (struct websocket_destination). */ - struct pool pool; - struct queue_signalled queue; /**< For samples which are received from WebSockets */ + struct pool pool; + struct queue_signalled queue; /**< For samples which are received from WebSockets */ }; /* Internal datastructures */ struct websocket_connection { - enum websocket_connection_state { - WEBSOCKET_CONNECTION_STATE_DESTROYED, - WEBSOCKET_CONNECTION_STATE_INITIALIZED, - WEBSOCKET_CONNECTION_STATE_CONNECTING, - WEBSOCKET_CONNECTION_STATE_RECONNECTING, - WEBSOCKET_CONNECTION_STATE_ESTABLISHED, - WEBSOCKET_CONNECTION_STATE_SHUTDOWN, - WEBSOCKET_CONNECTION_STATE_ERROR - } state; /**< The current status of this connection. */ + enum websocket_connection_state { + WEBSOCKET_CONNECTION_STATE_DESTROYED, + WEBSOCKET_CONNECTION_STATE_INITIALIZED, + WEBSOCKET_CONNECTION_STATE_CONNECTING, + WEBSOCKET_CONNECTION_STATE_RECONNECTING, + WEBSOCKET_CONNECTION_STATE_ESTABLISHED, + WEBSOCKET_CONNECTION_STATE_SHUTDOWN, + WEBSOCKET_CONNECTION_STATE_ERROR + } state; /**< The current status of this connection. */ - enum { - WEBSOCKET_MODE_CLIENT, - WEBSOCKET_MODE_SERVER, - } mode; + enum { + WEBSOCKET_MODE_CLIENT, + WEBSOCKET_MODE_SERVER, + } mode; - struct lws *wsi; - struct node *node; - struct io io; - struct queue queue; /**< For samples which are sent to the WebSocket */ + struct lws *wsi; + struct node *node; + struct io io; + struct queue queue; /**< For samples which are sent to the WebSocket */ - struct format_type *format; - struct websocket_destination *destination; + struct format_type *format; + struct websocket_destination *destination; - struct { - struct buffer recv; /**< A buffer for reconstructing fragmented messags. */ - struct buffer send; /**< A buffer for contsructing messages before calling lws_write() */ - } buffers; + struct { + struct buffer recv; /**< A buffer for reconstructing fragmented messags. */ + struct buffer send; /**< A buffer for contsructing messages before calling lws_write() */ + } buffers; - char *_name; + char *_name; }; struct websocket_destination { - char *uri; - struct lws_client_connect_info info; + char *uri; + struct lws_client_connect_info info; }; int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); @@ -113,4 +117,8 @@ int websocket_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int websocket_write(struct node *n, struct sample *smps[], unsigned cnt); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/nodes/zeromq.h b/include/villas/nodes/zeromq.h index afdf4a9b7..d883aaf07 100644 --- a/include/villas/nodes/zeromq.h +++ b/include/villas/nodes/zeromq.h @@ -35,8 +35,12 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + #if ZMQ_BUILD_DRAFT_API && (ZMQ_VERSION_MAJOR > 4 || (ZMQ_VERSION_MAJOR == 4 && ZMQ_VERSION_MINOR >= 2)) - #define ZMQ_BUILD_DISH 1 +#define ZMQ_BUILD_DISH 1 #endif /* Forward declarations */ @@ -68,19 +72,19 @@ struct zeromq { } pattern; struct { - void *socket; /**< ZeroMQ socket. */ + void *socket; /**< ZeroMQ socket. */ void *mon_socket; char *endpoint; } subscriber; struct { - void *socket; /**< ZeroMQ socket. */ + void *socket; /**< ZeroMQ socket. */ struct list endpoints; } publisher; }; /** @see node_type::print */ -char * zeromq_print(struct node *n); +char *zeromq_print(struct node *n); /** @see node_type::parse */ int zeromq_parse(struct node *n, json_t *cfg); @@ -103,4 +107,8 @@ int zeromq_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int zeromq_write(struct node *n, struct sample *smps[], unsigned cnt); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/path.h b/include/villas/path.h index 1db52dcf4..cef9b76ab 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -41,6 +41,10 @@ #include "mapping.h" #include "task.h" +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct stats; struct node; @@ -52,7 +56,7 @@ struct path_source { bool masked; struct pool pool; - struct list mappings; /**< List of mappings (struct mapping_entry). */ + struct list mappings; /**< List of mappings (struct mapping_entry). */ }; struct path_destination { @@ -63,15 +67,15 @@ struct path_destination { /** The register mode determines under which condition the path is triggered. */ enum path_mode { - PATH_MODE_ANY, /**< The path is triggered whenever one of the sources receives samples. */ - PATH_MODE_ALL /**< The path is triggered only after all sources have received at least 1 sample. */ + PATH_MODE_ANY, /**< The path is triggered whenever one of the sources receives samples. */ + PATH_MODE_ALL /**< The path is triggered only after all sources have received at least 1 sample. */ }; /** The datastructure for a path. */ struct path { - enum state state; /**< Path state. */ + enum state state; /**< Path state. */ - enum path_mode mode; /**< Determines when this path is triggered. */ + enum path_mode mode; /**< Determines when this path is triggered. */ struct { int nfds; @@ -82,27 +86,27 @@ struct path { struct sample *last_sample; int last_sequence; - struct list sources; /**< List of all incoming nodes (struct path_source). */ - struct list destinations; /**< List of all outgoing nodes (struct path_destination). */ - struct list hooks; /**< List of processing hooks (struct hook). */ + struct list sources; /**< List of all incoming nodes (struct path_source). */ + struct list destinations; /**< List of all outgoing nodes (struct path_destination). */ + struct list hooks; /**< List of processing hooks (struct hook). */ struct task timeout; - double rate; /**< A timeout for */ - int enabled; /**< Is this path enabled. */ - int poll; /**< Weather or not to use poll(2). */ - int reverse; /**< This path as a matching reverse path. */ - int builtin; /**< This path should use built-in hooks by default. */ - int queuelen; /**< The queue length for each path_destination::queue */ - int samplelen; /**< Will be calculated based on path::sources.mappings */ + double rate; /**< A timeout for */ + int enabled; /**< Is this path enabled. */ + int poll; /**< Weather or not to use poll(2). */ + int reverse; /**< This path as a matching reverse path. */ + int builtin; /**< This path should use built-in hooks by default. */ + int queuelen; /**< The queue length for each path_destination::queue */ + int samplelen; /**< Will be calculated based on path::sources.mappings */ - char *_name; /**< Singleton: A string which is used to print this path to screen. */ + char *_name; /**< Singleton: A string which is used to print this path to screen. */ - struct bitset mask; /**< A mask of path_sources which are enabled for poll(). */ - struct bitset received; /**< A mask of path_sources for which we already received samples. */ + struct bitset mask; /**< A mask of path_sources which are enabled for poll(). */ + struct bitset received; /**< A mask of path_sources for which we already received samples. */ - pthread_t tid; /**< The thread id for this path. */ - json_t *cfg; /**< A JSON object containing the configuration of the path. */ + pthread_t tid; /**< The thread id for this path. */ + json_t *cfg; /**< A JSON object containing the configuration of the path. */ }; /** Initialize internal data structures. */ @@ -150,7 +154,7 @@ void path_print_stats(struct path *p); * @param p A pointer to the path structure. * @return A pointer to a string containing a textual representation of the path. */ -const char * path_name(struct path *p); +const char *path_name(struct path *p); /** Reverse a path */ int path_reverse(struct path *p, struct path *r); @@ -168,4 +172,8 @@ int path_uses_node(struct path *p, struct node *n); */ int path_parse(struct path *p, json_t *cfg, struct list *nodes); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/plugin.h b/include/villas/plugin.h index 6a58b2d57..d373ab338 100644 --- a/include/villas/plugin.h +++ b/include/villas/plugin.h @@ -31,6 +31,10 @@ #include "node_type.h" #include "format_type.h" +#ifdef __cplusplus +extern "C"{ +#endif + /** @todo This is ugly as hell and broken on OS X / Clang anyway. */ #define REGISTER_PLUGIN(p) \ __attribute__((constructor(110))) static void UNIQUE(__ctor)() {\ @@ -95,3 +99,7 @@ void plugin_dump(enum plugin_type type); /** Find registered and loaded plugin with given name and type. */ struct plugin * plugin_lookup(enum plugin_type type, const char *name); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/pool.h b/include/villas/pool.h index 15d7833db..662336d99 100644 --- a/include/villas/pool.h +++ b/include/villas/pool.h @@ -32,17 +32,21 @@ #include "common.h" #include "memory.h" +#ifdef __cplusplus +extern "C" { +#endif + /** A thread-safe memory pool */ struct pool { - off_t buffer_off; /**< Offset from the struct address to the underlying memory area */ + off_t buffer_off; /**< Offset from the struct address to the underlying memory area */ struct memtype *mem; enum state state; - size_t len; /**< Length of the underlying memory area */ + size_t len; /**< Length of the underlying memory area */ - size_t blocksz; /**< Length of a block in bytes */ - size_t alignment; /**< Alignment of a block in bytes */ + size_t blocksz; /**< Length of a block in bytes */ + size_t alignment; /**< Alignment of a block in bytes */ struct queue queue; /**< The queue which is used to keep track of free blocks */ }; @@ -69,26 +73,26 @@ int pool_destroy(struct pool *p); * This number can be smaller than the requested \p cnt blocks * in case the pool currently holds less than \p cnt blocks. */ -INLINE ssize_t pool_get_many(struct pool *p, void *blocks[], size_t cnt) -{ +INLINE ssize_t pool_get_many(struct pool *p, void *blocks[], size_t cnt) { return queue_pull_many(&p->queue, blocks, cnt); } /** Push \p cnt values which are giving by the array values to the stack. */ -INLINE ssize_t pool_put_many(struct pool *p, void *blocks[], size_t cnt) -{ +INLINE ssize_t pool_put_many(struct pool *p, void *blocks[], size_t cnt) { return queue_push_many(&p->queue, blocks, cnt); } /** Get a free memory block from pool. */ -INLINE void * pool_get(struct pool *p) -{ +INLINE void *pool_get(struct pool *p) { void *ptr; return queue_pull(&p->queue, &ptr) == 1 ? ptr : NULL; } /** Release a memory block back to the pool. */ -INLINE int pool_put(struct pool *p, void *buf) -{ +INLINE int pool_put(struct pool *p, void *buf) { return queue_push(&p->queue, buf); } + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/queue.h b/include/villas/queue.h index ce1ab58d5..e75a95368 100644 --- a/include/villas/queue.h +++ b/include/villas/queue.h @@ -34,6 +34,8 @@ #pragma once + + #include #include #include @@ -41,6 +43,10 @@ #include "atomic.h" #include "common.h" +#ifdef __cplusplus +extern "C"{ +#endif + /* Forward declarations */ struct memtype; @@ -112,3 +118,7 @@ int queue_pull_many(struct queue *q, void *ptr[], size_t cnt); * @return -1 on failure. */ int queue_close(struct queue *q); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/queue_signalled.h b/include/villas/queue_signalled.h index 4f9e012b4..2d2a44fb3 100644 --- a/include/villas/queue_signalled.h +++ b/include/villas/queue_signalled.h @@ -27,6 +27,10 @@ #include "queue.h" +#ifdef __cplusplus +extern "C"{ +#endif + enum queue_signalled_flags { /* Mode */ QUEUE_SIGNALLED_AUTO = (0 << 0), /**< We will choose the best method available on the platform */ @@ -80,3 +84,7 @@ int queue_signalled_close(struct queue_signalled *qs); /** Returns a file descriptor which can be used with poll / select to wait for new data */ int queue_signalled_fd(struct queue_signalled *qs); + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/sample.h b/include/villas/sample.h index 149fcc4f5..4102f7f00 100644 --- a/include/villas/sample.h +++ b/include/villas/sample.h @@ -21,20 +21,22 @@ * along with this program. If not, see . *********************************************************************************/ + + #pragma once #include "atomic.h" -#ifdef __cplusplus -extern "C" { -#endif - #include #include #include #include #include +#ifdef __cplusplus +extern "C"{ +#endif + /* Forward declarations */ struct pool; diff --git a/include/villas/signal.h b/include/villas/signal.h index 56502e8f3..729cbb1f3 100644 --- a/include/villas/signal.h +++ b/include/villas/signal.h @@ -25,12 +25,16 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct list; struct node; struct signal { - char *name; /**< The name of the signal. */ + char *name; /**< The name of the signal. */ char *unit; int enabled; enum { @@ -46,3 +50,7 @@ int signal_parse(struct signal *s, json_t *cfg); int signal_parse_list(struct list *list, json_t *cfg); int signal_get_offset(const char *str, struct node *n); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/stats.h b/include/villas/stats.h index e0e46f941..70b044f2d 100644 --- a/include/villas/stats.h +++ b/include/villas/stats.h @@ -29,6 +29,10 @@ #include "hist.h" +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct sample; struct node; @@ -40,19 +44,19 @@ enum stats_format { }; enum stats_id { - STATS_SKIPPED, /**< Counter for skipped samples due to hooks. */ - STATS_TIME, /**< The processing time per sample within VILLAsnode. */ - STATS_REORDERED, /**< Counter for reordered samples. */ - STATS_GAP_SAMPLE, /**< Histogram for inter sample timestamps (as sent by remote). */ - STATS_GAP_RECEIVED, /**< Histogram for inter sample arrival time (as seen by this instance). */ - STATS_OWD, /**< Histogram for one-way-delay (OWD) of received samples. */ - STATS_COUNT /**< Just here to have an updated number of statistics. */ + STATS_SKIPPED, /**< Counter for skipped samples due to hooks. */ + STATS_TIME, /**< The processing time per sample within VILLAsnode. */ + STATS_REORDERED, /**< Counter for reordered samples. */ + STATS_GAP_SAMPLE, /**< Histogram for inter sample timestamps (as sent by remote). */ + STATS_GAP_RECEIVED, /**< Histogram for inter sample arrival time (as seen by this instance). */ + STATS_OWD, /**< Histogram for one-way-delay (OWD) of received samples. */ + STATS_COUNT /**< Just here to have an updated number of statistics. */ }; struct stats_delta { double values[STATS_COUNT]; - int update; /**< Bitmask of stats_id. Only those which are masked will be updated */ + int update; /**< Bitmask of stats_id. Only those which are masked will be updated */ }; struct stats { @@ -73,7 +77,7 @@ void stats_collect(struct stats *s, struct sample *smps[], size_t cnt); int stats_commit(struct stats *s); -json_t * stats_json(struct stats *s); +json_t *stats_json(struct stats *s); void stats_reset(struct stats *s); @@ -86,4 +90,8 @@ void stats_print(struct stats *s, FILE *f, enum stats_format fmt, int verbose); enum stats_id stats_lookup_id(const char *name); +#ifdef __cplusplus +} +#endif + #endif /* _STATS_H_ */ diff --git a/include/villas/super_node.h b/include/villas/super_node.h index 064c31cc9..4ff019119 100644 --- a/include/villas/super_node.h +++ b/include/villas/super_node.h @@ -29,33 +29,37 @@ #include "log.h" #include "common.h" +#ifdef __cplusplus +extern "C" { +#endif + /** Global configuration */ struct super_node { - int priority; /**< Process priority (lower is better) */ - int affinity; /**< Process affinity of the server and all created threads */ - int hugepages; /**< Number of hugepages to reserve. */ - double stats; /**< Interval for path statistics. Set to 0 to disable them. */ + int priority; /**< Process priority (lower is better) */ + int affinity; /**< Process affinity of the server and all created threads */ + int hugepages; /**< Number of hugepages to reserve. */ + double stats; /**< Interval for path statistics. Set to 0 to disable them. */ - struct list nodes; - struct list paths; - struct list plugins; + struct list nodes; + struct list paths; + struct list plugins; - struct log log; - struct api api; - struct web web; + struct log log; + struct api api; + struct web web; - char *name; /**< A name of this super node. Usually the hostname. */ + char *name; /**< A name of this super node. Usually the hostname. */ - enum state state; + enum state state; - char *uri; /**< URI of configuration */ + char *uri; /**< URI of configuration */ - json_t *cfg; /**< JSON representation of the configuration. */ + json_t *cfg; /**< JSON representation of the configuration. */ }; /* Compatibility with libconfig < 1.5 */ #if (LIBCONFIG_VER_MAJOR <= 1) && (LIBCONFIG_VER_MINOR < 5) - #define config_setting_lookup config_lookup_from +#define config_setting_lookup config_lookup_from #endif /** Inititalize configuration object before parsing the configuration. */ @@ -83,3 +87,7 @@ int super_node_stop(struct super_node *sn); /** Desctroy configuration object. */ int super_node_destroy(struct super_node *sn); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/table.h b/include/villas/table.h index f11a0d5d9..9ecf0d8a1 100644 --- a/include/villas/table.h +++ b/include/villas/table.h @@ -25,18 +25,22 @@ * @{ */ +#ifdef __cplusplus +extern "C" { +#endif + struct table_column { - int width; /**< Width of the column. */ - char *title; /**< The title as shown in the table header. */ - char *format; /**< The format which is used to print the table rows. */ - char *unit; /**< An optional unit which will be shown in the table header. */ + int width; /**< Width of the column. */ + char *title; /**< The title as shown in the table header. */ + char *format; /**< The format which is used to print the table rows. */ + char *unit; /**< An optional unit which will be shown in the table header. */ enum { TABLE_ALIGN_LEFT, TABLE_ALIGN_RIGHT } align; - int _width; /**< The real width of this column. Calculated by table_header() */ + int _width; /**< The real width of this column. Calculated by table_header() */ }; struct table { @@ -54,4 +58,8 @@ void table_row(struct table *t, ...); /** Print the table footer. */ void table_footer(struct table *t); +#ifdef __cplusplus +} +#endif + /** @} */ diff --git a/include/villas/task.h b/include/villas/task.h index 141f2f7e2..30b029edd 100644 --- a/include/villas/task.h +++ b/include/villas/task.h @@ -28,27 +28,31 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /** We can choose between two periodic task implementations */ //#define PERIODIC_TASK_IMPL NANOSLEEP -#define TIMERFD 1 -#define CLOCK_NANOSLEEP 2 -#define NANOSLEEP 3 +#define TIMERFD 1 +#define CLOCK_NANOSLEEP 2 +#define NANOSLEEP 3 #if defined(__MACH__) - #define PERIODIC_TASK_IMPL NANOSLEEP +#define PERIODIC_TASK_IMPL NANOSLEEP #elif defined(__linux__) - #define PERIODIC_TASK_IMPL TIMERFD +#define PERIODIC_TASK_IMPL TIMERFD #else - #error "Platform not supported" +#error "Platform not supported" #endif struct task { - int clock; /**< CLOCK_{MONOTONIC,REALTIME} */ + int clock; /**< CLOCK_{MONOTONIC,REALTIME} */ - struct timespec period; /**< The period of periodic invations of this task */ - struct timespec next; /**< The timer value for the next invocation */ + struct timespec period; /**< The period of periodic invations of this task */ + struct timespec next; /**< The timer value for the next invocation */ #if PERIODIC_TASK_IMPL == TIMERFD - int fd; /**< The timerfd_create(2) file descriptior. */ + int fd; /**< The timerfd_create(2) file descriptior. */ #endif }; @@ -73,3 +77,8 @@ int task_set_rate(struct task *t, double rate); * Note: currently not supported on all platforms. */ int task_fd(struct task *t); + +#ifdef __cplusplus +} +#endif + diff --git a/include/villas/timing.h b/include/villas/timing.h index 1ef49e123..dad07fad1 100644 --- a/include/villas/timing.h +++ b/include/villas/timing.h @@ -28,6 +28,10 @@ #include +#ifdef __cplusplus +extern "C"{ +#endif + /** Get delta between two timespec structs */ struct timespec time_diff(const struct timespec *start, const struct timespec *end); @@ -45,3 +49,7 @@ double time_to_double(const struct timespec *ts); /** Convert double containing seconds after 1970 to timespec. */ struct timespec time_from_double(double secs); + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/utils.h b/include/villas/utils.h index ac753be84..942087fbb 100644 --- a/include/villas/utils.h +++ b/include/villas/utils.h @@ -33,6 +33,11 @@ #include #include +#ifdef __cplusplus +extern "C"{ +#endif + + #ifdef __GNUC__ #define LIKELY(x) __builtin_expect((x),1) #define UNLIKELY(x) __builtin_expect((x),0) @@ -275,3 +280,8 @@ pid_t spawn(const char *name, char *const argv[]); /** Determines the string length as printed on the screen (ignores escable sequences). */ size_t strlenp(const char *str); + + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/villas/web.h b/include/villas/web.h index a299146e4..cb65c8775 100644 --- a/include/villas/web.h +++ b/include/villas/web.h @@ -27,6 +27,10 @@ #include "common.h" +#ifdef __cplusplus +extern "C" { +#endif + /* Forward declarations */ struct api; @@ -35,13 +39,13 @@ struct web { enum state state; - struct lws_context *context; /**< The libwebsockets server context. */ - struct lws_vhost *vhost; /**< The libwebsockets vhost. */ + struct lws_context *context; /**< The libwebsockets server context. */ + struct lws_vhost *vhost; /**< The libwebsockets vhost. */ - int port; /**< Port of the build in HTTP / WebSocket server. */ - char *htdocs; /**< The root directory for files served via HTTP. */ - char *ssl_cert; /**< Path to the SSL certitifcate for HTTPS / WSS. */ - char *ssl_private_key; /**< Path to the SSL private key for HTTPS / WSS. */ + int port; /**< Port of the build in HTTP / WebSocket server. */ + char *htdocs; /**< The root directory for files served via HTTP. */ + char *ssl_cert; /**< Path to the SSL certitifcate for HTTPS / WSS. */ + char *ssl_private_key; /**< Path to the SSL private key for HTTPS / WSS. */ pthread_t thread; }; @@ -60,3 +64,7 @@ int web_stop(struct web *w); /** Parse HTTPd and WebSocket related options */ int web_parse(struct web *w, json_t *cfg); + +#ifdef __cplusplus +} +#endif From 02464fc10c0fb962c4f8509543cf9bc1bbfe9180 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 29 Jun 2018 08:01:18 +0200 Subject: [PATCH 02/18] config.h is automatically generated. Do not commit it --- include/villas/config.h | 69 ----------------------------------------- 1 file changed, 69 deletions(-) delete mode 100644 include/villas/config.h diff --git a/include/villas/config.h b/include/villas/config.h deleted file mode 100644 index 082579cd8..000000000 --- a/include/villas/config.h +++ /dev/null @@ -1,69 +0,0 @@ -/** Static server configuration - * - * This file contains some compiled-in settings. - * This settings are not part of the configuration file. - * - * @file - * @author Steffen Vogel - * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC - * @license GNU General Public License (version 3) - * - * VILLASnode - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - *********************************************************************************/ - - - -#pragma once - -#ifdef __cplusplus -extern "C"{ -#endif - -/* Paths */ -#define PLUGIN_PATH PREFIX "/share/villas/node/plugins" -#define WEB_PATH PREFIX "/share/villas/node/web" -#define SYSFS_PATH "/sys" -#define PROCFS_PATH "/proc" - -/** Default number of values in a sample */ -#define DEFAULT_SAMPLELEN 64 -#define DEFAULT_QUEUELEN 1024 - -/** Number of hugepages which are requested from the the kernel. - * @see https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt */ -#define DEFAULT_NR_HUGEPAGES 100 - -/** Width of log output in characters */ -#define LOG_WIDTH 80 -#define LOG_HEIGHT 25 - -/** Socket priority */ -#define SOCKET_PRIO 7 - -/* Protocol numbers */ -#define IPPROTO_VILLAS 137 -#define ETH_P_VILLAS 0xBABE - -#define USER_AGENT "VILLASnode (" BUILDID ")" - -/* Required kernel version */ -#define KERNEL_VERSION_MAJ 3 -#define KERNEL_VERSION_MIN 6 - - -#ifdef __cplusplus -} -#endif \ No newline at end of file From 312cdc2fbe34fa20c203fd06153ba4b5d07626bf Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 29 Jun 2018 08:37:14 +0200 Subject: [PATCH 03/18] revert whitespace changes --- include/villas/config.h.in | 5 +- include/villas/formats/json-reserve.h | 2 +- include/villas/formats/msg.h | 2 +- include/villas/formats/msg_format.h | 61 ++++++++++++----------- include/villas/formats/protobuf.h | 2 +- include/villas/formats/raw.h | 25 +++++----- include/villas/formats/villas_binary.h | 5 +- include/villas/hist.h | 44 ++++++++--------- include/villas/hook.h | 16 +++--- include/villas/io.h | 14 +++--- include/villas/kernel/kernel.h | 2 +- include/villas/kernel/nl-private.h | 55 +++++++++++---------- include/villas/mapping.h | 9 ++-- include/villas/memory.h | 20 ++++---- include/villas/node.h | 1 - include/villas/nodes/amqp.h | 2 +- include/villas/nodes/comedi.h | 45 +++++++++-------- include/villas/nodes/file.h | 35 ++++++------- include/villas/nodes/influxdb.h | 2 +- include/villas/nodes/loopback.h | 2 +- include/villas/nodes/nanomsg.h | 2 +- include/villas/nodes/ngsi.h | 28 +++++------ include/villas/nodes/opal.h | 2 +- include/villas/nodes/shmem.h | 16 +++--- include/villas/nodes/signal_generator.h | 32 ++++++------ include/villas/nodes/socket.h | 32 ++++++------ include/villas/nodes/test_rtt.h | 22 ++++----- include/villas/nodes/websocket.h | 66 ++++++++++++------------- include/villas/nodes/zeromq.h | 12 ++--- include/villas/path.h | 46 ++++++++--------- include/villas/pool.h | 20 +++++--- include/villas/queue.h | 5 +- include/villas/sample.h | 2 - include/villas/signal.h | 4 +- include/villas/stats.h | 21 ++++---- include/villas/super_node.h | 32 ++++++------ include/villas/table.h | 14 +++--- include/villas/task.h | 21 ++++---- include/villas/web.h | 12 ++--- 39 files changed, 369 insertions(+), 369 deletions(-) diff --git a/include/villas/config.h.in b/include/villas/config.h.in index 082579cd8..419f0fa61 100644 --- a/include/villas/config.h.in +++ b/include/villas/config.h.in @@ -24,8 +24,6 @@ * along with this program. If not, see . *********************************************************************************/ - - #pragma once #ifdef __cplusplus @@ -63,7 +61,6 @@ extern "C"{ #define KERNEL_VERSION_MAJ 3 #define KERNEL_VERSION_MIN 6 - #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/include/villas/formats/json-reserve.h b/include/villas/formats/json-reserve.h index c715bc659..f6e6c227b 100644 --- a/include/villas/formats/json-reserve.h +++ b/include/villas/formats/json-reserve.h @@ -40,4 +40,4 @@ int json_reserve_scan(struct io *io, struct sample *smps[], unsigned cnt); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/include/villas/formats/msg.h b/include/villas/formats/msg.h index 2d88ec92a..c69e21bbc 100644 --- a/include/villas/formats/msg.h +++ b/include/villas/formats/msg.h @@ -60,4 +60,4 @@ int msg_from_sample(struct msg *msg, struct sample *smp); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/include/villas/formats/msg_format.h b/include/villas/formats/msg_format.h index 99069089a..1dc4f87b5 100644 --- a/include/villas/formats/msg_format.h +++ b/include/villas/formats/msg_format.h @@ -30,68 +30,71 @@ extern "C" { #endif /** The current version number for the message format */ -#define MSG_VERSION 2 +#define MSG_VERSION 2 /** @todo Implement more message types */ -#define MSG_TYPE_DATA 0 /**< Message contains float / integer values */ -#define MSG_TYPE_START 1 /**< Message marks the beginning of a new simulation case */ -#define MSG_TYPE_STOP 2 /**< Message marks the end of a simulation case */ +#define MSG_TYPE_DATA 0 /**< Message contains float / integer values */ +#define MSG_TYPE_START 1 /**< Message marks the beginning of a new simulation case */ +#define MSG_TYPE_STOP 2 /**< Message marks the end of a simulation case */ /** The total size in bytes of a message */ -#define MSG_LEN(values) (sizeof(struct msg) + MSG_DATA_LEN(values)) +#define MSG_LEN(values) (sizeof(struct msg) + MSG_DATA_LEN(values)) /** The length of \p values values in bytes. */ -#define MSG_DATA_LEN(values) (sizeof(float) * (values)) +#define MSG_DATA_LEN(values) (sizeof(float) * (values)) /** The offset to the first data value in a message. */ -#define MSG_DATA_OFFSET(msg) ((char *) (msg) + offsetof(struct msg, data)) +#define MSG_DATA_OFFSET(msg) ((char *) (msg) + offsetof(struct msg, data)) /** Initialize a message with default values */ #define MSG_INIT(len, seq) (struct msg) {\ - .version = MSG_VERSION, \ - .type = MSG_TYPE_DATA, \ - .length = len, \ - .sequence = seq, \ + .version = MSG_VERSION, \ + .type = MSG_TYPE_DATA, \ + .length = len, \ + .sequence = seq, \ } /** The timestamp of a message in struct timespec format */ -#define MSG_TS(msg) (struct timespec) { \ - .tv_sec = (msg)->ts.sec, \ - .tv_nsec = (msg)->ts.nsec \ +#define MSG_TS(msg) (struct timespec) { \ + .tv_sec = (msg)->ts.sec, \ + .tv_nsec = (msg)->ts.nsec \ } /** This message format is used by all clients * * @diafile msg_format.dia **/ -struct msg { +struct msg +{ #if BYTE_ORDER == BIG_ENDIAN - unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ - unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ - unsigned rsvd1 : 2; /**< Reserved bits */ + unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ + unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ + unsigned rsvd1 : 2; /**< Reserved bits */ #elif BYTE_ORDER == LITTLE_ENDIAN - unsigned rsvd1 : 2; /**< Reserved bits */ - unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ - unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ + unsigned rsvd1 : 2; /**< Reserved bits */ + unsigned type : 2; /**< Data or control message (see MSG_TYPE_*) */ + unsigned version: 4; /**< Specifies the format of the remaining message (see MGS_VERSION) */ +#else + #error Invalid byte-order #endif - uint8_t resv2; /**< An id which identifies the source of this sample. */ - uint16_t length; /**< The number of values in msg::data[]. */ - uint32_t sequence; /**< The sequence number is incremented by one for consecutive messages. */ + uint8_t resv2; /**< An id which identifies the source of this sample. */ + uint16_t length; /**< The number of values in msg::data[]. */ + uint32_t sequence; /**< The sequence number is incremented by one for consecutive messages. */ /** A timestamp per message. */ struct { - uint32_t sec; /**< Seconds since 1970-01-01 00:00:00 */ - uint32_t nsec; /**< Nanoseconds of the current second. */ + uint32_t sec; /**< Seconds since 1970-01-01 00:00:00 */ + uint32_t nsec; /**< Nanoseconds of the current second. */ } ts; /** The message payload. */ union { - float f; /**< Floating point values. */ - uint32_t i; /**< Integer values. */ + float f; /**< Floating point values. */ + uint32_t i; /**< Integer values. */ } data[]; } __attribute__((packed)); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/include/villas/formats/protobuf.h b/include/villas/formats/protobuf.h index 343920189..d6dda00dc 100644 --- a/include/villas/formats/protobuf.h +++ b/include/villas/formats/protobuf.h @@ -40,4 +40,4 @@ int protobuf_sscan(struct io *io, char *buf, size_t len, size_t *rbytes, struct #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/include/villas/formats/raw.h b/include/villas/formats/raw.h index d10eea879..3ee518b2f 100644 --- a/include/villas/formats/raw.h +++ b/include/villas/formats/raw.h @@ -33,28 +33,28 @@ extern "C" { struct sample; enum raw_flags { - RAW_FAKE = (1 << 16), /**< Treat the first three values as: sequenceno, seconds, nanoseconds */ + RAW_FAKE = (1 << 16), /**< Treat the first three values as: sequenceno, seconds, nanoseconds */ - RAW_BE_INT = (1 << 17), /**< Byte-order for integer data: big-endian if set. */ - RAW_BE_FLT = (1 << 18), /**< Byte-order for floating point data: big-endian if set. */ - RAW_BE_HDR = (1 << 19), /**< Byte-order for fake header fields: big-endian if set. */ + RAW_BE_INT = (1 << 17), /**< Byte-order for integer data: big-endian if set. */ + RAW_BE_FLT = (1 << 18), /**< Byte-order for floating point data: big-endian if set. */ + RAW_BE_HDR = (1 << 19), /**< Byte-order for fake header fields: big-endian if set. */ /** Byte-order for all fields: big-endian if set. */ - RAW_BE = RAW_BE_INT | RAW_BE_FLT | RAW_BE_HDR, + RAW_BE = RAW_BE_INT | RAW_BE_FLT | RAW_BE_HDR, /** Mix floating and integer types. * * io_raw_sscan() parses all values as single / double precission fp. * io_raw_sprint() uses sample::format to determine the type. */ - RAW_AUTO = (1 << 22), - RAW_FLT = (1 << 23), /**< Data-type: floating point otherwise integer. */ + RAW_AUTO = (1 << 22), + RAW_FLT = (1 << 23), /**< Data-type: floating point otherwise integer. */ //RAW_1 = (0 << 24), /**< Pack each value as a single bit. */ - RAW_8 = (3 << 24), /**< Pack each value as a byte. */ - RAW_16 = (4 << 24), /**< Pack each value as a word. */ - RAW_32 = (5 << 24), /**< Pack each value as a double word. */ - RAW_64 = (6 << 24) /**< Pack each value as a quad word. */ + RAW_8 = (3 << 24), /**< Pack each value as a byte. */ + RAW_16 = (4 << 24), /**< Pack each value as a word. */ + RAW_32 = (5 << 24), /**< Pack each value as a double word. */ + RAW_64 = (6 << 24) /**< Pack each value as a quad word. */ }; /** Copy / read struct msg's from buffer \p buf to / fram samples \p smps. */ @@ -62,6 +62,7 @@ int raw_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct samp /** Read struct sample's from buffer \p buf into samples \p smps. */ int raw_sscan(struct io *io, char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt); + #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/include/villas/formats/villas_binary.h b/include/villas/formats/villas_binary.h index ff520919f..8fd4428c3 100644 --- a/include/villas/formats/villas_binary.h +++ b/include/villas/formats/villas_binary.h @@ -35,12 +35,11 @@ struct msg; struct io; enum villas_binary_flags { - VILLAS_BINARY_WEB = (1 << 16) /**< Use webmsg format (everying little endian) */ + VILLAS_BINARY_WEB = (1 << 16) /**< Use webmsg format (everying little endian) */ }; /** Copy / read struct msg's from buffer \p buf to / fram samples \p smps. */ -int -villas_binary_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct sample *smps[], unsigned cnt); +int villas_binary_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct sample *smps[], unsigned cnt); /** Read struct sample's from buffer \p buf into samples \p smps. */ int villas_binary_sscan(struct io *io, char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt); diff --git a/include/villas/hist.h b/include/villas/hist.h index ca8a4d10a..477470956 100644 --- a/include/villas/hist.h +++ b/include/villas/hist.h @@ -32,39 +32,39 @@ extern "C" { #endif -#define HIST_HEIGHT (LOG_WIDTH - 55) -#define HIST_SEQ 17 +#define HIST_HEIGHT (LOG_WIDTH - 55) +#define HIST_SEQ 17 typedef uintmax_t hist_cnt_t; /** Histogram structure used to collect statistics. */ struct hist { - double resolution; /**< The distance between two adjacent buckets. */ + double resolution; /**< The distance between two adjacent buckets. */ - double high; /**< The value of the highest bucket. */ - double low; /**< The value of the lowest bucket. */ + double high; /**< The value of the highest bucket. */ + double low; /**< The value of the lowest bucket. */ - double highest; /**< The highest value observed (may be higher than #high). */ - double lowest; /**< The lowest value observed (may be lower than #low). */ - double last; /**< The last value which has been put into the buckets */ + double highest; /**< The highest value observed (may be higher than #high). */ + double lowest; /**< The lowest value observed (may be lower than #low). */ + double last; /**< The last value which has been put into the buckets */ - int length; /**< The number of buckets in #data. */ + int length; /**< The number of buckets in #data. */ - hist_cnt_t total; /**< Total number of counted values. */ - hist_cnt_t warmup; /**< Number of values which are used during warmup phase. */ + hist_cnt_t total; /**< Total number of counted values. */ + hist_cnt_t warmup; /**< Number of values which are used during warmup phase. */ - hist_cnt_t higher; /**< The number of values which are higher than #high. */ - hist_cnt_t lower; /**< The number of values which are lower than #low. */ + hist_cnt_t higher; /**< The number of values which are higher than #high. */ + hist_cnt_t lower; /**< The number of values which are lower than #low. */ - hist_cnt_t *data; /**< Pointer to dynamically allocated array of size length. */ + hist_cnt_t *data; /**< Pointer to dynamically allocated array of size length. */ - double _m[2], _s[2]; /**< Private variables for online variance calculation */ + double _m[2], _s[2]; /**< Private variables for online variance calculation */ }; -#define hist_last(h) ((h)->last) -#define hist_highest(h) ((h)->highest) -#define hist_lowest(h) ((h)->lowest) -#define hist_total(h) ((h)->total) +#define hist_last(h) ((h)->last) +#define hist_highest(h) ((h)->highest) +#define hist_lowest(h) ((h)->lowest) +#define hist_total(h) ((h)->total) /** Initialize struct hist with supplied values and allocate memory for buckets. */ int hist_init(struct hist *h, int buckets, hist_cnt_t warmup); @@ -97,7 +97,7 @@ void hist_plot(struct hist *h); * * @return The string containing the dump. The caller is responsible to free() the buffer. */ -char *hist_dump(struct hist *h); +char * hist_dump(struct hist *h); /** Prints Matlab struct containing all infos to file. */ int hist_dump_matlab(struct hist *h, FILE *f); @@ -106,8 +106,8 @@ int hist_dump_matlab(struct hist *h, FILE *f); int hist_dump_json(struct hist *h, FILE *f); /** Build a libjansson / JSON object of the histogram. */ -json_t *hist_json(struct hist *h); +json_t * hist_json(struct hist *h); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/include/villas/hook.h b/include/villas/hook.h index 66ec85e8d..9af46b333 100644 --- a/include/villas/hook.h +++ b/include/villas/hook.h @@ -48,17 +48,17 @@ struct list; /** Descriptor for user defined hooks. See hooks[]. */ struct hook { - enum state state; + enum state state; - struct path *path; - struct node *node; + struct path *path; + struct node *node; - struct hook_type *_vt; /**< C++ like Vtable pointer. */ - void *_vd; /**< Private data for this hook. This pointer can be used to pass data between consecutive calls of the callback. */ + struct hook_type *_vt; /**< C++ like Vtable pointer. */ + void *_vd; /**< Private data for this hook. This pointer can be used to pass data between consecutive calls of the callback. */ - int priority; /**< A priority to change the order of execution within one type of hook. */ + int priority; /**< A priority to change the order of execution within one type of hook. */ - json_t *cfg; /**< A JSON object containing the configuration of the hook. */ + json_t *cfg; /**< A JSON object containing the configuration of the hook. */ }; int hook_init(struct hook *h, struct hook_type *vt, struct path *p, struct node *n); @@ -103,4 +103,4 @@ int hook_parse_list(struct list *list, json_t *cfg, struct path *p, struct node #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/include/villas/io.h b/include/villas/io.h index b471a0764..3370b26de 100644 --- a/include/villas/io.h +++ b/include/villas/io.h @@ -36,16 +36,16 @@ struct sample; struct format_type; enum io_flags { - IO_FLUSH = (1 << 8), /**< Flush the output stream after each chunk of samples. */ - IO_NONBLOCK = (1 << 9), /**< Dont block io_read() while waiting for new samples. */ - IO_NEWLINES = (1 << 10) /**< The samples of this format are newline delimited. */ + IO_FLUSH = (1 << 8), /**< Flush the output stream after each chunk of samples. */ + IO_NONBLOCK = (1 << 9), /**< Dont block io_read() while waiting for new samples. */ + IO_NEWLINES = (1 << 10) /**< The samples of this format are newline delimited. */ }; struct io { enum state state; int flags; - char delimiter; /**< Newline delimiter. */ - char separator; /**< Column separator (used by csv and villas.human formats only) */ + char delimiter; /**< Newline delimiter. */ + char separator; /**< Column separator (used by csv and villas.human formats only) */ struct { /** A format type can use this file handle or overwrite the @@ -110,8 +110,8 @@ int io_stream_fd(struct io *io); int io_stream_flush(struct io *io); -FILE *io_stream_input(struct io *io); -FILE *io_stream_output(struct io *io); +FILE * io_stream_input(struct io *io); +FILE * io_stream_output(struct io *io); /** Parse samples from the buffer \p buf with a length of \p len bytes. * diff --git a/include/villas/kernel/kernel.h b/include/villas/kernel/kernel.h index 60ceb4312..265e125f4 100644 --- a/include/villas/kernel/kernel.h +++ b/include/villas/kernel/kernel.h @@ -89,7 +89,7 @@ int kernel_get_page_size(); int kernel_get_hugepage_size(); /** Set SMP affinity of IRQ */ -int kernel_irq_setaffinity(unsigned irq, uintmax_t new , uintmax_t *old ) ; +int kernel_irq_setaffinity(unsigned irq, uintmax_t new , uintmax_t *old ); #ifdef __cplusplus } diff --git a/include/villas/kernel/nl-private.h b/include/villas/kernel/nl-private.h index f67051dc7..ded3b0a97 100644 --- a/include/villas/kernel/nl-private.h +++ b/include/villas/kernel/nl-private.h @@ -6,39 +6,44 @@ extern "C" { #define SCH_NETEM_ATTR_DIST 0x2000 -struct rtnl_netem_corr { - uint32_t nmc_delay; - uint32_t nmc_loss; - uint32_t nmc_duplicate; +struct rtnl_netem_corr +{ + uint32_t nmc_delay; + uint32_t nmc_loss; + uint32_t nmc_duplicate; }; -struct rtnl_netem_reo { - uint32_t nmro_probability; - uint32_t nmro_correlation; +struct rtnl_netem_reo +{ + uint32_t nmro_probability; + uint32_t nmro_correlation; }; -struct rtnl_netem_crpt { - uint32_t nmcr_probability; - uint32_t nmcr_correlation; +struct rtnl_netem_crpt +{ + uint32_t nmcr_probability; + uint32_t nmcr_correlation; }; -struct rtnl_netem_dist { - int16_t *dist_data; - size_t dist_size; +struct rtnl_netem_dist +{ + int16_t * dist_data; + size_t dist_size; }; -struct rtnl_netem { - uint32_t qnm_latency; - uint32_t qnm_limit; - uint32_t qnm_loss; - uint32_t qnm_gap; - uint32_t qnm_duplicate; - uint32_t qnm_jitter; - uint32_t qnm_mask; - struct rtnl_netem_corr qnm_corr; - struct rtnl_netem_reo qnm_ro; - struct rtnl_netem_crpt qnm_crpt; - struct rtnl_netem_dist qnm_dist; +struct rtnl_netem +{ + uint32_t qnm_latency; + uint32_t qnm_limit; + uint32_t qnm_loss; + uint32_t qnm_gap; + uint32_t qnm_duplicate; + uint32_t qnm_jitter; + uint32_t qnm_mask; + struct rtnl_netem_corr qnm_corr; + struct rtnl_netem_reo qnm_ro; + struct rtnl_netem_crpt qnm_crpt; + struct rtnl_netem_dist qnm_dist; }; void *rtnl_tc_data(struct rtnl_tc *tc); diff --git a/include/villas/mapping.h b/include/villas/mapping.h index af26b3918..1db78444e 100644 --- a/include/villas/mapping.h +++ b/include/villas/mapping.h @@ -42,8 +42,8 @@ struct list; struct mapping_entry { struct node *node; - int offset; /**< Offset of this mapping entry within sample::data */ - int length; /**< The number of values which is covered by this mapping entry. */ + int offset; /**< Offset of this mapping entry within sample::data */ + int length; /**< The number of values which is covered by this mapping entry. */ enum { MAPPING_TYPE_DATA, @@ -88,10 +88,9 @@ struct mapping_entry { }; }; -int -mapping_remap(struct list *m, struct sample *remapped, struct sample *original, struct stats *s); +int mapping_remap(struct list *m, struct sample *remapped, struct sample *original, struct stats *s); -int mapping_update(struct mapping_entry *e, struct sample *remapped, struct sample * new , struct stats *s ) ; +int mapping_update(struct mapping_entry *e, struct sample *remapped, struct sample *new, struct stats *s); int mapping_parse(struct mapping_entry *e, json_t *cfg, struct list *nodes); diff --git a/include/villas/memory.h b/include/villas/memory.h index a680b65ff..54da2bbc0 100644 --- a/include/villas/memory.h +++ b/include/villas/memory.h @@ -21,16 +21,16 @@ * along with this program. If not, see . *********************************************************************************/ +#pragma once + #include #include -#pragma once - #ifdef __cplusplus extern "C" { #endif -#define HUGEPAGESIZE (1 << 21) +#define HUGEPAGESIZE (1 << 21) struct memtype; @@ -38,10 +38,10 @@ typedef void *(*memzone_allocator_t)(struct memtype *mem, size_t len, size_t ali typedef int (*memzone_deallocator_t)(struct memtype *mem, void *ptr, size_t len); enum memtype_flags { - MEMORY_MMAP = (1 << 0), - MEMORY_DMA = (1 << 1), - MEMORY_HUGEPAGE = (1 << 2), - MEMORY_HEAP = (1 << 3) + MEMORY_MMAP = (1 << 0), + MEMORY_DMA = (1 << 1), + MEMORY_HUGEPAGE = (1 << 2), + MEMORY_HEAP = (1 << 3) }; struct memtype { @@ -86,13 +86,13 @@ int memory_init(int hugepages); * @retval NULL If allocation failed. * @retval <>0 If allocation was successful. */ -void *memory_alloc(struct memtype *m, size_t len); +void * memory_alloc(struct memtype *m, size_t len); -void *memory_alloc_aligned(struct memtype *m, size_t len, size_t alignment); +void * memory_alloc_aligned(struct memtype *m, size_t len, size_t alignment); int memory_free(struct memtype *m, void *ptr, size_t len); -struct memtype *memtype_managed_init(void *ptr, size_t len); +struct memtype * memtype_managed_init(void *ptr, size_t len); extern struct memtype memtype_heap; extern struct memtype memtype_hugepage; diff --git a/include/villas/node.h b/include/villas/node.h index 8ec6f7523..d8c5b4c58 100644 --- a/include/villas/node.h +++ b/include/villas/node.h @@ -26,7 +26,6 @@ * @{ */ - #pragma once #include diff --git a/include/villas/nodes/amqp.h b/include/villas/nodes/amqp.h index aa453ec75..b343190c1 100644 --- a/include/villas/nodes/amqp.h +++ b/include/villas/nodes/amqp.h @@ -68,7 +68,7 @@ struct amqp { }; /** @see node_type::print */ -char *amqp_print(struct node *n); +char * amqp_print(struct node *n); /** @see node_type::parse */ int amqp_parse(struct node *n, json_t *json); diff --git a/include/villas/nodes/comedi.h b/include/villas/nodes/comedi.h index 6cc282b64..3aa01f5b3 100644 --- a/include/villas/nodes/comedi.h +++ b/include/villas/nodes/comedi.h @@ -49,23 +49,22 @@ struct comedi_chanspec { }; struct comedi_direction { - int subdevice; ///< Comedi subdevice - int buffer_size; ///< Comedi's kernel buffer size in kB - int sample_size; ///< Size of a single measurement sample - int sample_rate_hz; ///< Sample rate in Hz - bool present; ///< Config present - bool enabled; ///< Card is started successfully - bool running; ///< Card is actively transfering samples - struct timespec started; ///< Timestamp when sampling started - struct timespec last_debug; ///< Timestamp of last debug output - size_t counter; ///< Number of villas samples transfered - struct comedi_chanspec *chanspecs; ///< Range and maxdata config of channels - unsigned *chanlist; ///< Channel list in comedi's packed format - size_t chanlist_len; ///< Number of channels for this direction + int subdevice; ///< Comedi subdevice + int buffer_size; ///< Comedi's kernel buffer size in kB + int sample_size; ///< Size of a single measurement sample + int sample_rate_hz; ///< Sample rate in Hz + bool present; ///< Config present + bool enabled; ///< Card is started successfully + bool running; ///< Card is actively transfering samples + struct timespec started; ///< Timestamp when sampling started + struct timespec last_debug; ///< Timestamp of last debug output + size_t counter; ///< Number of villas samples transfered + struct comedi_chanspec *chanspecs; ///< Range and maxdata config of channels + unsigned *chanlist; ///< Channel list in comedi's packed format + size_t chanlist_len; ///< Number of channels for this direction - - char *buffer; - char *bufptr; + char* buffer; + char* bufptr; }; struct comedi { @@ -77,16 +76,16 @@ struct comedi { char *buf; char *bufptr; #else - char *map; - size_t bufpos; - size_t front; - size_t back; + char *map; + size_t bufpos; + size_t front; + size_t back; #endif }; /** @see node_type::print */ -char *comedi_print(struct node *n); +char * comedi_print(struct node *n); /** @see node_type::parse */ int comedi_parse(struct node *n, json_t *cfg); @@ -103,8 +102,8 @@ int comedi_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int comedi_write(struct node *n, struct sample *smps[], unsigned cnt); +/** @} */ + #ifdef __cplusplus } #endif - -/** @} */ diff --git a/include/villas/nodes/file.h b/include/villas/nodes/file.h index aa13409f8..498afb0a4 100644 --- a/include/villas/nodes/file.h +++ b/include/villas/nodes/file.h @@ -37,19 +37,19 @@ extern "C" { #endif -#define FILE_MAX_PATHLEN 512 +#define FILE_MAX_PATHLEN 512 struct file { - struct io io; /**< Format and file IO */ + struct io io; /**< Format and file IO */ struct format_type *format; - char *uri_tmpl; /**< Format string for file name. */ - char *uri; /**< Real file name. */ - char *mode; /**< File access mode. */ + char *uri_tmpl; /**< Format string for file name. */ + char *uri; /**< Real file name. */ + char *mode; /**< File access mode. */ - int flush; /**< Flush / upload file contents after each write. */ - struct task task; /**< Timer file descriptor. Blocks until 1 / rate seconds are elapsed. */ - double rate; /**< The read rate. */ + int flush; /**< Flush / upload file contents after each write. */ + struct task task; /**< Timer file descriptor. Blocks until 1 / rate seconds are elapsed. */ + double rate; /**< The read rate. */ enum epoch_mode { FILE_EPOCH_DIRECT, @@ -57,21 +57,21 @@ struct file { FILE_EPOCH_RELATIVE, FILE_EPOCH_ABSOLUTE, FILE_EPOCH_ORIGINAL - } epoch_mode; /**< Specifies how file::offset is calculated. */ + } epoch_mode; /**< Specifies how file::offset is calculated. */ enum { - FILE_EOF_EXIT, /**< Terminate when EOF is reached. */ - FILE_EOF_REWIND, /**< Rewind the file when EOF is reached. */ - FILE_EOF_WAIT /**< Blocking wait when EOF is reached. */ + FILE_EOF_EXIT, /**< Terminate when EOF is reached. */ + FILE_EOF_REWIND, /**< Rewind the file when EOF is reached. */ + FILE_EOF_WAIT /**< Blocking wait when EOF is reached. */ } eof; - struct timespec first; /**< The first timestamp in the file file::{read,write}::uri */ - struct timespec epoch; /**< The epoch timestamp from the configuration. */ - struct timespec offset; /**< An offset between the timestamp in the input file and the current time */ + struct timespec first; /**< The first timestamp in the file file::{read,write}::uri */ + struct timespec epoch; /**< The epoch timestamp from the configuration. */ + struct timespec offset; /**< An offset between the timestamp in the input file and the current time */ }; /** @see node_type::print */ -char *file_print(struct node *n); +char * file_print(struct node *n); /** @see node_type::parse */ int file_parse(struct node *n, json_t *cfg); @@ -88,7 +88,8 @@ int file_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int file_write(struct node *n, struct sample *smps[], unsigned cnt); +/** @} */ + #ifdef __cplusplus } #endif -/** @} */ diff --git a/include/villas/nodes/influxdb.h b/include/villas/nodes/influxdb.h index 7eb4ea9b2..3abbde1f9 100644 --- a/include/villas/nodes/influxdb.h +++ b/include/villas/nodes/influxdb.h @@ -53,7 +53,7 @@ struct influxdb { }; /** @see node_type::print */ -char *influxdb_print(struct node *n); +char * influxdb_print(struct node *n); /** @see node_type::parse */ int influxdb_parse(struct node *n, json_t *cfg); diff --git a/include/villas/nodes/loopback.h b/include/villas/nodes/loopback.h index 4560928c8..4cff73eb6 100644 --- a/include/villas/nodes/loopback.h +++ b/include/villas/nodes/loopback.h @@ -51,7 +51,7 @@ struct loopback { }; /** @see node_type::print */ -char *loopback_print(struct node *n); +char * loopback_print(struct node *n); /** @see node_type::parse */ int loopback_parse(struct node *n, json_t *cfg); diff --git a/include/villas/nodes/nanomsg.h b/include/villas/nodes/nanomsg.h index e2c775d6a..11b5d2a3e 100644 --- a/include/villas/nodes/nanomsg.h +++ b/include/villas/nodes/nanomsg.h @@ -59,7 +59,7 @@ struct nanomsg { }; /** @see node_type::print */ -char *nanomsg_print(struct node *n); +char * nanomsg_print(struct node *n); /** @see node_type::parse */ int nanomsg_parse(struct node *n, json_t *cfg); diff --git a/include/villas/nodes/ngsi.h b/include/villas/nodes/ngsi.h index 486d3f3e4..6160907a5 100644 --- a/include/villas/nodes/ngsi.h +++ b/include/villas/nodes/ngsi.h @@ -50,22 +50,22 @@ extern "C" { struct node; struct ngsi { - const char *endpoint; /**< The NGSI context broker endpoint URL. */ - const char *entity_id; /**< The context broker entity id related to this node */ - const char *entity_type; /**< The type of the entity */ - const char *access_token; /**< An optional authentication token which will be sent as HTTP header. */ + const char *endpoint; /**< The NGSI context broker endpoint URL. */ + const char *entity_id; /**< The context broker entity id related to this node */ + const char *entity_type; /**< The type of the entity */ + const char *access_token; /**< An optional authentication token which will be sent as HTTP header. */ - double timeout; /**< HTTP timeout in seconds */ - double rate; /**< Rate used for polling. */ + double timeout; /**< HTTP timeout in seconds */ + double rate; /**< Rate used for polling. */ - struct task task; /**< Timer for periodic events. */ - int ssl_verify; /**< Boolean flag whether SSL server certificates should be verified or not. */ + struct task task; /**< Timer for periodic events. */ + int ssl_verify; /**< Boolean flag whether SSL server certificates should be verified or not. */ - struct curl_slist *headers; /**< List of HTTP request headers for libcurl */ + struct curl_slist *headers; /**< List of HTTP request headers for libcurl */ - CURL *curl; /**< libcurl: handle */ + CURL *curl; /**< libcurl: handle */ - struct list mapping; /**< A mapping between indices of the VILLASnode samples and the attributes in ngsi::context */ + struct list mapping; /**< A mapping between indices of the VILLASnode samples and the attributes in ngsi::context */ }; /** Initialize global NGSI settings and maps shared memory regions. @@ -84,7 +84,7 @@ int ngsi_deinit(); int ngsi_parse(struct node *n, json_t *cfg); /** @see node_type::print */ -char *ngsi_print(struct node *n); +char * ngsi_print(struct node *n); /** @see node_type::open */ int ngsi_start(struct node *n); @@ -98,8 +98,8 @@ int ngsi_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int ngsi_write(struct node *n, struct sample *smps[], unsigned cnt); +/** @} */ + #ifdef __cplusplus } #endif - -/** @} */ diff --git a/include/villas/nodes/opal.h b/include/villas/nodes/opal.h index 4584e270d..370b58957 100644 --- a/include/villas/nodes/opal.h +++ b/include/villas/nodes/opal.h @@ -72,7 +72,7 @@ int opal_deinit(); int opal_parse(struct node *n, json_t *cfg); /** @see node_type::print */ -char *opal_print(struct node *n); +char * opal_print(struct node *n); /** Print global settings of the OPAL node type. */ int opal_print_global(); diff --git a/include/villas/nodes/shmem.h b/include/villas/nodes/shmem.h index 00225b2b8..0426645ce 100644 --- a/include/villas/nodes/shmem.h +++ b/include/villas/nodes/shmem.h @@ -44,15 +44,15 @@ extern "C" { * @see node_type */ struct shmem { - const char *out_name; /**< Name of the shm object for the output queue. */ - const char *in_name; /**< Name of the shm object for the input queue. */ - struct shmem_conf conf; /**< Interface configuration struct. */ - char **exec; /**< External program to execute on start. */ - struct shmem_int intf; /**< Shmem interface */ + const char* out_name; /**< Name of the shm object for the output queue. */ + const char* in_name; /**< Name of the shm object for the input queue. */ + struct shmem_conf conf; /**< Interface configuration struct. */ + char **exec; /**< External program to execute on start. */ + struct shmem_int intf; /**< Shmem interface */ }; /** @see node_type::print */ -char *shmem_print(struct node *n); +char * shmem_print(struct node *n); /** @see node_type::parse */ int shmem_parse(struct node *n, json_t *cfg); @@ -69,8 +69,8 @@ int shmem_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int shmem_write(struct node *n, struct sample *smps[], unsigned cnt); +/** @} */ + #ifdef __cplusplus } #endif - -/** @} */ diff --git a/include/villas/nodes/signal_generator.h b/include/villas/nodes/signal_generator.h index 6c08b99d4..18d0c0b48 100644 --- a/include/villas/nodes/signal_generator.h +++ b/include/villas/nodes/signal_generator.h @@ -55,29 +55,29 @@ enum signal_generator_type { * @see node_type */ struct signal_generator { - struct task task; /**< Timer for periodic events. */ - int rt; /**< Real-time mode? */ + struct task task; /**< Timer for periodic events. */ + int rt; /**< Real-time mode? */ enum signal_generator_type type; /**< Signal type */ - double rate; /**< Sampling rate. */ - double frequency; /**< Frequency of the generated signals. */ - double amplitude; /**< Amplitude of the generated signals. */ - double stddev; /**< Standard deviation of random signals (normal distributed). */ - double offset; /**< A constant bias. */ + double rate; /**< Sampling rate. */ + double frequency; /**< Frequency of the generated signals. */ + double amplitude; /**< Amplitude of the generated signals. */ + double stddev; /**< Standard deviation of random signals (normal distributed). */ + double offset; /**< A constant bias. */ - double *last; /**< The values from the previous period which are required for random walk. */ + double *last; /**< The values from the previous period which are required for random walk. */ - int values; /**< The number of values which will be emitted by this node. */ - int limit; /**< The number of values which should be generated by this node. <0 for infinitve. */ + int values; /**< The number of values which will be emitted by this node. */ + int limit; /**< The number of values which should be generated by this node. <0 for infinitve. */ - struct timespec started; /**< Point in time when this node was started. */ - int counter; /**< The number of packets already emitted. */ - int missed_steps; /**< Total number of missed steps. */ + struct timespec started; /**< Point in time when this node was started. */ + int counter; /**< The number of packets already emitted. */ + int missed_steps; /**< Total number of missed steps. */ }; /** @see node_type::print */ -char *signal_generator_print(struct node *n); +char * signal_generator_print(struct node *n); /** @see node_type::parse */ int signal_generator_parse(struct node *n, json_t *cfg); @@ -93,8 +93,8 @@ int signal_generator_read(struct node *n, struct sample *smps[], unsigned cnt); enum signal_generator_type signal_generator_lookup_type(const char *type); +/** @} */ + #ifdef __cplusplus } #endif - -/** @} */ diff --git a/include/villas/nodes/socket.h b/include/villas/nodes/socket.h index 3499c7329..6cccdf848 100644 --- a/include/villas/nodes/socket.h +++ b/include/villas/nodes/socket.h @@ -79,29 +79,29 @@ union sockaddr_union { }; struct socket { - int sd; /**< The socket descriptor */ - int mark; /**< Socket mark for netem, routing and filtering */ - int verify_source; /**< Verify the source address of incoming packets against socket::remote. */ + int sd; /**< The socket descriptor */ + int mark; /**< Socket mark for netem, routing and filtering */ + int verify_source; /**< Verify the source address of incoming packets against socket::remote. */ - enum socket_layer layer; /**< The OSI / IP layer which should be used for this socket */ + enum socket_layer layer; /**< The OSI / IP layer which should be used for this socket */ - union sockaddr_union local; /**< Local address of the socket */ - union sockaddr_union remote; /**< Remote address of the socket */ + union sockaddr_union local; /**< Local address of the socket */ + union sockaddr_union remote; /**< Remote address of the socket */ struct format_type *format; struct io io; /* Multicast options */ struct multicast { - int enabled; /**< Is multicast enabled? */ - unsigned char loop; /** Loopback multicast packets to local host? */ - unsigned char ttl; /**< The time to live for multicast packets. */ - struct ip_mreq mreq; /**< A multicast group to join. */ + int enabled; /**< Is multicast enabled? */ + unsigned char loop; /** Loopback multicast packets to local host? */ + unsigned char ttl; /**< The time to live for multicast packets. */ + struct ip_mreq mreq; /**< A multicast group to join. */ } multicast; #ifdef WITH_NETEM - struct rtnl_qdisc *tc_qdisc; /**< libnl3: Network emulator queuing discipline */ - struct rtnl_cls *tc_classifier; /**< libnl3: Firewall mark classifier */ + struct rtnl_qdisc *tc_qdisc; /**< libnl3: Network emulator queuing discipline */ + struct rtnl_cls *tc_classifier; /**< libnl3: Firewall mark classifier */ #endif /* WITH_NETEM */ }; @@ -128,7 +128,7 @@ int socket_read(struct node *n, struct sample *smps[], unsigned cnt); int socket_parse(struct node *n, json_t *cfg); /** @see node_type::print */ -char *socket_print(struct node *n); +char * socket_print(struct node *n); /** Generate printable socket address depending on the address family * @@ -138,7 +138,7 @@ char *socket_print(struct node *n); * @param sa A pointer to the socket address. * @return The buffer containing the textual representation of the address. The caller is responsible to free() this buffer! */ -char *socket_print_addr(struct sockaddr *saddr); +char * socket_print_addr(struct sockaddr *saddr); /** Parse a socket address depending on the address family * @@ -158,8 +158,8 @@ int socket_parse_addr(const char *str, struct sockaddr *sa, enum socket_layer la int socket_compare_addr(struct sockaddr *x, struct sockaddr *y); +/** @} */ + #ifdef __cplusplus } #endif - -/** @} */ diff --git a/include/villas/nodes/test_rtt.h b/include/villas/nodes/test_rtt.h index 97b615a26..20f204410 100644 --- a/include/villas/nodes/test_rtt.h +++ b/include/villas/nodes/test_rtt.h @@ -45,29 +45,29 @@ struct sample; struct test_rtt_case { double rate; int values; - int limit; /**< The number of samples we take per test. */ + int limit; /**< The number of samples we take per test. */ char *filename; }; struct test_rtt { - struct task task; /**< The periodic task for test_rtt_read() */ - struct io io; /**< The format of the output file */ + struct task task; /**< The periodic task for test_rtt_read() */ + struct io io; /**< The format of the output file */ struct format_type *format; - double cooldown; /**< Number of seconds to wait beween tests. */ + double cooldown; /**< Number of seconds to wait beween tests. */ - int current; /**< Index of current test in test_rtt::cases */ + int current; /**< Index of current test in test_rtt::cases */ int counter; - struct list cases; /**< List of test cases */ + struct list cases; /**< List of test cases */ - char *output; /**< The directory where we place the results. */ - char *prefix; /**< An optional prefix in the filename. */ + char *output; /**< The directory where we place the results. */ + char *prefix; /**< An optional prefix in the filename. */ }; /** @see node_type::print */ -char *test_rtt_print(struct node *n); +char * test_rtt_print(struct node *n); /** @see node_type::parse */ int test_rtt_parse(struct node *n, json_t *cfg); @@ -84,8 +84,8 @@ int test_rtt_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int test_rtt_write(struct node *n, struct sample *smps[], unsigned cnt); +/** @} */ + #ifdef __cplusplus } #endif - -/** @} */ diff --git a/include/villas/nodes/websocket.h b/include/villas/nodes/websocket.h index 7ea510d4b..0e5097a17 100644 --- a/include/villas/nodes/websocket.h +++ b/include/villas/nodes/websocket.h @@ -42,56 +42,56 @@ extern "C" { #endif -#define DEFAULT_WEBSOCKET_QUEUELEN (DEFAULT_QUEUELEN * 64) -#define DEFAULT_WEBSOCKET_SAMPLELEN DEFAULT_SAMPLELEN +#define DEFAULT_WEBSOCKET_QUEUELEN (DEFAULT_QUEUELEN * 64) +#define DEFAULT_WEBSOCKET_SAMPLELEN DEFAULT_SAMPLELEN /* Forward declaration */ struct lws; /** Internal data per websocket node */ struct websocket { - struct list destinations; /**< List of websocket servers connect to in client mode (struct websocket_destination). */ + struct list destinations; /**< List of websocket servers connect to in client mode (struct websocket_destination). */ - struct pool pool; - struct queue_signalled queue; /**< For samples which are received from WebSockets */ + struct pool pool; + struct queue_signalled queue; /**< For samples which are received from WebSockets */ }; /* Internal datastructures */ struct websocket_connection { - enum websocket_connection_state { - WEBSOCKET_CONNECTION_STATE_DESTROYED, - WEBSOCKET_CONNECTION_STATE_INITIALIZED, - WEBSOCKET_CONNECTION_STATE_CONNECTING, - WEBSOCKET_CONNECTION_STATE_RECONNECTING, - WEBSOCKET_CONNECTION_STATE_ESTABLISHED, - WEBSOCKET_CONNECTION_STATE_SHUTDOWN, - WEBSOCKET_CONNECTION_STATE_ERROR - } state; /**< The current status of this connection. */ + enum websocket_connection_state { + WEBSOCKET_CONNECTION_STATE_DESTROYED, + WEBSOCKET_CONNECTION_STATE_INITIALIZED, + WEBSOCKET_CONNECTION_STATE_CONNECTING, + WEBSOCKET_CONNECTION_STATE_RECONNECTING, + WEBSOCKET_CONNECTION_STATE_ESTABLISHED, + WEBSOCKET_CONNECTION_STATE_SHUTDOWN, + WEBSOCKET_CONNECTION_STATE_ERROR + } state; /**< The current status of this connection. */ - enum { - WEBSOCKET_MODE_CLIENT, - WEBSOCKET_MODE_SERVER, - } mode; + enum { + WEBSOCKET_MODE_CLIENT, + WEBSOCKET_MODE_SERVER, + } mode; - struct lws *wsi; - struct node *node; - struct io io; - struct queue queue; /**< For samples which are sent to the WebSocket */ + struct lws *wsi; + struct node *node; + struct io io; + struct queue queue; /**< For samples which are sent to the WebSocket */ - struct format_type *format; - struct websocket_destination *destination; + struct format_type *format; + struct websocket_destination *destination; - struct { - struct buffer recv; /**< A buffer for reconstructing fragmented messags. */ - struct buffer send; /**< A buffer for contsructing messages before calling lws_write() */ - } buffers; + struct { + struct buffer recv; /**< A buffer for reconstructing fragmented messags. */ + struct buffer send; /**< A buffer for contsructing messages before calling lws_write() */ + } buffers; - char *_name; + char *_name; }; struct websocket_destination { - char *uri; - struct lws_client_connect_info info; + char *uri; + struct lws_client_connect_info info; }; int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); @@ -117,8 +117,8 @@ int websocket_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int websocket_write(struct node *n, struct sample *smps[], unsigned cnt); +/** @} */ + #ifdef __cplusplus } #endif - -/** @} */ diff --git a/include/villas/nodes/zeromq.h b/include/villas/nodes/zeromq.h index d883aaf07..4f31de46e 100644 --- a/include/villas/nodes/zeromq.h +++ b/include/villas/nodes/zeromq.h @@ -40,7 +40,7 @@ extern "C" { #endif #if ZMQ_BUILD_DRAFT_API && (ZMQ_VERSION_MAJOR > 4 || (ZMQ_VERSION_MAJOR == 4 && ZMQ_VERSION_MINOR >= 2)) -#define ZMQ_BUILD_DISH 1 + #define ZMQ_BUILD_DISH 1 #endif /* Forward declarations */ @@ -72,19 +72,19 @@ struct zeromq { } pattern; struct { - void *socket; /**< ZeroMQ socket. */ + void *socket; /**< ZeroMQ socket. */ void *mon_socket; char *endpoint; } subscriber; struct { - void *socket; /**< ZeroMQ socket. */ + void *socket; /**< ZeroMQ socket. */ struct list endpoints; } publisher; }; /** @see node_type::print */ -char *zeromq_print(struct node *n); +char * zeromq_print(struct node *n); /** @see node_type::parse */ int zeromq_parse(struct node *n, json_t *cfg); @@ -107,8 +107,8 @@ int zeromq_read(struct node *n, struct sample *smps[], unsigned cnt); /** @see node_type::write */ int zeromq_write(struct node *n, struct sample *smps[], unsigned cnt); +/** @} */ + #ifdef __cplusplus } #endif - -/** @} */ diff --git a/include/villas/path.h b/include/villas/path.h index cef9b76ab..b8c2de58a 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -56,7 +56,7 @@ struct path_source { bool masked; struct pool pool; - struct list mappings; /**< List of mappings (struct mapping_entry). */ + struct list mappings; /**< List of mappings (struct mapping_entry). */ }; struct path_destination { @@ -67,15 +67,15 @@ struct path_destination { /** The register mode determines under which condition the path is triggered. */ enum path_mode { - PATH_MODE_ANY, /**< The path is triggered whenever one of the sources receives samples. */ - PATH_MODE_ALL /**< The path is triggered only after all sources have received at least 1 sample. */ + PATH_MODE_ANY, /**< The path is triggered whenever one of the sources receives samples. */ + PATH_MODE_ALL /**< The path is triggered only after all sources have received at least 1 sample. */ }; /** The datastructure for a path. */ struct path { - enum state state; /**< Path state. */ + enum state state; /**< Path state. */ - enum path_mode mode; /**< Determines when this path is triggered. */ + enum path_mode mode; /**< Determines when this path is triggered. */ struct { int nfds; @@ -86,27 +86,27 @@ struct path { struct sample *last_sample; int last_sequence; - struct list sources; /**< List of all incoming nodes (struct path_source). */ - struct list destinations; /**< List of all outgoing nodes (struct path_destination). */ - struct list hooks; /**< List of processing hooks (struct hook). */ + struct list sources; /**< List of all incoming nodes (struct path_source). */ + struct list destinations; /**< List of all outgoing nodes (struct path_destination). */ + struct list hooks; /**< List of processing hooks (struct hook). */ struct task timeout; - double rate; /**< A timeout for */ - int enabled; /**< Is this path enabled. */ - int poll; /**< Weather or not to use poll(2). */ - int reverse; /**< This path as a matching reverse path. */ - int builtin; /**< This path should use built-in hooks by default. */ - int queuelen; /**< The queue length for each path_destination::queue */ - int samplelen; /**< Will be calculated based on path::sources.mappings */ + double rate; /**< A timeout for */ + int enabled; /**< Is this path enabled. */ + int poll; /**< Weather or not to use poll(2). */ + int reverse; /**< This path as a matching reverse path. */ + int builtin; /**< This path should use built-in hooks by default. */ + int queuelen; /**< The queue length for each path_destination::queue */ + int samplelen; /**< Will be calculated based on path::sources.mappings */ - char *_name; /**< Singleton: A string which is used to print this path to screen. */ + char *_name; /**< Singleton: A string which is used to print this path to screen. */ - struct bitset mask; /**< A mask of path_sources which are enabled for poll(). */ - struct bitset received; /**< A mask of path_sources for which we already received samples. */ + struct bitset mask; /**< A mask of path_sources which are enabled for poll(). */ + struct bitset received; /**< A mask of path_sources for which we already received samples. */ - pthread_t tid; /**< The thread id for this path. */ - json_t *cfg; /**< A JSON object containing the configuration of the path. */ + pthread_t tid; /**< The thread id for this path. */ + json_t *cfg; /**< A JSON object containing the configuration of the path. */ }; /** Initialize internal data structures. */ @@ -154,7 +154,7 @@ void path_print_stats(struct path *p); * @param p A pointer to the path structure. * @return A pointer to a string containing a textual representation of the path. */ -const char *path_name(struct path *p); +const char * path_name(struct path *p); /** Reverse a path */ int path_reverse(struct path *p, struct path *r); @@ -172,8 +172,8 @@ int path_uses_node(struct path *p, struct node *n); */ int path_parse(struct path *p, json_t *cfg, struct list *nodes); +/** @} */ + #ifdef __cplusplus } #endif - -/** @} */ diff --git a/include/villas/pool.h b/include/villas/pool.h index 662336d99..c8075128d 100644 --- a/include/villas/pool.h +++ b/include/villas/pool.h @@ -38,15 +38,15 @@ extern "C" { /** A thread-safe memory pool */ struct pool { - off_t buffer_off; /**< Offset from the struct address to the underlying memory area */ + off_t buffer_off; /**< Offset from the struct address to the underlying memory area */ struct memtype *mem; enum state state; - size_t len; /**< Length of the underlying memory area */ + size_t len; /**< Length of the underlying memory area */ - size_t blocksz; /**< Length of a block in bytes */ - size_t alignment; /**< Alignment of a block in bytes */ + size_t blocksz; /**< Length of a block in bytes */ + size_t alignment; /**< Alignment of a block in bytes */ struct queue queue; /**< The queue which is used to keep track of free blocks */ }; @@ -73,23 +73,27 @@ int pool_destroy(struct pool *p); * This number can be smaller than the requested \p cnt blocks * in case the pool currently holds less than \p cnt blocks. */ -INLINE ssize_t pool_get_many(struct pool *p, void *blocks[], size_t cnt) { +INLINE ssize_t pool_get_many(struct pool *p, void *blocks[], size_t cnt) +{ return queue_pull_many(&p->queue, blocks, cnt); } /** Push \p cnt values which are giving by the array values to the stack. */ -INLINE ssize_t pool_put_many(struct pool *p, void *blocks[], size_t cnt) { +INLINE ssize_t pool_put_many(struct pool *p, void *blocks[], size_t cnt) +{ return queue_push_many(&p->queue, blocks, cnt); } /** Get a free memory block from pool. */ -INLINE void *pool_get(struct pool *p) { +INLINE void * pool_get(struct pool *p) +{ void *ptr; return queue_pull(&p->queue, &ptr) == 1 ? ptr : NULL; } /** Release a memory block back to the pool. */ -INLINE int pool_put(struct pool *p, void *buf) { +INLINE int pool_put(struct pool *p, void *buf) +{ return queue_push(&p->queue, buf); } diff --git a/include/villas/queue.h b/include/villas/queue.h index e75a95368..3bc7c969a 100644 --- a/include/villas/queue.h +++ b/include/villas/queue.h @@ -33,9 +33,6 @@ #pragma once - - - #include #include #include @@ -121,4 +118,4 @@ int queue_close(struct queue *q); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/include/villas/sample.h b/include/villas/sample.h index 4102f7f00..fcc0326c2 100644 --- a/include/villas/sample.h +++ b/include/villas/sample.h @@ -21,8 +21,6 @@ * along with this program. If not, see . *********************************************************************************/ - - #pragma once #include "atomic.h" diff --git a/include/villas/signal.h b/include/villas/signal.h index 729cbb1f3..09487bda7 100644 --- a/include/villas/signal.h +++ b/include/villas/signal.h @@ -34,7 +34,7 @@ struct list; struct node; struct signal { - char *name; /**< The name of the signal. */ + char *name; /**< The name of the signal. */ char *unit; int enabled; enum { @@ -53,4 +53,4 @@ int signal_get_offset(const char *str, struct node *n); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/include/villas/stats.h b/include/villas/stats.h index 70b044f2d..0d3660232 100644 --- a/include/villas/stats.h +++ b/include/villas/stats.h @@ -44,19 +44,19 @@ enum stats_format { }; enum stats_id { - STATS_SKIPPED, /**< Counter for skipped samples due to hooks. */ - STATS_TIME, /**< The processing time per sample within VILLAsnode. */ - STATS_REORDERED, /**< Counter for reordered samples. */ - STATS_GAP_SAMPLE, /**< Histogram for inter sample timestamps (as sent by remote). */ - STATS_GAP_RECEIVED, /**< Histogram for inter sample arrival time (as seen by this instance). */ - STATS_OWD, /**< Histogram for one-way-delay (OWD) of received samples. */ - STATS_COUNT /**< Just here to have an updated number of statistics. */ + STATS_SKIPPED, /**< Counter for skipped samples due to hooks. */ + STATS_TIME, /**< The processing time per sample within VILLAsnode. */ + STATS_REORDERED, /**< Counter for reordered samples. */ + STATS_GAP_SAMPLE, /**< Histogram for inter sample timestamps (as sent by remote). */ + STATS_GAP_RECEIVED, /**< Histogram for inter sample arrival time (as seen by this instance). */ + STATS_OWD, /**< Histogram for one-way-delay (OWD) of received samples. */ + STATS_COUNT /**< Just here to have an updated number of statistics. */ }; struct stats_delta { double values[STATS_COUNT]; - int update; /**< Bitmask of stats_id. Only those which are masked will be updated */ + int update; /**< Bitmask of stats_id. Only those which are masked will be updated */ }; struct stats { @@ -77,7 +77,7 @@ void stats_collect(struct stats *s, struct sample *smps[], size_t cnt); int stats_commit(struct stats *s); -json_t *stats_json(struct stats *s); +json_t * stats_json(struct stats *s); void stats_reset(struct stats *s); @@ -90,8 +90,7 @@ void stats_print(struct stats *s, FILE *f, enum stats_format fmt, int verbose); enum stats_id stats_lookup_id(const char *name); +#endif /* _STATS_H_ */ #ifdef __cplusplus } #endif - -#endif /* _STATS_H_ */ diff --git a/include/villas/super_node.h b/include/villas/super_node.h index 4ff019119..d8f70e219 100644 --- a/include/villas/super_node.h +++ b/include/villas/super_node.h @@ -35,31 +35,31 @@ extern "C" { /** Global configuration */ struct super_node { - int priority; /**< Process priority (lower is better) */ - int affinity; /**< Process affinity of the server and all created threads */ - int hugepages; /**< Number of hugepages to reserve. */ - double stats; /**< Interval for path statistics. Set to 0 to disable them. */ + int priority; /**< Process priority (lower is better) */ + int affinity; /**< Process affinity of the server and all created threads */ + int hugepages; /**< Number of hugepages to reserve. */ + double stats; /**< Interval for path statistics. Set to 0 to disable them. */ - struct list nodes; - struct list paths; - struct list plugins; + struct list nodes; + struct list paths; + struct list plugins; - struct log log; - struct api api; - struct web web; + struct log log; + struct api api; + struct web web; - char *name; /**< A name of this super node. Usually the hostname. */ + char *name; /**< A name of this super node. Usually the hostname. */ - enum state state; + enum state state; - char *uri; /**< URI of configuration */ + char *uri; /**< URI of configuration */ - json_t *cfg; /**< JSON representation of the configuration. */ + json_t *cfg; /**< JSON representation of the configuration. */ }; /* Compatibility with libconfig < 1.5 */ #if (LIBCONFIG_VER_MAJOR <= 1) && (LIBCONFIG_VER_MINOR < 5) -#define config_setting_lookup config_lookup_from + #define config_setting_lookup config_lookup_from #endif /** Inititalize configuration object before parsing the configuration. */ @@ -90,4 +90,4 @@ int super_node_destroy(struct super_node *sn); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/include/villas/table.h b/include/villas/table.h index 9ecf0d8a1..579903d38 100644 --- a/include/villas/table.h +++ b/include/villas/table.h @@ -30,17 +30,17 @@ extern "C" { #endif struct table_column { - int width; /**< Width of the column. */ - char *title; /**< The title as shown in the table header. */ - char *format; /**< The format which is used to print the table rows. */ - char *unit; /**< An optional unit which will be shown in the table header. */ + int width; /**< Width of the column. */ + char *title; /**< The title as shown in the table header. */ + char *format; /**< The format which is used to print the table rows. */ + char *unit; /**< An optional unit which will be shown in the table header. */ enum { TABLE_ALIGN_LEFT, TABLE_ALIGN_RIGHT } align; - int _width; /**< The real width of this column. Calculated by table_header() */ + int _width; /**< The real width of this column. Calculated by table_header() */ }; struct table { @@ -58,8 +58,8 @@ void table_row(struct table *t, ...); /** Print the table footer. */ void table_footer(struct table *t); +/** @} */ + #ifdef __cplusplus } #endif - -/** @} */ diff --git a/include/villas/task.h b/include/villas/task.h index 30b029edd..07eadcb50 100644 --- a/include/villas/task.h +++ b/include/villas/task.h @@ -34,25 +34,25 @@ extern "C" { /** We can choose between two periodic task implementations */ //#define PERIODIC_TASK_IMPL NANOSLEEP -#define TIMERFD 1 -#define CLOCK_NANOSLEEP 2 -#define NANOSLEEP 3 +#define TIMERFD 1 +#define CLOCK_NANOSLEEP 2 +#define NANOSLEEP 3 #if defined(__MACH__) -#define PERIODIC_TASK_IMPL NANOSLEEP + #define PERIODIC_TASK_IMPL NANOSLEEP #elif defined(__linux__) -#define PERIODIC_TASK_IMPL TIMERFD + #define PERIODIC_TASK_IMPL TIMERFD #else -#error "Platform not supported" + #error "Platform not supported" #endif struct task { - int clock; /**< CLOCK_{MONOTONIC,REALTIME} */ + int clock; /**< CLOCK_{MONOTONIC,REALTIME} */ - struct timespec period; /**< The period of periodic invations of this task */ - struct timespec next; /**< The timer value for the next invocation */ + struct timespec period; /**< The period of periodic invations of this task */ + struct timespec next; /**< The timer value for the next invocation */ #if PERIODIC_TASK_IMPL == TIMERFD - int fd; /**< The timerfd_create(2) file descriptior. */ + int fd; /**< The timerfd_create(2) file descriptior. */ #endif }; @@ -81,4 +81,3 @@ int task_fd(struct task *t); #ifdef __cplusplus } #endif - diff --git a/include/villas/web.h b/include/villas/web.h index cb65c8775..37958d35e 100644 --- a/include/villas/web.h +++ b/include/villas/web.h @@ -39,13 +39,13 @@ struct web { enum state state; - struct lws_context *context; /**< The libwebsockets server context. */ - struct lws_vhost *vhost; /**< The libwebsockets vhost. */ + struct lws_context *context; /**< The libwebsockets server context. */ + struct lws_vhost *vhost; /**< The libwebsockets vhost. */ - int port; /**< Port of the build in HTTP / WebSocket server. */ - char *htdocs; /**< The root directory for files served via HTTP. */ - char *ssl_cert; /**< Path to the SSL certitifcate for HTTPS / WSS. */ - char *ssl_private_key; /**< Path to the SSL private key for HTTPS / WSS. */ + int port; /**< Port of the build in HTTP / WebSocket server. */ + char *htdocs; /**< The root directory for files served via HTTP. */ + char *ssl_cert; /**< Path to the SSL certitifcate for HTTPS / WSS. */ + char *ssl_private_key; /**< Path to the SSL private key for HTTPS / WSS. */ pthread_t thread; }; From 951c388f5377c8aa9494f6df1ffe5baac215ead9 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 29 Jun 2018 08:37:37 +0200 Subject: [PATCH 04/18] add/replace missing "#pragma once" --- include/villas/atomic.h | 3 ++- include/villas/compat.h | 18 ++++++------------ include/villas/stats.h | 4 +--- include/villas/table.h | 2 ++ 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/include/villas/atomic.h b/include/villas/atomic.h index ea3a7f8a4..25c8de132 100644 --- a/include/villas/atomic.h +++ b/include/villas/atomic.h @@ -21,6 +21,7 @@ * along with this program. If not, see . *********************************************************************************/ +#pragma once #include "common.h" @@ -38,4 +39,4 @@ typedef std::atomic atomic_state; typedef _Atomic enum state atomic_state; -#endif +#endif /* __cplusplus */ diff --git a/include/villas/compat.h b/include/villas/compat.h index c5a2275d5..1cac42afb 100644 --- a/include/villas/compat.h +++ b/include/villas/compat.h @@ -20,6 +20,8 @@ * along with this program. If not, see . *********************************************************************************/ +#pragma once + #include #ifdef __cplusplus @@ -30,17 +32,9 @@ extern "C" { size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags); #endif -#ifdef __cplusplus -} -#endif - #ifdef __MACH__ #include - #ifdef __cplusplus - extern "C"{ - #endif - #define le16toh(x) OSSwapLittleToHostInt16(x) #define le32toh(x) OSSwapLittleToHostInt32(x) #define le64toh(x) OSSwapLittleToHostInt64(x) @@ -54,8 +48,8 @@ size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags); #define htobe16(x) OSSwapHostToBigInt16(x) #define htobe32(x) OSSwapHostToBigInt32(x) #define htobe64(x) OSSwapHostToBigInt64(x) - - #ifdef __cplusplus - } - #endif #endif /* __MACH__ */ + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/stats.h b/include/villas/stats.h index 0d3660232..904023c62 100644 --- a/include/villas/stats.h +++ b/include/villas/stats.h @@ -21,8 +21,7 @@ * along with this program. If not, see . *********************************************************************************/ -#ifndef _STATS_H_ -#define _STATS_H_ +#pragma once #include #include @@ -90,7 +89,6 @@ void stats_print(struct stats *s, FILE *f, enum stats_format fmt, int verbose); enum stats_id stats_lookup_id(const char *name); -#endif /* _STATS_H_ */ #ifdef __cplusplus } #endif diff --git a/include/villas/table.h b/include/villas/table.h index 579903d38..18998b2c4 100644 --- a/include/villas/table.h +++ b/include/villas/table.h @@ -25,6 +25,8 @@ * @{ */ +#pragma once + #ifdef __cplusplus extern "C" { #endif From ffec25bbfd5c6ed68d86cec4e4c74f7cc730c813 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 29 Jun 2018 09:06:04 +0200 Subject: [PATCH 05/18] use "#include " path for all includes --- include/villas/advio.h | 2 +- include/villas/atomic.h | 2 +- include/villas/hook.h | 4 ++-- include/villas/io.h | 6 +++--- include/villas/mapping.h | 6 +++--- include/villas/node.h | 10 +++++----- include/villas/nodes/opal.h | 4 ++-- include/villas/path.h | 16 ++++++++-------- include/villas/pool.h | 6 +++--- include/villas/queue.h | 4 ++-- include/villas/sample.h | 2 +- include/villas/stats.h | 2 +- include/villas/super_node.h | 10 +++++----- include/villas/web.h | 2 +- 14 files changed, 38 insertions(+), 38 deletions(-) diff --git a/include/villas/advio.h b/include/villas/advio.h index d9eb904cf..15c56ebd8 100644 --- a/include/villas/advio.h +++ b/include/villas/advio.h @@ -26,7 +26,7 @@ #include -#include "crypt.h" +#include #ifdef __cplusplus extern "C"{ diff --git a/include/villas/atomic.h b/include/villas/atomic.h index 25c8de132..2ae1a84be 100644 --- a/include/villas/atomic.h +++ b/include/villas/atomic.h @@ -23,7 +23,7 @@ #pragma once -#include "common.h" +#include #ifdef __cplusplus diff --git a/include/villas/hook.h b/include/villas/hook.h index 9af46b333..e80f6a46a 100644 --- a/include/villas/hook.h +++ b/include/villas/hook.h @@ -34,8 +34,8 @@ #pragma once -#include "hook_type.h" -#include "common.h" +#include +#include #ifdef __cplusplus extern "C" { diff --git a/include/villas/io.h b/include/villas/io.h index 3370b26de..c9e8a07a6 100644 --- a/include/villas/io.h +++ b/include/villas/io.h @@ -23,9 +23,9 @@ #pragma once -#include "advio.h" -#include "common.h" -#include "node.h" +#include +#include +#include #ifdef __cplusplus extern "C" { diff --git a/include/villas/mapping.h b/include/villas/mapping.h index 1db78444e..5bee741f6 100644 --- a/include/villas/mapping.h +++ b/include/villas/mapping.h @@ -25,9 +25,9 @@ #include -#include "stats.h" -#include "common.h" -#include "list.h" +#include +#include +#include #ifdef __cplusplus extern "C" { diff --git a/include/villas/node.h b/include/villas/node.h index d8c5b4c58..85d376ded 100644 --- a/include/villas/node.h +++ b/include/villas/node.h @@ -32,11 +32,11 @@ #include #include -#include "node_type.h" -#include "sample.h" -#include "list.h" -#include "queue.h" -#include "common.h" +#include +#include +#include +#include +#include #ifdef __cplusplus extern "C"{ diff --git a/include/villas/nodes/opal.h b/include/villas/nodes/opal.h index 370b58957..10d96e514 100644 --- a/include/villas/nodes/opal.h +++ b/include/villas/nodes/opal.h @@ -31,8 +31,8 @@ #include -#include "node.h" -#include "msg.h" +#include +#include /* Define RTLAB before including OpalPrint.h for messages to be sent * to the OpalDisplay. Otherwise stdout will be used. */ diff --git a/include/villas/path.h b/include/villas/path.h index b8c2de58a..8df955f55 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -32,14 +32,14 @@ #include #include -#include "list.h" -#include "queue.h" -#include "pool.h" -#include "bitset.h" -#include "common.h" -#include "hook.h" -#include "mapping.h" -#include "task.h" +#include +#include +#include +#include +#include +#include +#include +#include #ifdef __cplusplus extern "C" { diff --git a/include/villas/pool.h b/include/villas/pool.h index c8075128d..d09b6452c 100644 --- a/include/villas/pool.h +++ b/include/villas/pool.h @@ -28,9 +28,9 @@ #include #include -#include "queue.h" -#include "common.h" -#include "memory.h" +#include +#include +#include #ifdef __cplusplus extern "C" { diff --git a/include/villas/queue.h b/include/villas/queue.h index 3bc7c969a..2c7b8c669 100644 --- a/include/villas/queue.h +++ b/include/villas/queue.h @@ -37,8 +37,8 @@ #include #include -#include "atomic.h" -#include "common.h" +#include +#include #ifdef __cplusplus extern "C"{ diff --git a/include/villas/sample.h b/include/villas/sample.h index fcc0326c2..83e4e6334 100644 --- a/include/villas/sample.h +++ b/include/villas/sample.h @@ -23,7 +23,7 @@ #pragma once -#include "atomic.h" +#include #include #include diff --git a/include/villas/stats.h b/include/villas/stats.h index 904023c62..2ee375889 100644 --- a/include/villas/stats.h +++ b/include/villas/stats.h @@ -26,7 +26,7 @@ #include #include -#include "hist.h" +#include #ifdef __cplusplus extern "C" { diff --git a/include/villas/super_node.h b/include/villas/super_node.h index d8f70e219..71d172e63 100644 --- a/include/villas/super_node.h +++ b/include/villas/super_node.h @@ -23,11 +23,11 @@ #pragma once -#include "list.h" -#include "api.h" -#include "web.h" -#include "log.h" -#include "common.h" +#include +#include +#include +#include +#include #ifdef __cplusplus extern "C" { diff --git a/include/villas/web.h b/include/villas/web.h index 37958d35e..c7b06ea95 100644 --- a/include/villas/web.h +++ b/include/villas/web.h @@ -25,7 +25,7 @@ #include -#include "common.h" +#include #ifdef __cplusplus extern "C" { From eb446d2ac920490d77a53467de010fa8a91ec63b Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 29 Jun 2018 09:07:47 +0200 Subject: [PATCH 06/18] add missing GPL license header --- include/villas/list.h | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/include/villas/list.h b/include/villas/list.h index e1d796628..16d003f5c 100644 --- a/include/villas/list.h +++ b/include/villas/list.h @@ -8,7 +8,22 @@ * * @file * @author Steffen Vogel - * @copyright 20177, Institute for Automation of Complex Power Systems, EONERC + * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC +* + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . *********************************************************************************/ #pragma once @@ -127,4 +142,4 @@ ssize_t list_index(struct list *l, void *value); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif From f66af243ae2343d9d42fe476a9d7a46236da675c Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 29 Jun 2018 14:34:57 +0200 Subject: [PATCH 07/18] add missing dependency to Dockerfile --- packaging/docker/Dockerfile.dev | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/docker/Dockerfile.dev b/packaging/docker/Dockerfile.dev index a20728ea1..20fee6ef9 100644 --- a/packaging/docker/Dockerfile.dev +++ b/packaging/docker/Dockerfile.dev @@ -78,7 +78,7 @@ RUN dnf -y install \ libiec61850-devel \ librabbitmq-devel \ mosquitto-devel \ - comedilib-devel + comedilib-devel comedilib # Build & Install Criterion RUN cd /tmp && \ From 832c2857d81fc223c68ddf6c4e7680586cc59418 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 29 Jun 2018 14:35:22 +0200 Subject: [PATCH 08/18] add missing dependency to RPM specfile --- packaging/rpm/villas-node.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/rpm/villas-node.spec b/packaging/rpm/villas-node.spec index 6570b0090..71a8a3255 100644 --- a/packaging/rpm/villas-node.spec +++ b/packaging/rpm/villas-node.spec @@ -14,7 +14,7 @@ BuildRequires: gcc pkgconfig make Requires: iproute module-init-tools -BuildRequires: openssl-devel libconfig-devel libnl3-devel libcurl-devel jansson-devel libwebsockets-devel zeromq-devel nanomsg-devel libiec61850-devel librabbitmq-devel mosquitto-devel comedilib-devel +BuildRequires: openssl-devel libconfig-devel libnl3-devel libcurl-devel jansson-devel libwebsockets-devel zeromq-devel nanomsg-devel libiec61850-devel librabbitmq-devel mosquitto-devel comedilib-devel comedilib Requires: openssl libconfig libnl3 libcurl jansson libwebsockets zeromq nanomsg libiec61850 librabbitmq mosquitto comedilib %description From 7860c38bfe99b466659b4351d514ab43aa93de31 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 2 Jul 2018 10:51:01 +0200 Subject: [PATCH 09/18] plugins: improve documentation of REGISTER_PLUGIN macro --- include/villas/plugin.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/include/villas/plugin.h b/include/villas/plugin.h index d373ab338..a015c2e49 100644 --- a/include/villas/plugin.h +++ b/include/villas/plugin.h @@ -35,7 +35,17 @@ extern "C"{ #endif -/** @todo This is ugly as hell and broken on OS X / Clang anyway. */ +/** (De-)Register a plugin by adding it to the global plugin list. + * + * We make use of GCC's / Clang's constructor/destructor function + * attributes to let the following code be executed by the loader. + * This works only when we compile libvillas as a shared library! + * + * The __attribute__((constructor)) / __attribute__((destructor)) + * is currently only supported by GCC and Clang + * + * See: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes + */ #define REGISTER_PLUGIN(p) \ __attribute__((constructor(110))) static void UNIQUE(__ctor)() {\ if (plugins.state == STATE_DESTROYED) \ @@ -102,4 +112,4 @@ struct plugin * plugin_lookup(enum plugin_type type, const char *name); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif From f500cfa1e61c44ce3ec14e3910d7c7d3fa813610 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 2 Jul 2018 10:51:27 +0200 Subject: [PATCH 10/18] memory: update link and explanation of munmap() on hugepages --- lib/memory.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/memory.c b/lib/memory.c index 4877ee01a..246be848a 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -147,7 +147,11 @@ static void * memory_hugepage_alloc(struct memtype *m, size_t len, size_t alignm static int memory_hugepage_free(struct memtype *m, void *ptr, size_t len) { - len = ALIGN(len, HUGEPAGESIZE); /* ugly see: https://lkml.org/lkml/2015/3/27/171 */ + /** We must make sure that len is a multiple of the hugepage size + * + * See: https://lkml.org/lkml/2014/10/22/925 + */ + len = ALIGN(len, HUGEPAGESIZE); return munmap(ptr, len); } From b9f463ebee9de956389909823445e334b4bf1028 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 2 Jul 2018 10:59:45 +0200 Subject: [PATCH 11/18] node: extend struct node_type with a new function pointer for checking node configuration --- include/villas/node_type.h | 8 ++++++++ lib/node.c | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/include/villas/node_type.h b/include/villas/node_type.h index dcee596d0..39f0bfd17 100644 --- a/include/villas/node_type.h +++ b/include/villas/node_type.h @@ -88,6 +88,14 @@ struct node_type { */ int (*parse)(struct node *n, json_t *cfg); + /** Check the current node configuration for plausability and errors. + * + * @param n A pointer to the node object. + * @retval 0 Success. Node configuration is good. + * @retval <0 Error. The node configuration is bogus. + */ + int (*check)(struct node *n); + /** Parse node from command line arguments. */ int (*parse_cli)(struct node *n, int argc, char *argv[]); diff --git a/lib/node.c b/lib/node.c index 7a8c02f99..77d9b522f 100644 --- a/lib/node.c +++ b/lib/node.c @@ -308,6 +308,10 @@ int node_check(struct node *n) if (ret) return ret; + ret = n->_vt->check ? n->_vt->check(n) : 0; + if (ret) + return ret; + n->state = STATE_CHECKED; return 0; From 8e252bbb4b678b76206ec278c3d52f07ce4e7191 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 2 Jul 2018 13:07:45 +0200 Subject: [PATCH 12/18] hash_table: added simple hash table with linked lists --- include/villas/common.h | 6 ++ include/villas/hash_table.h | 75 +++++++++++++ include/villas/list.h | 8 +- lib/Makefile.villas.inc | 1 + lib/hash_table.c | 202 ++++++++++++++++++++++++++++++++++++ 5 files changed, 285 insertions(+), 7 deletions(-) create mode 100644 include/villas/hash_table.h create mode 100644 lib/hash_table.c diff --git a/include/villas/common.h b/include/villas/common.h index d6ac417a2..64de9bb8c 100644 --- a/include/villas/common.h +++ b/include/villas/common.h @@ -41,6 +41,12 @@ enum state { STATE_CLOSED = 5 /* alias for STATE_STARTED used by struct io */ }; +/** Callback to destroy list elements. + * + * @param data A pointer to the data which should be freed. + */ +typedef int (*dtor_cb_t)(void *); + #ifdef __cplusplus } #endif diff --git a/include/villas/hash_table.h b/include/villas/hash_table.h new file mode 100644 index 000000000..d8a79f873 --- /dev/null +++ b/include/villas/hash_table.h @@ -0,0 +1,75 @@ +/** A generic hash table + * + * @author Steffen Vogel + * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#include +#include + +#include + +struct hash_table_entry { + void *key; + void *data; + + struct hash_table_entry *next; +}; + +/** A thread-safe hash table using separate chaing with linked lists. */ +struct hash_table { + enum state state; + + struct hash_table_entry **table; + + size_t size; + pthread_mutex_t lock; +}; + +/** Initialize a new hash table. + * + */ +int hash_table_init(struct hash_table *ht, size_t size); + +/** Destroy a hash table. + * + * + */ +int hash_table_destroy(struct hash_table *ht, dtor_cb_t dtor, bool release); + +/** Insert a new key/value pair into the hash table. + * + */ +int hash_table_insert(struct hash_table *ht, void *key, void *data); + +/** Delete a key from the hash table. + * + * + */ +int hash_table_delete(struct hash_table *ht, void *key); + +/** Perform a lookup in the hash table. + * + * @retval != NULL The value for the given key. + * @retval NULL The given key is not stored in the hash table. + */ +void * hash_table_lookup(struct hash_table *ht, void *key); + +/** Dump the contents of the hash table in a human readable format to stdout. */ +void hash_table_dump(struct hash_table *ht); diff --git a/include/villas/list.h b/include/villas/list.h index 16d003f5c..ab79d6774 100644 --- a/include/villas/list.h +++ b/include/villas/list.h @@ -32,7 +32,7 @@ #include #include -#include "common.h" +#include #ifdef __cplusplus extern "C"{ @@ -65,12 +65,6 @@ __attribute__((destructor(105))) static void UNIQUE(__dtor)() { \ #define list_first(list) list_at(list, 0) #define list_last(list) list_at(list, (list)->length-1) -/** Callback to destroy list elements. - * - * @param data A pointer to the data which should be freed. - */ -typedef int (*dtor_cb_t)(void *); - /** Callback to search or sort a list. */ typedef int (*cmp_cb_t)(const void *, const void *); diff --git a/lib/Makefile.villas.inc b/lib/Makefile.villas.inc index dc0a3ca0a..68ff0b83d 100644 --- a/lib/Makefile.villas.inc +++ b/lib/Makefile.villas.inc @@ -31,6 +31,7 @@ LIB_SRCS += $(addprefix lib/kernel/, kernel.c rt.c) \ queue_signalled.c memory.c advio.c plugin.c node_type.c stats.c \ mapping.c shmem.c config_helper.c crypt.c compat.c \ log_helper.c task.c buffer.c table.c bitset.c signal.c \ + hash_table.c \ ) LIB_LDFLAGS += -shared diff --git a/lib/hash_table.c b/lib/hash_table.c new file mode 100644 index 000000000..2fb88aa88 --- /dev/null +++ b/lib/hash_table.c @@ -0,0 +1,202 @@ +/** A generic hash table + * + * @author Steffen Vogel + * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#include + +#include +#include + +static int hash_table_hash(struct hash_table *ht, void *key) +{ + uintptr_t ptr = (uintptr_t) key; + + return ptr % ht->size; +} + +int hash_table_init(struct hash_table *ht, size_t size) +{ + int ret; + size_t len = sizeof(struct hash_table_entry *) * size; + + assert(ht->state == STATE_DESTROYED); + + ret = pthread_mutex_init(&ht->lock, NULL); + if (ret) + return ret; + + ht->table = alloc(len); + + memset(ht->table, 0, len); + + ht->size = size; + ht->state = STATE_INITIALIZED; + + return 0; +} + +int hash_table_destroy(struct hash_table *ht, dtor_cb_t dtor, bool release) +{ + int ret; + struct hash_table_entry *cur, *next; + + assert(ht->state == STATE_INITIALIZED); + + pthread_mutex_lock(&ht->lock); + + for (int i = 0; i < ht->size; i++) { + for (cur = ht->table[i]; cur; cur = next) { + if (dtor) + dtor(cur->data); + + if (release) + free(cur->data); + + next = cur->next; + + free(cur); + } + } + + pthread_mutex_unlock(&ht->lock); + + ret = pthread_mutex_destroy(&ht->lock); + if (ret) + return ret; + + free(ht->table); + + ht->state = STATE_DESTROYED; + + return 0; +} + +int hash_table_insert(struct hash_table *ht, void *key, void *data) +{ + int ret, ikey = hash_table_hash(ht, key); + struct hash_table_entry *hte, *cur; + + assert(ht->state == STATE_INITIALIZED); + + pthread_mutex_lock(&ht->lock); + + /* Check that the key is not already in the table */ + for (cur = ht->table[ikey]; + cur && cur->key != key; + cur = cur->next); + + if (cur) + ret = -1; + else { + hte = alloc(sizeof(struct hash_table_entry)); + if (hte) { + hte->key = key; + hte->data = data; + hte->next = NULL; + + if ((cur = ht->table[ikey])) + hte->next = ht->table[ikey]; + + ht->table[ikey] = hte; + + ret = 0; + } + else + ret = -1; + } + + pthread_mutex_unlock(&ht->lock); + + return ret; +} + +#include + +int hash_table_delete(struct hash_table *ht, void *key) +{ + int ret, ikey = hash_table_hash(ht, key); + struct hash_table_entry *cur, *prev; + + assert(ht->state == STATE_INITIALIZED); + + pthread_mutex_lock(&ht->lock); + + for (prev = NULL, + cur = ht->table[ikey]; + cur && cur->key != key; + prev = cur, + cur = cur->next); + + if (cur) { + if (prev) + prev->next = cur->next; + else + ht->table[ikey] = cur->next; + + free(cur); + + ret = 0; + } + else + ret = -1; /* not found */ + + pthread_mutex_unlock(&ht->lock); + + return ret; +} + +void * hash_table_lookup(struct hash_table *ht, void *key) +{ + int ikey = hash_table_hash(ht, key); + struct hash_table_entry *hte; + + assert(ht->state == STATE_INITIALIZED); + + pthread_mutex_lock(&ht->lock); + + for (hte = ht->table[ikey]; + hte && hte->key != key; + hte = hte->next); + + void *data = hte ? hte->data : NULL; + + pthread_mutex_unlock(&ht->lock); + + return data; +} + +void hash_table_dump(struct hash_table *ht) +{ + struct hash_table_entry *hte; + + assert(ht->state == STATE_INITIALIZED); + + pthread_mutex_lock(&ht->lock); + + for (int i = 0; i < ht->size; i++) { + printf("%i: ", i); + for (hte = ht->table[i]; hte; hte = hte->next) + printf("%p->%p ", hte->key, hte->data); + printf("\n"); + } + + pthread_mutex_unlock(&ht->lock); +} From d5fa35b62e863739e06fce3ab51a484ccded839e Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 2 Jul 2018 13:08:01 +0200 Subject: [PATCH 13/18] hash_table: added simple unit test for hash table --- tests/unit/hash_table.c | 71 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 tests/unit/hash_table.c diff --git a/tests/unit/hash_table.c b/tests/unit/hash_table.c new file mode 100644 index 000000000..362c42e69 --- /dev/null +++ b/tests/unit/hash_table.c @@ -0,0 +1,71 @@ +/** Unit tests for hash table + * + * @author Steffen Vogel + * @copyright 2018, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#include + +#include +#include + +static char *keys[] = { "able", "achieve", "acoustics", "action", "activity", "aftermath", "afternoon", "afterthought", "apparel", "appliance", "beginner", "believe", "bomb", "border", "boundary", "breakfast", "cabbage", "cable", "calculator", "calendar", "caption", "carpenter", "cemetery", "channel", "circle", "creator", "creature", "education", "faucet", "feather", "friction", "fruit", "fuel", "galley", "guide", "guitar", "health", "heart", "idea", "kitten", "laborer", "language" }; +static char *values[] = { "lawyer", "linen", "locket", "lumber", "magic", "minister", "mitten", "money", "mountain", "music", "partner", "passenger", "pickle", "picture", "plantation", "plastic", "pleasure", "pocket", "police", "pollution", "railway", "recess", "reward", "route", "scene", "scent", "squirrel", "stranger", "suit", "sweater", "temper", "territory", "texture", "thread", "treatment", "veil", "vein", "volcano", "wealth", "weather", "wilderness", "wren" }; + +Test(hash_table, hash_table_lookup) +{ + int ret; + struct hash_table ht = { .state = STATE_DESTROYED }; + + ret = hash_table_init(&ht, 20); + cr_assert(!ret); + + /* Insert */ + for (int i = 0; i < ARRAY_LEN(keys); i++) { + ret = hash_table_insert(&ht, keys[i], values[i]); + cr_assert(!ret); + } + + /* Lookup */ + for (int i = 0; i < ARRAY_LEN(keys); i++) { + char *value = hash_table_lookup(&ht, keys[i]); + cr_assert_eq(values[i], value); + } + + /* Inserting the same key twice should fail */ + ret = hash_table_insert(&ht, keys[0], values[0]); + cr_assert(ret); + + hash_table_dump(&ht); + + /* Removing an entry */ + ret = hash_table_delete(&ht, keys[0]); + cr_assert(!ret); + + /* Removing the same entry twice should fail */ + ret = hash_table_delete(&ht, keys[0]); + cr_assert(ret); + + /* After removing, we should be able to insert it again */ + ret = hash_table_insert(&ht, keys[0], values[0]); + cr_assert(!ret); + + ret = hash_table_destroy(&ht, NULL, false); + cr_assert(!ret); +} From bb70be0b2ce9b419242f496b27d982923d3a7e1d Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 2 Jul 2018 14:17:50 +0200 Subject: [PATCH 14/18] memory: refactored memory subsystem --- include/villas/memory.h | 42 +----- include/villas/memory_type.h | 69 +++++++++ include/villas/node.h | 2 +- include/villas/node_type.h | 2 +- include/villas/pool.h | 4 +- include/villas/queue.h | 6 +- include/villas/queue_signalled.h | 2 +- lib/Makefile.villas.inc | 3 +- lib/api.c | 2 +- lib/api/session.c | 4 +- lib/memory.c | 245 +------------------------------ lib/memory/heap.c | 54 +++++++ lib/memory/hugepage.c | 86 +++++++++++ lib/{memory_ib.c => memory/ib.c} | 15 +- lib/memory/managed.c | 193 ++++++++++++++++++++++++ lib/node.c | 4 +- lib/nodes/iec61850_sv.c | 4 +- lib/nodes/infiniband.c | 8 +- lib/nodes/loopback.c | 4 +- lib/nodes/mqtt.c | 4 +- lib/nodes/websocket.c | 6 +- lib/path.c | 6 +- lib/pool.c | 2 +- lib/queue.c | 2 +- lib/queue_signalled.c | 2 +- lib/shmem.c | 10 +- src/hook.c | 2 +- src/pipe.c | 4 +- src/signal.c | 2 +- src/test-cmp.c | 2 +- tests/unit/io.c | 4 +- tests/unit/memory.c | 18 ++- tests/unit/pool.c | 12 +- tests/unit/queue.c | 18 +-- tests/unit/queue_signalled.c | 2 +- 35 files changed, 496 insertions(+), 349 deletions(-) create mode 100644 include/villas/memory_type.h create mode 100644 lib/memory/heap.c create mode 100644 lib/memory/hugepage.c rename lib/{memory_ib.c => memory/ib.c} (84%) create mode 100644 lib/memory/managed.c diff --git a/include/villas/memory.h b/include/villas/memory.h index 54da2bbc0..95ee21972 100644 --- a/include/villas/memory.h +++ b/include/villas/memory.h @@ -26,35 +26,14 @@ #include #include +#include + #ifdef __cplusplus extern "C" { #endif -#define HUGEPAGESIZE (1 << 21) - -struct memtype; - -typedef void *(*memzone_allocator_t)(struct memtype *mem, size_t len, size_t alignment); -typedef int (*memzone_deallocator_t)(struct memtype *mem, void *ptr, size_t len); - -enum memtype_flags { - MEMORY_MMAP = (1 << 0), - MEMORY_DMA = (1 << 1), - MEMORY_HUGEPAGE = (1 << 2), - MEMORY_HEAP = (1 << 3) -}; - -struct memtype { - const char *name; - int flags; - - size_t alignment; - - memzone_allocator_t alloc; - memzone_deallocator_t free; - - void *_vd; /**0 If allocation was successful. */ -void * memory_alloc(struct memtype *m, size_t len); +void * memory_alloc(struct memory_type *m, size_t len); -void * memory_alloc_aligned(struct memtype *m, size_t len, size_t alignment); +void * memory_alloc_aligned(struct memory_type *m, size_t len, size_t alignment); -int memory_free(struct memtype *m, void *ptr, size_t len); - -struct memtype * memtype_managed_init(void *ptr, size_t len); - -extern struct memtype memtype_heap; -extern struct memtype memtype_hugepage; +int memory_free(struct memory_type *m, void *ptr, size_t len); #ifdef __cplusplus } diff --git a/include/villas/memory_type.h b/include/villas/memory_type.h new file mode 100644 index 000000000..4daae7bfd --- /dev/null +++ b/include/villas/memory_type.h @@ -0,0 +1,69 @@ +/** Memory allocators. + * + * @file + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct memory_type; + +typedef void *(*memzone_allocator_t)(struct memory_type *mem, size_t len, size_t alignment); +typedef int (*memzone_deallocator_t)(struct memory_type *mem, void *ptr, size_t len); + +enum memory_type_flags { + MEMORY_MMAP = (1 << 0), + MEMORY_DMA = (1 << 1), + MEMORY_HUGEPAGE = (1 << 2), + MEMORY_HEAP = (1 << 3) +}; + +struct memory_type { + const char *name; + int flags; + + size_t alignment; + + memzone_allocator_t alloc; + memzone_deallocator_t free; + + void *_vd; /**< Virtual data for internal state */ +}; + +extern struct memory_type memory_type_heap; +extern struct memory_type memory_hugepage; + +struct ibv_mr * memory_type_ib_mr(void *ptr); + +struct node; + +struct memory_type * memory_ib(struct node *n, struct memory_type *parent); +struct memory_type * memory_managed(void *ptr, size_t len); + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/node.h b/include/villas/node.h index 60857489d..b63acb2cc 100644 --- a/include/villas/node.h +++ b/include/villas/node.h @@ -162,7 +162,7 @@ int node_write(struct node *n, struct sample *smps[], unsigned cnt); int node_fd(struct node *n); -struct memtype * node_memtype(struct node *n, struct memtype *parent); +struct memory_type * node_memory_type(struct node *n, struct memory_type *parent); #ifdef __cplusplus } diff --git a/include/villas/node_type.h b/include/villas/node_type.h index b34eb8d8f..b9026b1d3 100644 --- a/include/villas/node_type.h +++ b/include/villas/node_type.h @@ -164,7 +164,7 @@ struct node_type { int (*fd)(struct node *n); /** */ - struct memtype * (*memtype)(struct node *n, struct memtype *parent); + struct memory_type * (*memory_type)(struct node *n, struct memory_type *parent); }; /** Initialize all registered node type subsystems. diff --git a/include/villas/pool.h b/include/villas/pool.h index d09b6452c..7ab23a3c4 100644 --- a/include/villas/pool.h +++ b/include/villas/pool.h @@ -39,7 +39,7 @@ extern "C" { /** A thread-safe memory pool */ struct pool { off_t buffer_off; /**< Offset from the struct address to the underlying memory area */ - struct memtype *mem; + struct memory_type *mem; enum state state; @@ -62,7 +62,7 @@ struct pool { * @retval 0 The pool has been successfully initialized. * @retval <>0 There was an error during the pool initialization. */ -int pool_init(struct pool *p, size_t cnt, size_t blocksz, struct memtype *mem); +int pool_init(struct pool *p, size_t cnt, size_t blocksz, struct memory_type *mem); /** Destroy and release memory used by pool. */ int pool_destroy(struct pool *p); diff --git a/include/villas/queue.h b/include/villas/queue.h index 2c7b8c669..b1630d28c 100644 --- a/include/villas/queue.h +++ b/include/villas/queue.h @@ -45,7 +45,7 @@ extern "C"{ #endif /* Forward declarations */ -struct memtype; +struct memory_type; #define CACHELINE_SIZE 64 typedef char cacheline_pad_t[CACHELINE_SIZE]; @@ -61,7 +61,7 @@ struct queue { atomic_state state; - struct memtype *mem; + struct memory_type *mem; size_t buffer_mask; off_t buffer_off; /**< Relative pointer to struct queue_cell[] */ @@ -77,7 +77,7 @@ struct queue { }; /** Initialize MPMC queue */ -int queue_init(struct queue *q, size_t size, struct memtype *mem); +int queue_init(struct queue *q, size_t size, struct memory_type *mem); /** Desroy MPMC queue and release memory */ int queue_destroy(struct queue *q); diff --git a/include/villas/queue_signalled.h b/include/villas/queue_signalled.h index 2d2a44fb3..0b73e7c5b 100644 --- a/include/villas/queue_signalled.h +++ b/include/villas/queue_signalled.h @@ -68,7 +68,7 @@ struct queue_signalled { #define queue_signalled_available(q) queue_available(&((q)->queue)) -int queue_signalled_init(struct queue_signalled *qs, size_t size, struct memtype *mem, int flags); +int queue_signalled_init(struct queue_signalled *qs, size_t size, struct memory_type *mem, int flags); int queue_signalled_destroy(struct queue_signalled *qs); diff --git a/lib/Makefile.villas.inc b/lib/Makefile.villas.inc index 120161f72..963d98511 100644 --- a/lib/Makefile.villas.inc +++ b/lib/Makefile.villas.inc @@ -26,9 +26,10 @@ LIB = $(BUILDDIR)/$(LIB_NAME).so.$(LIB_ABI_VERSION) # Object files for libvillas LIB_SRCS += $(addprefix lib/kernel/, kernel.c rt.c) \ + $(addprefix lib/memory/, heap.c hugepage.c ib.c managed.c) \ $(addprefix lib/, sample.c path.c node.c hook.c log.c log_config.c \ utils.c super_node.c hist.c timing.c pool.c list.c queue.c \ - queue_signalled.c memory.c memory_ib.c advio.c plugin.c node_type.c stats.c \ + queue_signalled.c memory.c advio.c plugin.c node_type.c stats.c \ mapping.c shmem.c config_helper.c crypt.c compat.c \ log_helper.c task.c buffer.c table.c bitset.c signal.c \ hash_table.c \ diff --git a/lib/api.c b/lib/api.c index 8ea079949..dbf31c23d 100644 --- a/lib/api.c +++ b/lib/api.c @@ -272,7 +272,7 @@ int api_init(struct api *a, struct super_node *sn) if (ret) return ret; - ret = queue_signalled_init(&a->pending, 1024, &memtype_heap, 0); + ret = queue_signalled_init(&a->pending, 1024, &memory_type_heap, 0); if (ret) return ret; diff --git a/lib/api/session.c b/lib/api/session.c index 8ad155efe..e421bff79 100644 --- a/lib/api/session.c +++ b/lib/api/session.c @@ -40,11 +40,11 @@ int api_session_init(struct api_session *s, enum api_mode m) if (ret) return ret; - ret = queue_init(&s->request.queue, 128, &memtype_heap); + ret = queue_init(&s->request.queue, 128, &memory_type_heap); if (ret) return ret; - ret = queue_init(&s->response.queue, 128, &memtype_heap); + ret = queue_init(&s->response.queue, 128, &memory_type_heap); if (ret) return ret; diff --git a/lib/memory.c b/lib/memory.c index 246be848a..34f1f299c 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -25,21 +25,13 @@ #include #include -#include #include #include -#include - -/* Required to allocate hugepages on Apple OS X */ -#ifdef __MACH__ - #include -#elif defined(__linux__) - #include -#endif #include #include #include +#include int memory_init(int hugepages) { @@ -77,7 +69,7 @@ int memory_init(int hugepages) return 0; } -void * memory_alloc(struct memtype *m, size_t len) +void * memory_alloc(struct memory_type *m, size_t len) { void *ptr = m->alloc(m, len, sizeof(void *)); @@ -86,7 +78,7 @@ void * memory_alloc(struct memtype *m, size_t len) return ptr; } -void * memory_alloc_aligned(struct memtype *m, size_t len, size_t alignment) +void * memory_alloc_aligned(struct memory_type *m, size_t len, size_t alignment) { void *ptr = m->alloc(m, len, alignment); @@ -95,238 +87,9 @@ void * memory_alloc_aligned(struct memtype *m, size_t len, size_t alignment) return ptr; } -int memory_free(struct memtype *m, void *ptr, size_t len) +int memory_free(struct memory_type *m, void *ptr, size_t len) { debug(LOG_MEM | 5, "Releasing %#zx bytes of %s memory", len, m->name); return m->free(m, ptr, len); } - -static void * memory_heap_alloc(struct memtype *m, size_t len, size_t alignment) -{ - void *ptr; - int ret; - - if (alignment < sizeof(void *)) - alignment = sizeof(void *); - - ret = posix_memalign(&ptr, alignment, len); - - return ret ? NULL : ptr; -} - -int memory_heap_free(struct memtype *m, void *ptr, size_t len) -{ - free(ptr); - - return 0; -} - -/** Allocate memory backed by hugepages with malloc() like interface */ -static void * memory_hugepage_alloc(struct memtype *m, size_t len, size_t alignment) -{ - void *ret; - int prot = PROT_READ | PROT_WRITE; - int flags = MAP_PRIVATE | MAP_ANONYMOUS; - -#ifdef __MACH__ - flags |= VM_FLAGS_SUPERPAGE_SIZE_2MB; -#elif defined(__linux__) - flags |= MAP_HUGETLB; - - if (getuid() == 0) - flags |= MAP_LOCKED; -#endif - - ret = mmap(NULL, len, prot, flags, -1, 0); - if (ret == MAP_FAILED) - return NULL; - - return ret; -} - -static int memory_hugepage_free(struct memtype *m, void *ptr, size_t len) -{ - /** We must make sure that len is a multiple of the hugepage size - * - * See: https://lkml.org/lkml/2014/10/22/925 - */ - len = ALIGN(len, HUGEPAGESIZE); - - return munmap(ptr, len); -} - -void* memory_managed_alloc(struct memtype *m, size_t len, size_t alignment) -{ - /* Simple first-fit allocation */ - struct memblock *first = (struct memblock *) m->_vd; - struct memblock *block; - - for (block = first; block != NULL; block = block->next) { - if (block->flags & MEMBLOCK_USED) - continue; - - char* cptr = (char *) block + sizeof(struct memblock); - size_t avail = block->len; - uintptr_t uptr = (uintptr_t) cptr; - - /* Check alignment first; leave a gap at start of block to assure - * alignment if necessary */ - uintptr_t rem = uptr % alignment; - uintptr_t gap = 0; - if (rem != 0) { - gap = alignment - rem; - if (gap > avail) - continue; /* Next aligned address isn't in this block anymore */ - - cptr += gap; - avail -= gap; - } - - if (avail >= len) { - if (gap > sizeof(struct memblock)) { - /* The alignment gap is big enough to fit another block. - * The original block descriptor is already at the correct - * position, so we just change its len and create a new block - * descriptor for the actual block we're handling. */ - block->len = gap - sizeof(struct memblock); - struct memblock *newblock = (struct memblock *) (cptr - sizeof(struct memblock)); - newblock->prev = block; - newblock->next = block->next; - block->next = newblock; - newblock->flags = 0; - newblock->len = len; - block = newblock; - } - else { - /* The gap is too small to fit another block descriptor, so we - * must account for the gap length in the block length. */ - block->len = len + gap; - } - - if (avail > len + sizeof(struct memblock)) { - /* Imperfect fit, so create another block for the remaining part */ - struct memblock *newblock = (struct memblock *) (cptr + len); - newblock->prev = block; - newblock->next = block->next; - block->next = newblock; - if (newblock->next) - newblock->next->prev = newblock; - newblock->flags = 0; - newblock->len = avail - len - sizeof(struct memblock); - } - else { - /* If this block was larger than the requested length, but only - * by less than sizeof(struct memblock), we may have wasted - * memory by previous assignments to block->len. */ - block->len = avail; - } - - block->flags |= MEMBLOCK_USED; - - return (void *) cptr; - } - } - - /* No suitable block found */ - return NULL; -} - -int memory_managed_free(struct memtype *m, void *ptr, size_t len) -{ - struct memblock *first = (struct memblock *) m->_vd; - struct memblock *block; - char *cptr = ptr; - - for (block = first; block != NULL; block = block->next) { - if (!(block->flags & MEMBLOCK_USED)) - continue; - - /* Since we may waste some memory at the start of a block to ensure - * alignment, ptr may not actually be the start of the block */ - if ((char *) block + sizeof(struct memblock) <= cptr && - cptr < (char *) block + sizeof(struct memblock) + block->len) { - /* Try to merge it with neighbouring free blocks */ - if (block->prev && !(block->prev->flags & MEMBLOCK_USED) && - block->next && !(block->next->flags & MEMBLOCK_USED)) { - /* Special case first: both previous and next block are unused */ - block->prev->len += block->len + block->next->len + 2 * sizeof(struct memblock); - block->prev->next = block->next->next; - if (block->next->next) - block->next->next->prev = block->prev; - } - else if (block->prev && !(block->prev->flags & MEMBLOCK_USED)) { - block->prev->len += block->len + sizeof(struct memblock); - block->prev->next = block->next; - if (block->next) - block->next->prev = block->prev; - } - else if (block->next && !(block->next->flags & MEMBLOCK_USED)) { - block->len += block->next->len + sizeof(struct memblock); - block->next = block->next->next; - if (block->next) - block->next->prev = block; - } - else { - /* no neighbouring free block, so just mark it as free */ - block->flags &= ~MEMBLOCK_USED; - } - - return 0; - } - } - - return -1; -} - -struct memtype * memtype_managed_init(void *ptr, size_t len) -{ - struct memtype *mt = ptr; - struct memblock *mb; - char *cptr = ptr; - - if (len < sizeof(struct memtype) + sizeof(struct memblock)) { - info("memtype_managed_init: passed region too small"); - return NULL; - } - - /* Initialize memtype */ - mt->name = "managed"; - mt->flags = 0; - mt->alloc = memory_managed_alloc; - mt->free = memory_managed_free; - mt->alignment = 1; - - cptr += ALIGN(sizeof(struct memtype), sizeof(void *)); - - /* Initialize first free memblock */ - mb = (struct memblock *) cptr; - mb->prev = NULL; - mb->next = NULL; - mb->flags = 0; - - cptr += ALIGN(sizeof(struct memblock), sizeof(void *)); - - mb->len = len - (cptr - (char *) ptr); - - mt->_vd = (void *) mb; - - return mt; -} - -/* List of available memory types */ -struct memtype memtype_heap = { - .name = "heap", - .flags = MEMORY_HEAP, - .alloc = memory_heap_alloc, - .free = memory_heap_free, - .alignment = 1 -}; - -struct memtype memtype_hugepage = { - .name = "mmap_hugepages", - .flags = MEMORY_MMAP | MEMORY_HUGEPAGE, - .alloc = memory_hugepage_alloc, - .free = memory_hugepage_free, - .alignment = 21 /* 2 MiB hugepage */ -}; diff --git a/lib/memory/heap.c b/lib/memory/heap.c new file mode 100644 index 000000000..7a70abf63 --- /dev/null +++ b/lib/memory/heap.c @@ -0,0 +1,54 @@ +/** Memory allocators. + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#include + +#include + +static void * memory_heap_alloc(struct memory_type *m, size_t len, size_t alignment) +{ + void *ptr; + int ret; + + if (alignment < sizeof(void *)) + alignment = sizeof(void *); + + ret = posix_memalign(&ptr, alignment, len); + + return ret ? NULL : ptr; +} + +int memory_heap_free(struct memory_type *m, void *ptr, size_t len) +{ + free(ptr); + + return 0; +} + +/* List of available memory types */ +struct memory_type memory_type_heap = { + .name = "heap", + .flags = MEMORY_HEAP, + .alloc = memory_heap_alloc, + .free = memory_heap_free, + .alignment = 1 +}; diff --git a/lib/memory/hugepage.c b/lib/memory/hugepage.c new file mode 100644 index 000000000..83abbcf15 --- /dev/null +++ b/lib/memory/hugepage.c @@ -0,0 +1,86 @@ +/** Hugepage memory allocator. + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Required to allocate hugepages on Apple OS X */ +#ifdef __MACH__ + #include +#elif defined(__linux__) + #include +#endif + +#include +#include +#include + +#define HUGEPAGESIZE (1 << 21) /* 2 MiB */ + +/** Allocate memory backed by hugepages with malloc() like interface */ +static void * memory_hugepage_alloc(struct memory_type *m, size_t len, size_t alignment) +{ + void *ret; + int prot = PROT_READ | PROT_WRITE; + int flags = MAP_PRIVATE | MAP_ANONYMOUS; + +#ifdef __MACH__ + flags |= VM_FLAGS_SUPERPAGE_SIZE_2MB; +#elif defined(__linux__) + flags |= MAP_HUGETLB; + + if (getuid() == 0) + flags |= MAP_LOCKED; +#endif + + ret = mmap(NULL, len, prot, flags, -1, 0); + if (ret == MAP_FAILED) + return NULL; + + return ret; +} + +static int memory_hugepage_free(struct memory_type *m, void *ptr, size_t len) +{ + /** We must make sure that len is a multiple of the hugepage size + * + * See: https://lkml.org/lkml/2014/10/22/925 + */ + len = ALIGN(len, HUGEPAGESIZE); + + return munmap(ptr, len); +} + +struct memory_type memory_hugepage = { + .name = "mmap_hugepages", + .flags = MEMORY_MMAP | MEMORY_HUGEPAGE, + .alloc = memory_hugepage_alloc, + .free = memory_hugepage_free, + .alignment = 21 /* 2 MiB hugepage */ +}; diff --git a/lib/memory_ib.c b/lib/memory/ib.c similarity index 84% rename from lib/memory_ib.c rename to lib/memory/ib.c index 9a1432aaf..38955e4d6 100644 --- a/lib/memory_ib.c +++ b/lib/memory/ib.c @@ -21,9 +21,14 @@ *********************************************************************************/ #include -#include +#include #include +struct memory_ib { + struct ibv_pd *pd; + struct memory_type *parent; +}; + struct ibv_mr * memory_ib_mr(void *ptr) { struct ibv_mr *mr = (struct ibv_mr *) ptr; @@ -31,7 +36,7 @@ struct ibv_mr * memory_ib_mr(void *ptr) return (mr - 1); } -void * memory_ib_alloc(struct memtype *m, size_t len, size_t alignment) +void * memory_ib_alloc(struct memory_type *m, size_t len, size_t alignment) { struct memory_ib *mi = (struct memory_ib *) m->_vd; @@ -47,7 +52,7 @@ void * memory_ib_alloc(struct memtype *m, size_t len, size_t alignment) return ptr; } -int memory_ib_free(struct memtype *m, void *ptr, size_t len) +int memory_ib_free(struct memory_type *m, void *ptr, size_t len) { struct memory_ib *mi = (struct memory_ib *) m->_vd; struct ibv_mr *mr = memory_ib_mr(ptr); @@ -62,10 +67,10 @@ int memory_ib_free(struct memtype *m, void *ptr, size_t len) return 0; } -struct memtype * ib_memtype(struct node *n, struct memtype *parent) +struct memory_type * memory_ib(struct node *n, struct memory_type *parent) { struct infiniband *i = (struct infiniband *) n->_vd; - struct memtype *mt = malloc(sizeof(struct memtype)); + struct memory_type *mt = malloc(sizeof(struct memory_type)); mt->name = "ib"; mt->flags = 0; diff --git a/lib/memory/managed.c b/lib/memory/managed.c new file mode 100644 index 000000000..05ea6f439 --- /dev/null +++ b/lib/memory/managed.c @@ -0,0 +1,193 @@ +/** Memory allocators. + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +void* memory_managed_alloc(struct memory_type *m, size_t len, size_t alignment) +{ + /* Simple first-fit allocation */ + struct memblock *first = (struct memblock *) m->_vd; + struct memblock *block; + + for (block = first; block != NULL; block = block->next) { + if (block->flags & MEMBLOCK_USED) + continue; + + char* cptr = (char *) block + sizeof(struct memblock); + size_t avail = block->len; + uintptr_t uptr = (uintptr_t) cptr; + + /* Check alignment first; leave a gap at start of block to assure + * alignment if necessary */ + uintptr_t rem = uptr % alignment; + uintptr_t gap = 0; + if (rem != 0) { + gap = alignment - rem; + if (gap > avail) + continue; /* Next aligned address isn't in this block anymore */ + + cptr += gap; + avail -= gap; + } + + if (avail >= len) { + if (gap > sizeof(struct memblock)) { + /* The alignment gap is big enough to fit another block. + * The original block descriptor is already at the correct + * position, so we just change its len and create a new block + * descriptor for the actual block we're handling. */ + block->len = gap - sizeof(struct memblock); + struct memblock *newblock = (struct memblock *) (cptr - sizeof(struct memblock)); + newblock->prev = block; + newblock->next = block->next; + block->next = newblock; + newblock->flags = 0; + newblock->len = len; + block = newblock; + } + else { + /* The gap is too small to fit another block descriptor, so we + * must account for the gap length in the block length. */ + block->len = len + gap; + } + + if (avail > len + sizeof(struct memblock)) { + /* Imperfect fit, so create another block for the remaining part */ + struct memblock *newblock = (struct memblock *) (cptr + len); + newblock->prev = block; + newblock->next = block->next; + block->next = newblock; + if (newblock->next) + newblock->next->prev = newblock; + newblock->flags = 0; + newblock->len = avail - len - sizeof(struct memblock); + } + else { + /* If this block was larger than the requested length, but only + * by less than sizeof(struct memblock), we may have wasted + * memory by previous assignments to block->len. */ + block->len = avail; + } + + block->flags |= MEMBLOCK_USED; + + return (void *) cptr; + } + } + + /* No suitable block found */ + return NULL; +} + +int memory_managed_free(struct memory_type *m, void *ptr, size_t len) +{ + struct memblock *first = (struct memblock *) m->_vd; + struct memblock *block; + char *cptr = ptr; + + for (block = first; block != NULL; block = block->next) { + if (!(block->flags & MEMBLOCK_USED)) + continue; + + /* Since we may waste some memory at the start of a block to ensure + * alignment, ptr may not actually be the start of the block */ + if ((char *) block + sizeof(struct memblock) <= cptr && + cptr < (char *) block + sizeof(struct memblock) + block->len) { + /* Try to merge it with neighbouring free blocks */ + if (block->prev && !(block->prev->flags & MEMBLOCK_USED) && + block->next && !(block->next->flags & MEMBLOCK_USED)) { + /* Special case first: both previous and next block are unused */ + block->prev->len += block->len + block->next->len + 2 * sizeof(struct memblock); + block->prev->next = block->next->next; + if (block->next->next) + block->next->next->prev = block->prev; + } + else if (block->prev && !(block->prev->flags & MEMBLOCK_USED)) { + block->prev->len += block->len + sizeof(struct memblock); + block->prev->next = block->next; + if (block->next) + block->next->prev = block->prev; + } + else if (block->next && !(block->next->flags & MEMBLOCK_USED)) { + block->len += block->next->len + sizeof(struct memblock); + block->next = block->next->next; + if (block->next) + block->next->prev = block; + } + else { + /* no neighbouring free block, so just mark it as free */ + block->flags &= ~MEMBLOCK_USED; + } + + return 0; + } + } + + return -1; +} + +struct memory_type * memory_managed(void *ptr, size_t len) +{ + struct memory_type *mt = ptr; + struct memblock *mb; + char *cptr = ptr; + + if (len < sizeof(struct memory_type) + sizeof(struct memblock)) { + info("memory_managed: passed region too small"); + return NULL; + } + + /* Initialize memory_type */ + mt->name = "managed"; + mt->flags = 0; + mt->alloc = memory_managed_alloc; + mt->free = memory_managed_free; + mt->alignment = 1; + + cptr += ALIGN(sizeof(struct memory_type), sizeof(void *)); + + /* Initialize first free memblock */ + mb = (struct memblock *) cptr; + mb->prev = NULL; + mb->next = NULL; + mb->flags = 0; + + cptr += ALIGN(sizeof(struct memblock), sizeof(void *)); + + mb->len = len - (cptr - (char *) ptr); + + mt->_vd = (void *) mb; + + return mt; +} diff --git a/lib/node.c b/lib/node.c index 4b028c471..e7c9f7a7f 100644 --- a/lib/node.c +++ b/lib/node.c @@ -549,9 +549,9 @@ int node_fd(struct node *n) return n->_vt->fd ? n->_vt->fd(n) : -1; } -struct memtype * node_memtype(struct node *n, struct memtype *parent) +struct memory_type * node_memory_type(struct node *n, struct memory_type *parent) { - return n->_vt->memtype(n, parent) ? n->_vt->memtype(n, parent) : &memtype_hugepage; + return n->_vt->memory_type ? n->_vt->memory_type(n, parent) : &memory_hugepage; } int node_parse_list(struct list *list, json_t *cfg, struct list *all) diff --git a/lib/nodes/iec61850_sv.c b/lib/nodes/iec61850_sv.c index 70c91efca..82dadf238 100644 --- a/lib/nodes/iec61850_sv.c +++ b/lib/nodes/iec61850_sv.c @@ -294,11 +294,11 @@ int iec61850_sv_start(struct node *n) SVReceiver_addSubscriber(i->subscriber.receiver, i->subscriber.subscriber); /* Initialize pool and queue to pass samples between threads */ - ret = pool_init(&i->subscriber.pool, 1024, SAMPLE_LEN(n->samplelen), &memtype_hugepage); + ret = pool_init(&i->subscriber.pool, 1024, SAMPLE_LEN(n->samplelen), &memory_hugepage); if (ret) return ret; - ret = queue_signalled_init(&i->subscriber.queue, 1024, &memtype_hugepage, 0); + ret = queue_signalled_init(&i->subscriber.queue, 1024, &memory_hugepage, 0); if (ret) return ret; } diff --git a/lib/nodes/infiniband.c b/lib/nodes/infiniband.c index efe372816..c732d756c 100644 --- a/lib/nodes/infiniband.c +++ b/lib/nodes/infiniband.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include @@ -240,7 +240,7 @@ static void ib_build_ibv(struct node *n) pool_init(&ib->mem.p_recv, ib->qp_init.cap.max_recv_wr, 64*sizeof(double), - &memtype_heap); + &memory_type_heap); if(ret) { error("Failed to init recv memory pool of node %s: %s", @@ -271,7 +271,7 @@ static void ib_build_ibv(struct node *n) pool_init(&ib->mem.p_send, ib->qp_init.cap.max_send_wr, sizeof(double), - &memtype_heap); + &memory_type_heap); if(ret) { error("Failed to init send memory of node %s: %s", @@ -839,7 +839,7 @@ static struct plugin p = { .read = ib_read, .write = ib_write, .fd = ib_fd, - .memtype = ib_memtype + .memory_type = memory_ib } }; diff --git a/lib/nodes/loopback.c b/lib/nodes/loopback.c index e25efcd67..62b11519c 100644 --- a/lib/nodes/loopback.c +++ b/lib/nodes/loopback.c @@ -50,11 +50,11 @@ int loopback_open(struct node *n) int ret; struct loopback *l = (struct loopback *) n->_vd; - ret = pool_init(&l->pool, l->queuelen, SAMPLE_LEN(n->samplelen), &memtype_hugepage); + ret = pool_init(&l->pool, l->queuelen, SAMPLE_LEN(n->samplelen), &memory_hugepage); if (ret) return ret; - return queue_signalled_init(&l->queue, l->queuelen, &memtype_hugepage, QUEUE_SIGNALLED_EVENTFD); + return queue_signalled_init(&l->queue, l->queuelen, &memory_hugepage, QUEUE_SIGNALLED_EVENTFD); } int loopback_close(struct node *n) diff --git a/lib/nodes/mqtt.c b/lib/nodes/mqtt.c index bc3692f13..893d10d8d 100644 --- a/lib/nodes/mqtt.c +++ b/lib/nodes/mqtt.c @@ -301,11 +301,11 @@ int mqtt_start(struct node *n) if (ret) return ret; - ret = pool_init(&m->pool, 1024, SAMPLE_LEN(n->samplelen), &memtype_hugepage); + ret = pool_init(&m->pool, 1024, SAMPLE_LEN(n->samplelen), &memory_hugepage); if (ret) return ret; - ret = queue_signalled_init(&m->queue, 1024, &memtype_hugepage, 0); + ret = queue_signalled_init(&m->queue, 1024, &memory_hugepage, 0); if (ret) return ret; diff --git a/lib/nodes/websocket.c b/lib/nodes/websocket.c index b30926fff..a81b8b2e8 100644 --- a/lib/nodes/websocket.c +++ b/lib/nodes/websocket.c @@ -81,7 +81,7 @@ static int websocket_connection_init(struct websocket_connection *c) c->_name = NULL; - ret = queue_init(&c->queue, DEFAULT_QUEUELEN, &memtype_hugepage); + ret = queue_init(&c->queue, DEFAULT_QUEUELEN, &memory_hugepage); if (ret) return ret; @@ -400,11 +400,11 @@ int websocket_start(struct node *n) int ret; struct websocket *w = (struct websocket *) n->_vd; - ret = pool_init(&w->pool, DEFAULT_WEBSOCKET_QUEUELEN, SAMPLE_LEN(DEFAULT_WEBSOCKET_SAMPLELEN), &memtype_hugepage); + ret = pool_init(&w->pool, DEFAULT_WEBSOCKET_QUEUELEN, SAMPLE_LEN(DEFAULT_WEBSOCKET_SAMPLELEN), &memory_hugepage); if (ret) return ret; - ret = queue_signalled_init(&w->queue, DEFAULT_WEBSOCKET_QUEUELEN, &memtype_hugepage, 0); + ret = queue_signalled_init(&w->queue, DEFAULT_WEBSOCKET_QUEUELEN, &memory_hugepage, 0); if (ret) return ret; diff --git a/lib/path.c b/lib/path.c index 7763e1aa5..b3bb3d9e0 100644 --- a/lib/path.c +++ b/lib/path.c @@ -46,7 +46,7 @@ static int path_source_init(struct path_source *ps) { int ret; - ret = pool_init(&ps->pool, MAX(DEFAULT_QUEUELEN, ps->node->in.vectorize), SAMPLE_LEN(ps->node->samplelen), &memtype_hugepage); + ret = pool_init(&ps->pool, MAX(DEFAULT_QUEUELEN, ps->node->in.vectorize), SAMPLE_LEN(ps->node->samplelen), &memory_hugepage); if (ret) return ret; @@ -148,7 +148,7 @@ static int path_destination_init(struct path_destination *pd, int queuelen) { int ret; - ret = queue_init(&pd->queue, queuelen, &memtype_hugepage); + ret = queue_init(&pd->queue, queuelen, &memory_hugepage); if (ret) return ret; @@ -430,7 +430,7 @@ int path_init2(struct path *p) if (!p->samplelen) p->samplelen = DEFAULT_SAMPLELEN; - ret = pool_init(&p->pool, MAX(1, list_length(&p->destinations)) * p->queuelen, SAMPLE_LEN(p->samplelen), &memtype_hugepage); + ret = pool_init(&p->pool, MAX(1, list_length(&p->destinations)) * p->queuelen, SAMPLE_LEN(p->samplelen), &memory_hugepage); if (ret) return ret; diff --git a/lib/pool.c b/lib/pool.c index 0f77df83a..78b47f2c8 100644 --- a/lib/pool.c +++ b/lib/pool.c @@ -25,7 +25,7 @@ #include #include -int pool_init(struct pool *p, size_t cnt, size_t blocksz, struct memtype *m) +int pool_init(struct pool *p, size_t cnt, size_t blocksz, struct memory_type *m) { int ret; diff --git a/lib/queue.c b/lib/queue.c index af65d0bde..438a2c523 100644 --- a/lib/queue.c +++ b/lib/queue.c @@ -36,7 +36,7 @@ #include /** Initialize MPMC queue */ -int queue_init(struct queue *q, size_t size, struct memtype *mem) +int queue_init(struct queue *q, size_t size, struct memory_type *mem) { assert(q->state == STATE_DESTROYED); diff --git a/lib/queue_signalled.c b/lib/queue_signalled.c index a37caa316..bc625ecd6 100644 --- a/lib/queue_signalled.c +++ b/lib/queue_signalled.c @@ -36,7 +36,7 @@ static void queue_signalled_cleanup(void *p) pthread_mutex_unlock(&qs->pthread.mutex); } -int queue_signalled_init(struct queue_signalled *qs, size_t size, struct memtype *mem, int flags) +int queue_signalled_init(struct queue_signalled *qs, size_t size, struct memory_type *mem, int flags) { int ret; diff --git a/lib/shmem.c b/lib/shmem.c index 56020a249..65042a155 100644 --- a/lib/shmem.c +++ b/lib/shmem.c @@ -35,8 +35,8 @@ size_t shmem_total_size(int queuelen, int samplelen) { - /* We have the constant const of the memtype header */ - return sizeof(struct memtype) + /* We have the constant const of the memory_type header */ + return sizeof(struct memory_type) /* and the shared struct itself */ + sizeof(struct shmem_shared) /* the size of the actual queue and the queue for the pool */ @@ -55,7 +55,7 @@ int shmem_int_open(const char *wname, const char* rname, struct shmem_int *shm, int fd, ret; size_t len; void *base; - struct memtype *manager; + struct memory_type *manager; struct shmem_shared *shared; struct stat stat_buf; sem_t *sem_own, *sem_other; @@ -92,7 +92,7 @@ retry: fd = shm_open(wname, O_RDWR|O_CREAT|O_EXCL, 0600); close(fd); - manager = memtype_managed_init(base, len); + manager = memory_managed(base, len); shared = memory_alloc(manager, sizeof(struct shmem_shared)); if (!shared) { errno = ENOMEM; @@ -144,7 +144,7 @@ retry: fd = shm_open(wname, O_RDWR|O_CREAT|O_EXCL, 0600); if (base == MAP_FAILED) return -10; - cptr = (char *) base + sizeof(struct memtype) + sizeof(struct memblock); + cptr = (char *) base + sizeof(struct memory_type) + sizeof(struct memblock); shared = (struct shmem_shared *) cptr; shm->read.base = base; shm->read.name = rname; diff --git a/src/hook.c b/src/hook.c index ecf31cf9f..1d444b458 100644 --- a/src/hook.c +++ b/src/hook.c @@ -182,7 +182,7 @@ check: if (optarg == endptr) smps = alloc(cnt * sizeof(struct sample *)); - ret = pool_init(&q, 10 * cnt, SAMPLE_LEN(DEFAULT_SAMPLELEN), &memtype_hugepage); + ret = pool_init(&q, 10 * cnt, SAMPLE_LEN(DEFAULT_SAMPLELEN), &memory_hugepage); if (ret) error("Failed to initilize memory pool"); diff --git a/src/pipe.c b/src/pipe.c index 2b0260398..67e68435e 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -132,7 +132,7 @@ static void * send_loop(void *ctx) struct sample *smps[node->out.vectorize]; /* Initialize memory */ - ret = pool_init(&sendd.pool, LOG2_CEIL(node->out.vectorize), SAMPLE_LEN(DEFAULT_SAMPLELEN), node_memtype(node, &memtype_hugepage)); + ret = pool_init(&sendd.pool, LOG2_CEIL(node->out.vectorize), SAMPLE_LEN(DEFAULT_SAMPLELEN), node_memory_type(node, &memory_hugepage)); if (ret < 0) error("Failed to allocate memory for receive pool."); @@ -196,7 +196,7 @@ static void * recv_loop(void *ctx) struct sample *smps[node->in.vectorize]; /* Initialize memory */ - ret = pool_init(&recvv.pool, LOG2_CEIL(node->in.vectorize), SAMPLE_LEN(DEFAULT_SAMPLELEN), node_memtype(node, &memtype_hugepage)); + ret = pool_init(&recvv.pool, LOG2_CEIL(node->in.vectorize), SAMPLE_LEN(DEFAULT_SAMPLELEN), node_memory_type(node, &memory_hugepage)); if (ret < 0) error("Failed to allocate memory for receive pool."); diff --git a/src/signal.c b/src/signal.c index 324f12733..31e47716c 100644 --- a/src/signal.c +++ b/src/signal.c @@ -155,7 +155,7 @@ int main(int argc, char *argv[]) if (ret) error("Failed to verify node configuration"); - ret = pool_init(&q, 16, SAMPLE_LEN(n.samplelen), &memtype_heap); + ret = pool_init(&q, 16, SAMPLE_LEN(n.samplelen), &memory_type_heap); if (ret) error("Failed to initialize pool"); diff --git a/src/test-cmp.c b/src/test-cmp.c index 0c5bad66e..52d93c5b0 100644 --- a/src/test-cmp.c +++ b/src/test-cmp.c @@ -122,7 +122,7 @@ check: if (optarg == endptr) int n = argc - optind; /* The number of files which we compare */ struct side s[n]; - ret = pool_init(&pool, n, SAMPLE_LEN(DEFAULT_SAMPLELEN), &memtype_heap); + ret = pool_init(&pool, n, SAMPLE_LEN(DEFAULT_SAMPLELEN), &memory_type_heap); if (ret) error("Failed to initialize pool"); diff --git a/tests/unit/io.c b/tests/unit/io.c index 4abdc57a2..8c2338cd9 100644 --- a/tests/unit/io.c +++ b/tests/unit/io.c @@ -185,7 +185,7 @@ ParameterizedTest(char *fmt, io, lowlevel) struct sample *smps[NUM_SAMPLES]; struct sample *smpt[NUM_SAMPLES]; - ret = pool_init(&p, 2 * NUM_SAMPLES, SAMPLE_LEN(NUM_VALUES), &memtype_hugepage); + ret = pool_init(&p, 2 * NUM_SAMPLES, SAMPLE_LEN(NUM_VALUES), &memory_hugepage); cr_assert_eq(ret, 0); info("Running test for format = %s", fmt); @@ -232,7 +232,7 @@ ParameterizedTest(char *fmt, io, highlevel) info("Running test for format = %s", fmt); - ret = pool_init(&p, 2 * NUM_SAMPLES, SAMPLE_LEN(NUM_VALUES), &memtype_hugepage); + ret = pool_init(&p, 2 * NUM_SAMPLES, SAMPLE_LEN(NUM_VALUES), &memory_hugepage); cr_assert_eq(ret, 0); generate_samples(&p, smps, smpt, NUM_SAMPLES, NUM_VALUES); diff --git a/tests/unit/memory.c b/tests/unit/memory.c index 55435d45c..38ccbe51a 100644 --- a/tests/unit/memory.c +++ b/tests/unit/memory.c @@ -28,13 +28,15 @@ #include #include +#define HUGEPAGESIZE (1<<22) + TheoryDataPoints(memory, aligned) = { DataPoints(size_t, 1, 32, 55, 1 << 10, 1 << 20), DataPoints(size_t, 1, 8, 1 << 12), - DataPoints(struct memtype *, &memtype_heap, &memtype_hugepage) + DataPoints(struct memory_type *, &memory_type_heap, &memory_hugepage) }; -Theory((size_t len, size_t align, struct memtype *m), memory, aligned) { +Theory((size_t len, size_t align, struct memory_type *m), memory, aligned) { int ret; void *ptr; @@ -43,7 +45,7 @@ Theory((size_t len, size_t align, struct memtype *m), memory, aligned) { cr_assert(IS_ALIGNED(ptr, align)); - if (m == &memtype_hugepage) { + if (m == &memory_hugepage) { cr_assert(IS_ALIGNED(ptr, HUGEPAGESIZE)); } @@ -57,15 +59,15 @@ Test(memory, manager) { int ret; void *p, *p1, *p2, *p3; - struct memtype *m; + struct memory_type *m; total_size = 1 << 10; - max_block = total_size - sizeof(struct memtype) - sizeof(struct memblock); + max_block = total_size - sizeof(struct memory_type) - sizeof(struct memblock); - p = memory_alloc(&memtype_heap, total_size); + p = memory_alloc(&memory_type_heap, total_size); cr_assert_not_null(p); - m = memtype_managed_init(p, total_size); + m = memory_managed(p, total_size); cr_assert_not_null(m); p1 = memory_alloc(m, 16); @@ -100,6 +102,6 @@ Test(memory, manager) { ret = memory_free(m, p1, max_block); cr_assert(ret == 0); - ret = memory_free(&memtype_heap, p, total_size); + ret = memory_free(&memory_type_heap, p, total_size); cr_assert(ret == 0); } diff --git a/tests/unit/pool.c b/tests/unit/pool.c index d2ef6160a..e2958185a 100644 --- a/tests/unit/pool.c +++ b/tests/unit/pool.c @@ -32,16 +32,16 @@ struct param { int thread_count; int pool_size; size_t block_size; - struct memtype *memtype; + struct memory_type *memory_type; }; ParameterizedTestParameters(pool, basic) { static struct param params[] = { - { 1, 4096, 150, &memtype_heap }, - { 1, 128, 8, &memtype_hugepage }, - { 1, 4, 8192, &memtype_hugepage }, - { 1, 1 << 13, 4, &memtype_heap } + { 1, 4096, 150, &memory_type_heap }, + { 1, 128, 8, &memory_hugepage }, + { 1, 4, 8192, &memory_hugepage }, + { 1, 1 << 13, 4, &memory_type_heap } }; return cr_make_param_array(struct param, params, ARRAY_LEN(params)); @@ -54,7 +54,7 @@ ParameterizedTest(struct param *p, pool, basic) void *ptr, *ptrs[p->pool_size]; - ret = pool_init(&pool, p->pool_size, p->block_size, p->memtype); + ret = pool_init(&pool, p->pool_size, p->block_size, p->memory_type); cr_assert_eq(ret, 0, "Failed to create pool"); ptr = pool_get(&pool); diff --git a/tests/unit/queue.c b/tests/unit/queue.c index fad646c11..dca93f12d 100644 --- a/tests/unit/queue.c +++ b/tests/unit/queue.c @@ -51,7 +51,7 @@ struct param { int batch_size; void * (*thread_func)(void *); struct queue queue; - const struct memtype *memtype; + const struct memory_type *memory_type; }; /** Get thread id as integer @@ -243,7 +243,7 @@ Test(queue, single_threaded) .start = 1 /* we start immeadiatly */ }; - ret = queue_init(&p.queue, p.queue_size, &memtype_heap); + ret = queue_init(&p.queue, p.queue_size, &memory_type_heap); cr_assert_eq(ret, 0, "Failed to create queue"); producer(&p); @@ -265,35 +265,35 @@ ParameterizedTestParameters(queue, multi_threaded) .thread_count = 32, .thread_func = producer_consumer_many, .batch_size = 10, - .memtype = &memtype_heap + .memory_type = &memory_type_heap }, { .iter_count = 1 << 8, .queue_size = 1 << 9, .thread_count = 4, .thread_func = producer_consumer_many, .batch_size = 100, - .memtype = &memtype_heap + .memory_type = &memory_type_heap }, { .iter_count = 1 << 16, .queue_size = 1 << 14, .thread_count = 16, .thread_func = producer_consumer_many, .batch_size = 100, - .memtype = &memtype_heap + .memory_type = &memory_type_heap }, { .iter_count = 1 << 8, .queue_size = 1 << 9, .thread_count = 4, .thread_func = producer_consumer_many, .batch_size = 10, - .memtype = &memtype_heap + .memory_type = &memory_type_heap }, { .iter_count = 1 << 16, .queue_size = 1 << 9, .thread_count = 16, .thread_func = producer_consumer, .batch_size = 10, - .memtype = &memtype_hugepage + .memory_type = &memory_hugepage } }; @@ -308,7 +308,7 @@ ParameterizedTest(struct param *p, queue, multi_threaded, .timeout = 20) p->start = 0; - ret = queue_init(&p->queue, p->queue_size, &memtype_heap); + ret = queue_init(&p->queue, p->queue_size, &memory_type_heap); cr_assert_eq(ret, 0, "Failed to create queue"); uint64_t start_tsc_time, end_tsc_time; @@ -350,7 +350,7 @@ Test(queue, init_destroy) int ret; struct queue q = { .state = STATE_DESTROYED }; - ret = queue_init(&q, 1024, &memtype_heap); + ret = queue_init(&q, 1024, &memory_type_heap); cr_assert_eq(ret, 0); /* Should succeed */ ret = queue_destroy(&q); diff --git a/tests/unit/queue_signalled.c b/tests/unit/queue_signalled.c index 0acf8d1ea..030ef9117 100644 --- a/tests/unit/queue_signalled.c +++ b/tests/unit/queue_signalled.c @@ -132,7 +132,7 @@ ParameterizedTest(struct param *param, queue_signalled, simple, .timeout = 5) pthread_t t1, t2; - ret = queue_signalled_init(&q, LOG2_CEIL(NUM_ELEM), &memtype_heap, param->flags); + ret = queue_signalled_init(&q, LOG2_CEIL(NUM_ELEM), &memory_type_heap, param->flags); cr_assert_eq(ret, 0, "Failed to initialize queue: flags=%#x, ret=%d", param->flags, ret); ret = pthread_create(&t1, NULL, producer, &q); From 45b121d884dafc594b7a1c22c1b57b8a74786541 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 2 Jul 2018 16:05:05 +0200 Subject: [PATCH 15/18] infiniband: do not build memory allocator if node is not acticated --- lib/Makefile.villas.inc | 2 +- lib/nodes/Makefile.inc | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Makefile.villas.inc b/lib/Makefile.villas.inc index 963d98511..48819cb1d 100644 --- a/lib/Makefile.villas.inc +++ b/lib/Makefile.villas.inc @@ -26,7 +26,7 @@ LIB = $(BUILDDIR)/$(LIB_NAME).so.$(LIB_ABI_VERSION) # Object files for libvillas LIB_SRCS += $(addprefix lib/kernel/, kernel.c rt.c) \ - $(addprefix lib/memory/, heap.c hugepage.c ib.c managed.c) \ + $(addprefix lib/memory/, heap.c hugepage.c managed.c) \ $(addprefix lib/, sample.c path.c node.c hook.c log.c log_config.c \ utils.c super_node.c hist.c timing.c pool.c list.c queue.c \ queue_signalled.c memory.c advio.c plugin.c node_type.c stats.c \ diff --git a/lib/nodes/Makefile.inc b/lib/nodes/Makefile.inc index 47a329242..f6423c129 100644 --- a/lib/nodes/Makefile.inc +++ b/lib/nodes/Makefile.inc @@ -159,6 +159,7 @@ endif # Enable Infiniband support ifeq ($(WITH_NODE_INFINIBAND),1) LIB_SRCS += lib/nodes/infiniband.c + LIB_SRCS += lib/memory/ib.c LIB_NODES += infiniband LIB_LDLIBS += -libverbs LIB_LDLIBS += -lrdmacm From da8124e472d353b05e8b383b3243bf5cfadc7cde Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 2 Jul 2018 19:00:55 +0200 Subject: [PATCH 16/18] memory: use hash_table to store allocation metadata --- include/villas/hash_table.h | 10 +++ include/villas/memory.h | 42 +++++++---- include/villas/memory_type.h | 9 ++- include/villas/pool.h | 2 - include/villas/queue.h | 1 - lib/Makefile.villas-ext.inc | 2 +- lib/memory.c | 47 +++++++++--- lib/memory/heap.c | 31 +++++--- lib/memory/hugepage.c | 41 +++++++---- lib/memory/ib.c | 36 +++++---- lib/memory/managed.c | 138 +++++++++++++++++------------------ lib/pool.c | 3 +- lib/queue.c | 8 +- lib/shmem.c | 4 +- tests/unit/memory.c | 24 +++--- 15 files changed, 241 insertions(+), 157 deletions(-) diff --git a/include/villas/hash_table.h b/include/villas/hash_table.h index d8a79f873..87726184f 100644 --- a/include/villas/hash_table.h +++ b/include/villas/hash_table.h @@ -20,11 +20,17 @@ * along with this program. If not, see . *********************************************************************************/ +#pragma once + #include #include #include +#ifdef __cplusplus +extern "C" { +#endif + struct hash_table_entry { void *key; void *data; @@ -73,3 +79,7 @@ void * hash_table_lookup(struct hash_table *ht, void *key); /** Dump the contents of the hash table in a human readable format to stdout. */ void hash_table_dump(struct hash_table *ht); + +#ifdef __cplusplus +} +#endif diff --git a/include/villas/memory.h b/include/villas/memory.h index 95ee21972..616377d20 100644 --- a/include/villas/memory.h +++ b/include/villas/memory.h @@ -25,6 +25,7 @@ #include #include +#include #include @@ -35,26 +36,35 @@ extern "C" { /* Forward declarations */ struct node; -enum memblock_flags { - MEMBLOCK_USED = 1, -}; - /** Descriptor of a memory block. Associated block always starts at - * &m + sizeof(struct memblock). */ -struct memblock { - struct memblock *prev; - struct memblock *next; - size_t len; /** #include #include +#include #include +static struct hash_table allocations = { .state = STATE_DESTROYED }; + int memory_init(int hugepages) { + int ret; + + if (allocations.state == STATE_DESTROYED) { + ret = hash_table_init(&allocations, 100); + if (ret) + return ret; + } + #ifdef __linux__ int ret, pagecnt, pagesz; struct rlimit l; @@ -71,25 +82,39 @@ int memory_init(int hugepages) void * memory_alloc(struct memory_type *m, size_t len) { - void *ptr = m->alloc(m, len, sizeof(void *)); - - debug(LOG_MEM | 5, "Allocated %#zx bytes of %s memory: %p", len, m->name, ptr); - - return ptr; + return memory_alloc_aligned(m, len, sizeof(void *)); } void * memory_alloc_aligned(struct memory_type *m, size_t len, size_t alignment) { - void *ptr = m->alloc(m, len, alignment); + struct memory_allocation *ma = m->alloc(m, len, alignment); - debug(LOG_MEM | 5, "Allocated %#zx bytes of %#zx-byte-aligned %s memory: %p", len, alignment, m->name, ptr); + hash_table_insert(&allocations, ma->address, ma); - return ptr; + debug(LOG_MEM | 5, "Allocated %#zx bytes of %#zx-byte-aligned %s memory: %p", ma->length, ma->alignment, ma->type->name, ma->address); + + return ma->address; } -int memory_free(struct memory_type *m, void *ptr, size_t len) +int memory_free(void *ptr) { - debug(LOG_MEM | 5, "Releasing %#zx bytes of %s memory", len, m->name); + int ret; - return m->free(m, ptr, len); + /* Find corresponding memory allocation entry */ + struct memory_allocation *ma = (struct memory_allocation *) hash_table_lookup(&allocations, ptr); + if (!ma) + return -1; + + debug(LOG_MEM | 5, "Releasing %#zx bytes of %s memory", ma->length, ma->type->name); + + ret = ma->type->free(ma->type, ma); + if (ret) + return ret; + + /* Remove allocation entry */ + ret = hash_table_delete(&allocations, ma->address); + if (ret) + return ret; + + return 0; } diff --git a/lib/memory/heap.c b/lib/memory/heap.c index 7a70abf63..1a2c61552 100644 --- a/lib/memory/heap.c +++ b/lib/memory/heap.c @@ -22,24 +22,37 @@ #include -#include +#include +#include -static void * memory_heap_alloc(struct memory_type *m, size_t len, size_t alignment) +static struct memory_allocation * memory_heap_alloc(struct memory_type *m, size_t len, size_t alignment) { - void *ptr; int ret; - if (alignment < sizeof(void *)) - alignment = sizeof(void *); + struct memory_allocation *ma = alloc(sizeof(struct memory_allocation)); + if (!ma) + return NULL; - ret = posix_memalign(&ptr, alignment, len); + ma->alignment = alignment; + ma->type = m; + ma->length = len; - return ret ? NULL : ptr; + if (ma->alignment < sizeof(void *)) + ma->alignment = sizeof(void *); + + ret = posix_memalign(&ma->address, ma->alignment, ma->length); + if (ret) { + free(ma); + return ret; + } + + return ma; } -int memory_heap_free(struct memory_type *m, void *ptr, size_t len) +static int memory_heap_free(struct memory_type *m, struct memory_allocation *ma) { - free(ptr); + free(ma->address); + free(ma); return 0; } diff --git a/lib/memory/hugepage.c b/lib/memory/hugepage.c index 83abbcf15..6bf17719c 100644 --- a/lib/memory/hugepage.c +++ b/lib/memory/hugepage.c @@ -38,15 +38,14 @@ #endif #include -#include +#include #include -#define HUGEPAGESIZE (1 << 21) /* 2 MiB */ +#define HUGEPAGESIZE (1 << 22) /* 2 MiB */ /** Allocate memory backed by hugepages with malloc() like interface */ -static void * memory_hugepage_alloc(struct memory_type *m, size_t len, size_t alignment) +static struct memory_allocation * memory_hugepage_alloc(struct memory_type *m, size_t len, size_t alignment) { - void *ret; int prot = PROT_READ | PROT_WRITE; int flags = MAP_PRIVATE | MAP_ANONYMOUS; @@ -59,22 +58,38 @@ static void * memory_hugepage_alloc(struct memory_type *m, size_t len, size_t al flags |= MAP_LOCKED; #endif - ret = mmap(NULL, len, prot, flags, -1, 0); - if (ret == MAP_FAILED) + struct memory_allocation *ma = alloc(sizeof(struct memory_allocation)); + if (!ma) return NULL; - return ret; -} - -static int memory_hugepage_free(struct memory_type *m, void *ptr, size_t len) -{ /** We must make sure that len is a multiple of the hugepage size * * See: https://lkml.org/lkml/2014/10/22/925 */ - len = ALIGN(len, HUGEPAGESIZE); + ma->length = ALIGN(len, HUGEPAGESIZE); + ma->alignment = alignment; + ma->type = m; - return munmap(ptr, len); + ma->address = mmap(NULL, len, prot, flags, -1, 0); + if (ma->address == MAP_FAILED) { + free(ma); + return NULL; + } + + return ma; +} + +static int memory_hugepage_free(struct memory_type *m, struct memory_allocation *ma) +{ + int ret; + + ret = munmap(ma->address, ma->length); + if (ret) + return ret; + + free(ma); + + return 0; } struct memory_type memory_hugepage = { diff --git a/lib/memory/ib.c b/lib/memory/ib.c index 38955e4d6..fe62e223f 100644 --- a/lib/memory/ib.c +++ b/lib/memory/ib.c @@ -36,33 +36,43 @@ struct ibv_mr * memory_ib_mr(void *ptr) return (mr - 1); } -void * memory_ib_alloc(struct memory_type *m, size_t len, size_t alignment) +static struct memory_allocation * memory_ib_alloc(struct memory_type *m, size_t len, size_t alignment) { struct memory_ib *mi = (struct memory_ib *) m->_vd; - struct ibv_mr **mr = memory_alloc_aligned(mi->parent, len + sizeof(struct ibv_mr *), alignment); - char *ptr = (char *) (mr + 1); + struct memory_allocation *ma = alloc(sizeof(struct memory_allocation)); + if (!ma) + return NULL; - *mr = ibv_reg_mr(mi->pd, ptr, len, IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_WRITE); - if(!*mr) { - free(ptr); + ma->type = m; + ma->length = len; + ma->alignment = alignment; + + ma->parent = mi->parent->alloc(mi->parent, len + sizeof(struct ibv_mr *), alignment); + ma->address = ma->parent->address; + + ma->ib.mr = ibv_reg_mr(mi->pd, ma->address, ma->length, IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_WRITE); + if(!ma->ib.mr) { + mi->parent->free(mi->parent, ma->parent); + free(ma); return NULL; } - return ptr; + return ma; } -int memory_ib_free(struct memory_type *m, void *ptr, size_t len) +static int memory_ib_free(struct memory_type *m, struct memory_allocation *ma) { + int ret; struct memory_ib *mi = (struct memory_ib *) m->_vd; - struct ibv_mr *mr = memory_ib_mr(ptr); - ibv_dereg_mr(mr); + ibv_dereg_mr(ma->ib.mr); - ptr -= sizeof(struct ibv_mr *); - len += sizeof(struct ibv_mr *); + ret = mi->parent->free(mi->parent, ma->parent); + if (ret) + return ret; - memory_free(mi->parent, ptr, len); + free(ma); return 0; } diff --git a/lib/memory/managed.c b/lib/memory/managed.c index 05ea6f439..ab8bc4b59 100644 --- a/lib/memory/managed.c +++ b/lib/memory/managed.c @@ -34,18 +34,18 @@ #include #include -void* memory_managed_alloc(struct memory_type *m, size_t len, size_t alignment) +static struct memory_allocation * memory_managed_alloc(struct memory_type *m, size_t len, size_t alignment) { /* Simple first-fit allocation */ - struct memblock *first = (struct memblock *) m->_vd; - struct memblock *block; + struct memory_block *first = (struct memory_block *) m->_vd; + struct memory_block *block; for (block = first; block != NULL; block = block->next) { - if (block->flags & MEMBLOCK_USED) + if (block->used) continue; - char* cptr = (char *) block + sizeof(struct memblock); - size_t avail = block->len; + char* cptr = (char *) block + sizeof(struct memory_block); + size_t avail = block->length; uintptr_t uptr = (uintptr_t) cptr; /* Check alignment first; leave a gap at start of block to assure @@ -62,47 +62,59 @@ void* memory_managed_alloc(struct memory_type *m, size_t len, size_t alignment) } if (avail >= len) { - if (gap > sizeof(struct memblock)) { + if (gap > sizeof(struct memory_block)) { /* The alignment gap is big enough to fit another block. * The original block descriptor is already at the correct * position, so we just change its len and create a new block * descriptor for the actual block we're handling. */ - block->len = gap - sizeof(struct memblock); - struct memblock *newblock = (struct memblock *) (cptr - sizeof(struct memblock)); + block->length = gap - sizeof(struct memory_block); + struct memory_block *newblock = (struct memory_block *) (cptr - sizeof(struct memory_block)); newblock->prev = block; newblock->next = block->next; block->next = newblock; - newblock->flags = 0; - newblock->len = len; + newblock->used = false; + newblock->length = len; block = newblock; } else { /* The gap is too small to fit another block descriptor, so we * must account for the gap length in the block length. */ - block->len = len + gap; + block->length = len + gap; } - if (avail > len + sizeof(struct memblock)) { + if (avail > len + sizeof(struct memory_block)) { /* Imperfect fit, so create another block for the remaining part */ - struct memblock *newblock = (struct memblock *) (cptr + len); + struct memory_block *newblock = (struct memory_block *) (cptr + len); newblock->prev = block; newblock->next = block->next; block->next = newblock; + if (newblock->next) newblock->next->prev = newblock; - newblock->flags = 0; - newblock->len = avail - len - sizeof(struct memblock); + + newblock->used = false; + newblock->length = avail - len - sizeof(struct memory_block); } else { /* If this block was larger than the requested length, but only - * by less than sizeof(struct memblock), we may have wasted - * memory by previous assignments to block->len. */ - block->len = avail; + * by less than sizeof(struct memory_block), we may have wasted + * memory by previous assignments to block->length. */ + block->length = avail; } - block->flags |= MEMBLOCK_USED; + block->used = true; - return (void *) cptr; + struct memory_allocation *ma = alloc(sizeof(struct memory_allocation)); + if (!ma) + return NULL; + + ma->address = cptr; + ma->type = m; + ma->alignment = alignment; + ma->length = len; + ma->managed.block = block; + + return ma; } } @@ -110,60 +122,48 @@ void* memory_managed_alloc(struct memory_type *m, size_t len, size_t alignment) return NULL; } -int memory_managed_free(struct memory_type *m, void *ptr, size_t len) +static int memory_managed_free(struct memory_type *m, struct memory_allocation *ma) { - struct memblock *first = (struct memblock *) m->_vd; - struct memblock *block; - char *cptr = ptr; + struct memory_block *block = ma->managed.block; - for (block = first; block != NULL; block = block->next) { - if (!(block->flags & MEMBLOCK_USED)) - continue; - - /* Since we may waste some memory at the start of a block to ensure - * alignment, ptr may not actually be the start of the block */ - if ((char *) block + sizeof(struct memblock) <= cptr && - cptr < (char *) block + sizeof(struct memblock) + block->len) { - /* Try to merge it with neighbouring free blocks */ - if (block->prev && !(block->prev->flags & MEMBLOCK_USED) && - block->next && !(block->next->flags & MEMBLOCK_USED)) { - /* Special case first: both previous and next block are unused */ - block->prev->len += block->len + block->next->len + 2 * sizeof(struct memblock); - block->prev->next = block->next->next; - if (block->next->next) - block->next->next->prev = block->prev; - } - else if (block->prev && !(block->prev->flags & MEMBLOCK_USED)) { - block->prev->len += block->len + sizeof(struct memblock); - block->prev->next = block->next; - if (block->next) - block->next->prev = block->prev; - } - else if (block->next && !(block->next->flags & MEMBLOCK_USED)) { - block->len += block->next->len + sizeof(struct memblock); - block->next = block->next->next; - if (block->next) - block->next->prev = block; - } - else { - /* no neighbouring free block, so just mark it as free */ - block->flags &= ~MEMBLOCK_USED; - } - - return 0; - } + /* Try to merge it with neighbouring free blocks */ + if (block->prev && !block->prev->used && + block->next && !block->next->used) { + /* Special case first: both previous and next block are unused */ + block->prev->length += block->length + block->next->length + 2 * sizeof(struct memory_block); + block->prev->next = block->next->next; + if (block->next->next) + block->next->next->prev = block->prev; + } + else if (block->prev && !block->prev->used) { + block->prev->length += block->length + sizeof(struct memory_block); + block->prev->next = block->next; + if (block->next) + block->next->prev = block->prev; + } + else if (block->next && !block->next->used) { + block->length += block->next->length + sizeof(struct memory_block); + block->next = block->next->next; + if (block->next) + block->next->prev = block; + } + else { + /* no neighbouring free block, so just mark it as free */ + block->used = false; } - return -1; + free(ma); + + return 0; } struct memory_type * memory_managed(void *ptr, size_t len) { struct memory_type *mt = ptr; - struct memblock *mb; + struct memory_block *mb; char *cptr = ptr; - if (len < sizeof(struct memory_type) + sizeof(struct memblock)) { + if (len < sizeof(struct memory_type) + sizeof(struct memory_block)) { info("memory_managed: passed region too small"); return NULL; } @@ -177,15 +177,15 @@ struct memory_type * memory_managed(void *ptr, size_t len) cptr += ALIGN(sizeof(struct memory_type), sizeof(void *)); - /* Initialize first free memblock */ - mb = (struct memblock *) cptr; + /* Initialize first free memory block */ + mb = (struct memory_block *) cptr; mb->prev = NULL; mb->next = NULL; - mb->flags = 0; + mb->used = false; - cptr += ALIGN(sizeof(struct memblock), sizeof(void *)); + cptr += ALIGN(sizeof(struct memory_block), sizeof(void *)); - mb->len = len - (cptr - (char *) ptr); + mb->length = len - (cptr - (char *) ptr); mt->_vd = (void *) mb; diff --git a/lib/pool.c b/lib/pool.c index 78b47f2c8..1a7ce726f 100644 --- a/lib/pool.c +++ b/lib/pool.c @@ -35,7 +35,6 @@ int pool_init(struct pool *p, size_t cnt, size_t blocksz, struct memory_type *m) p->alignment = kernel_get_cacheline_size(); p->blocksz = p->alignment * CEIL(blocksz, p->alignment); p->len = cnt * p->blocksz; - p->mem = m; void *buffer = memory_alloc_aligned(m, p->len, p->alignment); if (!buffer) @@ -66,7 +65,7 @@ int pool_destroy(struct pool *p) queue_destroy(&p->queue); void *buffer = (char*) p + p->buffer_off; - ret = memory_free(p->mem, buffer, p->len); + ret = memory_free(buffer); if (ret == 0) p->state = STATE_DESTROYED; diff --git a/lib/queue.c b/lib/queue.c index 438a2c523..0b020b192 100644 --- a/lib/queue.c +++ b/lib/queue.c @@ -36,7 +36,7 @@ #include /** Initialize MPMC queue */ -int queue_init(struct queue *q, size_t size, struct memory_type *mem) +int queue_init(struct queue *q, size_t size, struct memory_type *m) { assert(q->state == STATE_DESTROYED); @@ -47,9 +47,8 @@ int queue_init(struct queue *q, size_t size, struct memory_type *mem) warn("A queue size was changed from %lu to %lu", old_size, size); } - q->mem = mem; q->buffer_mask = size - 1; - struct queue_cell *buffer = (struct queue_cell *) memory_alloc(q->mem, sizeof(struct queue_cell) * size); + struct queue_cell *buffer = (struct queue_cell *) memory_alloc(m, sizeof(struct queue_cell) * size); if (!buffer) return -2; @@ -74,8 +73,7 @@ int queue_destroy(struct queue *q) if (q->state == STATE_DESTROYED) return 0; - ret = memory_free(q->mem, buffer, (q->buffer_mask + 1) * sizeof(struct queue_cell)); - + ret = memory_free(buffer); if (ret == 0) q->state = STATE_DESTROYED; diff --git a/lib/shmem.c b/lib/shmem.c index 65042a155..294e7ae67 100644 --- a/lib/shmem.c +++ b/lib/shmem.c @@ -44,7 +44,7 @@ size_t shmem_total_size(int queuelen, int samplelen) /* the size of the pool */ + queuelen * kernel_get_cacheline_size() * CEIL(SAMPLE_LEN(samplelen), kernel_get_cacheline_size()) /* a memblock for each allocation (1 shmem_shared, 2 queues, 1 pool) */ - + 4 * sizeof(struct memblock) + + 4 * sizeof(struct memory_block) /* and some extra buffer for alignment */ + 1024; } @@ -144,7 +144,7 @@ retry: fd = shm_open(wname, O_RDWR|O_CREAT|O_EXCL, 0600); if (base == MAP_FAILED) return -10; - cptr = (char *) base + sizeof(struct memory_type) + sizeof(struct memblock); + cptr = (char *) base + sizeof(struct memory_type) + sizeof(struct memory_block); shared = (struct shmem_shared *) cptr; shm->read.base = base; shm->read.name = rname; diff --git a/tests/unit/memory.c b/tests/unit/memory.c index 38ccbe51a..821795afd 100644 --- a/tests/unit/memory.c +++ b/tests/unit/memory.c @@ -28,7 +28,7 @@ #include #include -#define HUGEPAGESIZE (1<<22) +#define HUGEPAGESIZE (1 << 22) TheoryDataPoints(memory, aligned) = { DataPoints(size_t, 1, 32, 55, 1 << 10, 1 << 20), @@ -40,6 +40,9 @@ Theory((size_t len, size_t align, struct memory_type *m), memory, aligned) { int ret; void *ptr; + ret = memory_init(100); + cr_assert(!ret); + ptr = memory_alloc_aligned(m, len, align); cr_assert_neq(ptr, NULL, "Failed to allocate memory"); @@ -49,7 +52,7 @@ Theory((size_t len, size_t align, struct memory_type *m), memory, aligned) { cr_assert(IS_ALIGNED(ptr, HUGEPAGESIZE)); } - ret = memory_free(m, ptr, len); + ret = memory_free(ptr); cr_assert_eq(ret, 0, "Failed to release memory: ret=%d, ptr=%p, len=%zu: %s", ret, ptr, len, strerror(errno)); } @@ -62,7 +65,10 @@ Test(memory, manager) { struct memory_type *m; total_size = 1 << 10; - max_block = total_size - sizeof(struct memory_type) - sizeof(struct memblock); + max_block = total_size - sizeof(struct memory_type) - sizeof(struct memory_block); + + ret = memory_init(0); + cr_assert(!ret); p = memory_alloc(&memory_type_heap, total_size); cr_assert_not_null(p); @@ -76,7 +82,7 @@ Test(memory, manager) { p2 = memory_alloc(m, 32); cr_assert_not_null(p2); - ret = memory_free(m, p1, 16); + ret = memory_free(p1); cr_assert(ret == 0); p1 = memory_alloc_aligned(m, 128, 128); @@ -87,21 +93,21 @@ Test(memory, manager) { cr_assert(p3); cr_assert(IS_ALIGNED(p3, 256)); - ret = memory_free(m, p2, 32); + ret = memory_free(p2); cr_assert(ret == 0); - ret = memory_free(m, p1, 128); + ret = memory_free(p1); cr_assert(ret == 0); - ret = memory_free(m, p3, 128); + ret = memory_free(p3); cr_assert(ret == 0); p1 = memory_alloc(m, max_block); cr_assert_not_null(p1); - ret = memory_free(m, p1, max_block); + ret = memory_free(p1); cr_assert(ret == 0); - ret = memory_free(&memory_type_heap, p, total_size); + ret = memory_free(p); cr_assert(ret == 0); } From 1c2c210f13cfd08560548adbe8e471755b4d0289 Mon Sep 17 00:00:00 2001 From: Dennis Potter Date: Tue, 3 Jul 2018 18:28:21 +0200 Subject: [PATCH 17/18] Fixed two minor compilation errors --- lib/memory.c | 2 +- lib/memory/ib.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/memory.c b/lib/memory.c index 0eac3e437..4257d14aa 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -47,7 +47,7 @@ int memory_init(int hugepages) } #ifdef __linux__ - int ret, pagecnt, pagesz; + int pagecnt, pagesz; struct rlimit l; info("Initialize memory sub-system"); diff --git a/lib/memory/ib.c b/lib/memory/ib.c index fe62e223f..5679c6e6a 100644 --- a/lib/memory/ib.c +++ b/lib/memory/ib.c @@ -22,6 +22,7 @@ #include #include +#include #include struct memory_ib { From 5a6b9120be8ced2c52a90c26af17a35501f37115 Mon Sep 17 00:00:00 2001 From: Dennis Potter Date: Wed, 4 Jul 2018 10:39:13 +0200 Subject: [PATCH 18/18] Fixed incompatible integer to pointer conversion returning 'int' from a function with result type 'struct memory_allocation *' --- lib/memory/heap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/memory/heap.c b/lib/memory/heap.c index 1a2c61552..7e054fd23 100644 --- a/lib/memory/heap.c +++ b/lib/memory/heap.c @@ -43,7 +43,7 @@ static struct memory_allocation * memory_heap_alloc(struct memory_type *m, size_ ret = posix_memalign(&ma->address, ma->alignment, ma->length); if (ret) { free(ma); - return ret; + return NULL; } return ma;