1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

Merge branch 'develop' into infiniband-memory

This commit is contained in:
Steffen Vogel 2018-07-02 13:09:24 +02:00
commit 93750a2bcd
79 changed files with 1030 additions and 87 deletions

View file

@ -26,7 +26,11 @@
#include <curl/curl.h>
#include "crypt.h"
#include <villas/crypt.h>
#ifdef __cplusplus
extern "C"{
#endif
struct advio {
CURL *curl;
@ -81,3 +85,7 @@ void arewind(AFILE *file);
int adownload(AFILE *af, int resume);
int aupload(AFILE *af, int resume);
#ifdef __cplusplus
}
#endif

View file

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

View file

@ -30,6 +30,10 @@
#include <villas/queue.h>
#include <villas/buffer.h>
#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

View file

@ -21,7 +21,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************************/
#include "common.h"
#pragma once
#include <villas/common.h>
#ifdef __cplusplus
@ -37,4 +39,4 @@ typedef std::atomic<enum state> atomic_state;
typedef _Atomic enum state atomic_state;
#endif
#endif /* __cplusplus */

View file

@ -26,6 +26,10 @@
#include <stddef.h>
#include <stdint.h>
#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

View file

@ -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);
int buffer_append_json(struct buffer *b, json_t *j);
#ifdef __cplusplus
}
#endif

View file

@ -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,13 @@ enum state {
STATE_UNLOADED = 5, /* alias for STATE_STARTED used by struct plugin */
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

View file

@ -20,8 +20,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************************/
#pragma once
#include <jansson.h>
#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
@ -43,3 +49,7 @@ size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags);
#define htobe32(x) OSSwapHostToBigInt32(x)
#define htobe64(x) OSSwapHostToBigInt64(x)
#endif /* __MACH__ */
#ifdef __cplusplus
}
#endif

View file

@ -26,6 +26,10 @@
#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 +60,7 @@
/* Required kernel version */
#define KERNEL_VERSION_MAJ 3
#define KERNEL_VERSION_MIN 6
#ifdef __cplusplus
}
#endif

View file

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

View file

@ -25,9 +25,17 @@
#include <stdio.h>
#include <openssl/sha.h>
#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

View file

@ -25,6 +25,10 @@
#include <stdio.h>
#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

View file

@ -25,6 +25,9 @@
#include <stdio.h>
#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

View file

@ -24,6 +24,10 @@
#include <jansson.h>
#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

View file

@ -24,6 +24,10 @@
#include <jansson.h>
#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

View file

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

View file

@ -25,6 +25,10 @@
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** The current version number for the message format */
#define MSG_VERSION 2
@ -90,3 +94,7 @@ struct msg
uint32_t i; /**< Integer values. */
} data[];
} __attribute__((packed));
#ifdef __cplusplus
}
#endif

View file

@ -25,6 +25,10 @@
#include <stdlib.h>
#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

View file

@ -25,6 +25,10 @@
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declarations */
struct sample;
@ -58,3 +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

View file

@ -25,6 +25,10 @@
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declarations. */
struct sample;
struct msg;
@ -39,3 +43,7 @@ int villas_binary_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, s
/** 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

View file

@ -25,6 +25,10 @@
#include <stdio.h>
#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

View file

@ -0,0 +1,75 @@
/** A generic hash table
*
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @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 <http://www.gnu.org/licenses/>.
*********************************************************************************/
#include <pthread.h>
#include <stdbool.h>
#include <villas/common.h>
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);

View file

@ -28,6 +28,10 @@
#include <jansson.h>
#ifdef __cplusplus
extern "C" {
#endif
#define HIST_HEIGHT (LOG_WIDTH - 55)
#define HIST_SEQ 17
@ -103,3 +107,7 @@ int hist_dump_json(struct hist *h, FILE *f);
/** Build a libjansson / JSON object of the histogram. */
json_t * hist_json(struct hist *h);
#ifdef __cplusplus
}
#endif

View file

@ -34,8 +34,12 @@
#pragma once
#include "hook_type.h"
#include "common.h"
#include <villas/hook_type.h>
#include <villas/common.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declarations */
struct path;
@ -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

View file

@ -39,6 +39,10 @@
#include <jansson.h>
#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

View file

@ -23,9 +23,13 @@
#pragma once
#include "advio.h"
#include "common.h"
#include "node.h"
#include <villas/advio.h>
#include <villas/common.h>
#include <villas/node.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declarations */
struct sample;
@ -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

View file

@ -33,6 +33,10 @@
#include <villas/list.h>
#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
/** @} */

View file

@ -28,6 +28,10 @@
#include <string.h>
#include <stdint.h>
#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
/** @} */

View file

@ -1,5 +1,9 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define SCH_NETEM_ATTR_DIST 0x2000
struct rtnl_netem_corr
@ -43,3 +47,7 @@ struct rtnl_netem
};
void *rtnl_tc_data(struct rtnl_tc *tc);
#ifdef __cplusplus
}
#endif

View file

@ -29,6 +29,10 @@
#include <netlink/route/route.h>
#include <netlink/route/link.h>
#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
/** @} */

View file

@ -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
/** @} */

View file

@ -37,6 +37,10 @@
#include <jansson.h>
#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
/** @} */

View file

@ -37,6 +37,10 @@
#include <jansson.h>
#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
/** @} */

View file

@ -8,7 +8,22 @@
*
* @file
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @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 <http://www.gnu.org/licenses/>.
*********************************************************************************/
#pragma once
@ -17,7 +32,11 @@
#include <sys/types.h>
#include <pthread.h>
#include "common.h"
#include <villas/common.h>
#ifdef __cplusplus
extern "C"{
#endif
#define LIST_CHUNKSIZE 16
@ -46,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 *);
@ -120,3 +133,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

View file

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

View file

@ -25,9 +25,13 @@
#include <jansson.h>
#include "stats.h"
#include "common.h"
#include "list.h"
#include <villas/stats.h>
#include <villas/common.h>
#include <villas/list.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declarations */
struct stats;
@ -93,3 +97,7 @@ 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

View file

@ -21,10 +21,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************************/
#pragma once
#include <stddef.h>
#include <stdint.h>
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define HUGEPAGESIZE (1 << 21)
@ -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; /**<Length of the block; doesn't include the descriptor itself */
int flags;
};
/** @todo Unused for now */
struct memzone {
struct memtype * const type;
struct memtype *const type;
void *addr;
uintptr_t physaddr;
@ -92,3 +96,7 @@ struct memtype * memtype_managed_init(void *ptr, size_t len);
extern struct memtype memtype_heap;
extern struct memtype memtype_hugepage;
#ifdef __cplusplus
}
#endif

View file

@ -32,11 +32,15 @@
#include <netinet/in.h>
#include <jansson.h>
#include "node_type.h"
#include "sample.h"
#include "list.h"
#include "queue.h"
#include "common.h"
#include <villas/node_type.h>
#include <villas/sample.h>
#include <villas/list.h>
#include <villas/queue.h>
#include <villas/common.h>
#ifdef __cplusplus
extern "C"{
#endif
struct node_direction {
int enabled;
@ -160,5 +164,8 @@ int node_fd(struct node *n);
struct memtype * node_memtype(struct node *n, struct memtype *parent);
#ifdef __cplusplus
}
#endif
/** @} */

View file

@ -24,6 +24,10 @@
* @{
*********************************************************************************/
#ifdef __cplusplus
extern "C"{
#endif
#pragma once
#include <jansson.h>
@ -85,6 +89,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[]);
@ -172,4 +184,8 @@ const char * node_type_name(struct node_type *vt);
struct node_type * node_type_lookup(const char *name);
#ifdef __cplusplus
}
#endif
/** @} */

View file

@ -35,6 +35,10 @@
#include <villas/list.h>
#include <villas/io.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declarations */
struct format_type;
@ -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
/** @} */

View file

@ -33,6 +33,10 @@
#include <villas/list.h>
#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
/** @} */

View file

@ -35,6 +35,10 @@
#include <villas/list.h>
#include <villas/timing.h>
#ifdef __cplusplus
extern "C" {
#endif
// whether to use read() or mmap() kernel interface
#define COMEDI_USE_READ (1)
//#define COMEDI_USE_READ (0)
@ -45,20 +49,19 @@ 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
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
unsigned *chanlist; ///< Channel list in comedi's packed format
size_t chanlist_len; ///< Number of channels for this direction
char* buffer;
char* bufptr;
@ -70,8 +73,8 @@ struct comedi {
comedi_t *dev;
#if COMEDI_USE_READ
char* buf;
char* bufptr;
char *buf;
char *bufptr;
#else
char *map;
size_t bufpos;
@ -100,3 +103,7 @@ int comedi_read(struct node *n, struct sample *smps[], unsigned cnt);
int comedi_write(struct node *n, struct sample *smps[], unsigned cnt);
/** @} */
#ifdef __cplusplus
}
#endif

View file

@ -33,6 +33,10 @@
#include <villas/node.h>
#include <villas/task.h>
#ifdef __cplusplus
extern "C" {
#endif
#define FILE_MAX_PATHLEN 512
struct file {
@ -85,3 +89,7 @@ int file_read(struct node *n, struct sample *smps[], unsigned cnt);
int file_write(struct node *n, struct sample *smps[], unsigned cnt);
/** @} */
#ifdef __cplusplus
}
#endif

View file

@ -38,6 +38,10 @@
#include <villas/node.h>
#include <villas/list.h>
#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
/** @} */

View file

@ -40,6 +40,10 @@
#include <villas/list.h>
#include <villas/nodes/iec61850.h>
#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
/** @} */

View file

@ -31,6 +31,10 @@
#include <villas/list.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declarations */
struct node;
struct sample;
@ -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
/** @} */

View file

@ -32,6 +32,10 @@
#include <villas/queue_signalled.h>
#include <villas/pool.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declarations */
struct node;
struct sample;
@ -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
/** @} */

View file

@ -34,6 +34,10 @@
#include <villas/io.h>
#include <villas/queue_signalled.h>
#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
/** @} */

View file

@ -33,6 +33,10 @@
#include <villas/list.h>
#include <villas/io.h>
#ifdef __cplusplus
extern "C" {
#endif
/** The maximum length of a packet which contains stuct msg. */
#define NANOMSG_MAX_PACKET_LEN 1500
@ -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
/** @} */

View file

@ -43,6 +43,10 @@
#include <villas/node.h>
#include <villas/task.h>
#ifdef __cplusplus
extern "C" {
#endif
struct node;
struct ngsi {
@ -95,3 +99,7 @@ int ngsi_read(struct node *n, struct sample *smps[], unsigned cnt);
int ngsi_write(struct node *n, struct sample *smps[], unsigned cnt);
/** @} */
#ifdef __cplusplus
}
#endif

View file

@ -31,8 +31,8 @@
#include <pthread.h>
#include "node.h"
#include "msg.h"
#include <villas/node.h>
#include <villas/msg.h>
/* Define RTLAB before including OpalPrint.h for messages to be sent
* to the OpalDisplay. Otherwise stdout will be used. */
@ -41,6 +41,10 @@
#include "AsyncApi.h"
#include "OpalGenAsyncParamCtrl.h"
#ifdef __cplusplus
extern "C" {
#endif
struct opal {
int reply;
int mode;
@ -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
/** @} */

View file

@ -36,6 +36,10 @@
#include <villas/config.h>
#include <villas/shmem.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Node-type for shared memory communication.
* @see node_type
*/
@ -66,3 +70,7 @@ int shmem_read(struct node *n, struct sample *smps[], unsigned cnt);
int shmem_write(struct node *n, struct sample *smps[], unsigned cnt);
/** @} */
#ifdef __cplusplus
}
#endif

View file

@ -32,6 +32,10 @@
#include <villas/timing.h>
#include <villas/task.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declarations */
struct node;
struct sample;
@ -90,3 +94,7 @@ 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

View file

@ -50,6 +50,10 @@
#include <villas/node.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declarations */
struct format_type;
@ -155,3 +159,7 @@ 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

View file

@ -33,6 +33,10 @@
#include <villas/task.h>
#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
/** @} */

View file

@ -33,6 +33,10 @@
#include <villas/io.h>
#include <villas/task.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declarations */
struct test_rtt;
struct node;
@ -81,3 +85,7 @@ int test_rtt_read(struct node *n, struct sample *smps[], unsigned cnt);
int test_rtt_write(struct node *n, struct sample *smps[], unsigned cnt);
/** @} */
#ifdef __cplusplus
}
#endif

View file

@ -38,6 +38,10 @@
#include <villas/io.h>
#include <villas/config.h>
#ifdef __cplusplus
extern "C" {
#endif
#define DEFAULT_WEBSOCKET_QUEUELEN (DEFAULT_QUEUELEN * 64)
#define DEFAULT_WEBSOCKET_SAMPLELEN DEFAULT_SAMPLELEN
@ -114,3 +118,7 @@ int websocket_read(struct node *n, struct sample *smps[], unsigned cnt);
int websocket_write(struct node *n, struct sample *smps[], unsigned cnt);
/** @} */
#ifdef __cplusplus
}
#endif

View file

@ -35,6 +35,10 @@
#include <villas/list.h>
#include <villas/io.h>
#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
#endif
@ -104,3 +108,7 @@ int zeromq_read(struct node *n, struct sample *smps[], unsigned cnt);
int zeromq_write(struct node *n, struct sample *smps[], unsigned cnt);
/** @} */
#ifdef __cplusplus
}
#endif

View file

@ -32,14 +32,18 @@
#include <pthread.h>
#include <jansson.h>
#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 <villas/list.h>
#include <villas/queue.h>
#include <villas/pool.h>
#include <villas/bitset.h>
#include <villas/common.h>
#include <villas/hook.h>
#include <villas/mapping.h>
#include <villas/task.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declarations */
struct stats;
@ -169,3 +173,7 @@ 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

View file

@ -31,7 +31,21 @@
#include "node_type.h"
#include "format_type.h"
/** @todo This is ugly as hell and broken on OS X / Clang anyway. */
#ifdef __cplusplus
extern "C"{
#endif
/** (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) \
@ -95,3 +109,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

View file

@ -28,9 +28,13 @@
#include <stddef.h>
#include <sys/types.h>
#include "queue.h"
#include "common.h"
#include "memory.h"
#include <villas/queue.h>
#include <villas/common.h>
#include <villas/memory.h>
#ifdef __cplusplus
extern "C" {
#endif
/** A thread-safe memory pool */
struct pool {
@ -92,3 +96,7 @@ INLINE int pool_put(struct pool *p, void *buf)
{
return queue_push(&p->queue, buf);
}
#ifdef __cplusplus
}
#endif

View file

@ -33,13 +33,16 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <unistd.h>
#include "atomic.h"
#include "common.h"
#include <villas/atomic.h>
#include <villas/common.h>
#ifdef __cplusplus
extern "C"{
#endif
/* Forward declarations */
struct memtype;
@ -112,3 +115,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

View file

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

View file

@ -23,11 +23,7 @@
#pragma once
#include "atomic.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <villas/atomic.h>
#include <stddef.h>
#include <stdlib.h>
@ -35,6 +31,10 @@ extern "C" {
#include <stdint.h>
#include <time.h>
#ifdef __cplusplus
extern "C"{
#endif
/* Forward declarations */
struct pool;

View file

@ -25,6 +25,10 @@
#include <jansson.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declarations */
struct list;
struct node;
@ -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

View file

@ -21,13 +21,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************************/
#ifndef _STATS_H_
#define _STATS_H_
#pragma once
#include <stdint.h>
#include <jansson.h>
#include "hist.h"
#include <villas/hist.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declarations */
struct sample;
@ -86,4 +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

View file

@ -23,11 +23,15 @@
#pragma once
#include "list.h"
#include "api.h"
#include "web.h"
#include "log.h"
#include "common.h"
#include <villas/list.h>
#include <villas/api.h>
#include <villas/web.h>
#include <villas/log.h>
#include <villas/common.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Global configuration */
struct super_node {
@ -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

View file

@ -25,6 +25,12 @@
* @{
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
struct table_column {
int width; /**< Width of the column. */
char *title; /**< The title as shown in the table header. */
@ -55,3 +61,7 @@ void table_row(struct table *t, ...);
void table_footer(struct table *t);
/** @} */
#ifdef __cplusplus
}
#endif

View file

@ -28,6 +28,10 @@
#include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
/** We can choose between two periodic task implementations */
//#define PERIODIC_TASK_IMPL NANOSLEEP
#define TIMERFD 1
@ -73,3 +77,7 @@ 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

View file

@ -28,6 +28,10 @@
#include <time.h>
#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

View file

@ -33,6 +33,11 @@
#include <villas/config.h>
#include <villas/log.h>
#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

View file

@ -25,7 +25,11 @@
#include <pthread.h>
#include "common.h"
#include <villas/common.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declarations */
struct api;
@ -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

View file

@ -31,6 +31,7 @@ LIB_SRCS += $(addprefix lib/kernel/, kernel.c rt.c) \
queue_signalled.c memory.c memory_ib.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

202
lib/hash_table.c Normal file
View file

@ -0,0 +1,202 @@
/** A generic hash table
*
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @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 <http://www.gnu.org/licenses/>.
*********************************************************************************/
#include <string.h>
#include <villas/utils.h>
#include <villas/hash_table.h>
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 <stdio.h>
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);
}

View file

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

View file

@ -309,6 +309,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;

View file

@ -78,7 +78,7 @@ RUN dnf -y install \
libiec61850-devel \
librabbitmq-devel \
mosquitto-devel \
comedilib-devel
comedilib-devel comedilib
# IB Verbs Dependencies
RUN dnf -y install \

View file

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

71
tests/unit/hash_table.c Normal file
View file

@ -0,0 +1,71 @@
/** Unit tests for hash table
*
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @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 <http://www.gnu.org/licenses/>.
*********************************************************************************/
#include <criterion/criterion.h>
#include <villas/utils.h>
#include <villas/hash_table.h>
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);
}