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

more refactoring to C++

This commit is contained in:
Steffen Vogel 2019-10-27 20:23:47 +01:00
parent fd3e387cc8
commit e90431aa98
36 changed files with 304 additions and 321 deletions

View file

@ -27,6 +27,7 @@
#include <curl/curl.h>
#include <villas/utils.hpp>
#include <villas/exceptions.hpp>
struct advio {
CURL *curl;

View file

@ -27,24 +27,28 @@
#include <jansson.h>
#include <villas/common.h>
#include <villas/common.hpp>
struct buffer {
enum State state;
namespace villas {
class Buffer {
public:
char *buf;
size_t len;
size_t size;
Buffer(size_t size);
~Buffer();
void clear();
int append(const char *data, size_t len);
int parseJson(json_t **j);
int appendJson(json_t *j);
};
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);
} /* namespace villas */

View file

@ -31,7 +31,7 @@ enum class State {
CHECKED = 3,
STARTED = 4,
LOADED = 4, /* alias for STARTED used by struct plugin */
OPENED = 4, /* alias for STARTED used by struct io */
OPENED = 4, /* alias for STARTED used by IO */
STOPPED = 5,
UNLOADED = 5, /* alias for STARTED used by struct plugin */
CLOSED = 5, /* alias for STARTED used by struct io */

View file

@ -45,14 +45,14 @@ protected:
public:
Window(size_type s = 0, T i = 0) :
init(i)
init(i),
steps(s)
{
size_type len = LOG2_CEIL(s);
/* Allocate memory for circular history buffer */
data = std::vector<T>(len, i);
steps = s;
pos = len;
mask = len - 1;
}

View file

@ -31,17 +31,7 @@
namespace villas {
class Buffer : public std::vector<char> {
public:
void append(const char *data, size_t len)
{
insert(end(), data, data + len);
}
};
class JsonBuffer : public Buffer
class JsonBuffer : public std::vector<char>
{
protected:
@ -53,6 +43,11 @@ public:
/** Decode JSON document from the beginning of the buffer */
json_t * decode();
void append(const char *data, size_t len)
{
insert(end(), data, data + len);
}
};
} /* namespace villas */

View file

@ -1,91 +0,0 @@
/** Linux kernel related functions.
*
* @file
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLAScommon
*
* 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/>.
*********************************************************************************/
/** @addtogroup kernel Kernel
* @{
*/
#pragma once
#include <cstring>
#include <cstdint>
#if WITH_CAP
#include <sys/capability.h>
/** Check if current process has capability \p cap.
*
* @retval 0 If capabilty is present.
* @retval <0 If capability is not present.
*/
int kernel_check_cap(cap_value_t cap);
#endif
/** Get number of reserved hugepages. */
int kernel_get_nr_hugepages();
/** Set number of reserved hugepages. */
int kernel_set_nr_hugepages(int nr);
/** Get kernel cmdline parameter
*
* See https://www.kernel.org/doc/Documentation/kernel-parameters.txt
*
* @param param The cmdline parameter to look for.
* @param buf The string buffer to which the parameter value will be copied to.
* @param len The length of the buffer \p value
* @retval 0 Parameter \p key was found and value was copied to \p value
* @reval <>0 Kernel was not booted with parameter \p key
*/
int kernel_get_cmdline_param(const char *param, char *buf, size_t len);
/** Checks if a kernel module is loaded
*
* @param module the name of the module
* @retval 0 Module is loaded.
* @reval <>0 Module is not loaded.
*/
int kernel_module_loaded(const char *module);
/** Load kernel module via modprobe */
int kernel_module_load(const char *module);
/** Set parameter of loaded kernel module */
int kernel_module_set_param(const char *module, const char *param, const char *value);
/** Get cacheline size in bytes */
int kernel_get_cacheline_size();
/** Get the size of a standard page in bytes. */
int kernel_get_page_size();
/** Get the size of a huge page in bytes. */
int kernel_get_hugepage_size();
/** Get CPU base frequency */
int kernel_get_cpu_frequency(uint64_t *freq);
/** Set SMP affinity of IRQ */
int kernel_irq_setaffinity(unsigned irq, uintmax_t aff , uintmax_t *old);
/** @} */

View file

@ -23,6 +23,8 @@
#pragma once
#include <cstddef>
#include <villas/version.hpp>
namespace villas {
@ -31,5 +33,63 @@ namespace kernel {
/** Get the version of the kernel. */
utils::Version getVersion();
#if WITH_CAP
#include <sys/capability.h>
/** Check if current process has capability \p cap.
*
* @retval 0 If capabilty is present.
* @retval <0 If capability is not present.
*/
int check_cap(cap_value_t cap);
#endif
/** Get number of reserved hugepages. */
int get_nr_hugepages();
/** Set number of reserved hugepages. */
int set_nr_hugepages(int nr);
/** Get kernel cmdline parameter
*
* See https://www.kernel.org/doc/Documentation/kernel-parameters.txt
*
* @param param The cmdline parameter to look for.
* @param buf The string buffer to which the parameter value will be copied to.
* @param len The length of the buffer \p value
* @retval 0 Parameter \p key was found and value was copied to \p value
* @reval <>0 Kernel was not booted with parameter \p key
*/
int get_cmdline_param(const char *param, char *buf, size_t len);
/** Checks if a kernel module is loaded
*
* @param module the name of the module
* @retval 0 Module is loaded.
* @reval <>0 Module is not loaded.
*/
int module_loaded(const char *module);
/** Load kernel module via modprobe */
int module_load(const char *module);
/** Set parameter of loaded kernel module */
int module_set_param(const char *module, const char *param, const char *value);
/** Get cacheline size in bytes */
int get_cacheline_size();
/** Get the size of a standard page in bytes. */
int get_page_size();
/** Get the size of a huge page in bytes. */
int get_hugepage_size();
/** Get CPU base frequency */
int get_cpu_frequency(uint64_t *freq);
/** Set SMP affinity of IRQ */
int irq_setaffinity(unsigned irq, uintmax_t aff , uintmax_t *old);
} /* namespace villas */
} /* namespace kernel */

View file

@ -31,7 +31,7 @@
#include <sys/types.h>
#include <pthread.h>
#include <villas/common.h>
#include <villas/common.hpp>
#define LIST_CHUNKSIZE 16
@ -76,7 +76,7 @@ int vlist_init(struct vlist *l);
* @param dtor A function pointer to a desctructor which will be called for every list item when the list is destroyed.
* @param l A pointer to the list data structure.
*/
int vlist_destroy(struct vlist *l, dtor_cb_t dtor, bool free);
int vlist_destroy(struct vlist *l, dtor_cb_t dtor = nullptr, bool free = false);
/** Append an element to the end of the list */
void vlist_push(struct vlist *l, void *p);
@ -101,7 +101,7 @@ int vlist_insert(struct vlist *l, size_t idx, void *p);
*/
void * vlist_lookup(struct vlist *l, const char *name);
ssize_t vlist_lookup_index(struct vlist *l, const char *name);
ssize_t vlist_lookup_index(struct vlist *l, const void *ptr);
/** Return the first element of the list for which cmp returns zero */
void * vlist_search(struct vlist *l, cmp_cb_t cmp, void *ctx);

View file

@ -33,8 +33,6 @@
#include <jansson.h>
#include <villas/terminal.hpp>
namespace villas {
/* Forward declarations */

View file

@ -29,7 +29,7 @@
#include <jansson.h>
#include <villas/log.hpp>
#include <villas/common.h>
#include <villas/common.hpp>
namespace villas {
namespace plugin {
@ -120,8 +120,8 @@ public:
virtual void dump();
std::string getName();
std::string getDescription();
const std::string & getName() const;
const std::string & getDescription() const;
protected:
std::string name;

View file

@ -47,7 +47,7 @@
#include <villas/tsc.h>
#endif
struct task {
struct Task {
int clock; /**< CLOCK_{MONOTONIC,REALTIME} */
#if PERIODIC_TASK_IMPL == RDTSC /* We use cycle counts in RDTSC mode */
@ -63,26 +63,28 @@ struct task {
#elif PERIODIC_TASK_IMPL == RDTSC
struct tsc tsc; /**< Initialized by tsc_init(). */
#endif
/** Create a new task with the given rate. */
Task(int clock = CLOCK_REALTIME);
~Task();
/** Wait until task elapsed
*
* @retval 0 An error occured. Maybe the task was stopped.
* @retval >0 The nummer of runs this task already fired.
*/
uint64_t wait();
void setNext(const struct timespec *next);
void setTimeout(double to);
void setRate(double rate);
void stop();
/** Returns a poll'able file descriptor which becomes readable when the timer expires.
*
* Note: currently not supported on all platforms.
*/
int getFD() const;
};
/** Create a new task with the given rate. */
int task_init(struct task *t, double rate, int clock);
int task_destroy(struct task *t);
/** Wait until task elapsed
*
* @retval 0 An error occured. Maybe the task was stopped.
* @retval >0 The nummer of runs this task already fired.
*/
uint64_t task_wait(struct task *t);
int task_set_next(struct task *t, struct timespec *next);
int task_set_timeout(struct task *t, double to);
int task_set_rate(struct task *t, double rate);
/** Returns a poll'able file descriptor which becomes readable when the timer expires.
*
* Note: currently not supported on all platforms.
*/
int task_fd(struct task *t);

View file

@ -35,7 +35,7 @@
#include <sys/sysctl.h>
#endif
#include <villas/kernel/kernel.h>
#include <villas/kernel/kernel.hpp>
#ifndef bit_TSC
#define bit_TSC (1 << 4)

View file

@ -28,7 +28,6 @@ add_library(villas-common SHARED
hist.cpp
dsp/pid.cpp
kernel/kernel.cpp
kernel/kernel.cpp
kernel/rt.cpp
list.cpp
log.cpp

View file

@ -41,8 +41,9 @@
#include <villas/utils.hpp>
#include <villas/config.h>
#include <villas/advio.h>
#include <villas/advio.hpp>
using namespace villas;
using namespace villas::utils;
#define BAR_WIDTH 60 /**< How wide you want the progress meter to be. */
@ -209,6 +210,10 @@ AFILE * afopen(const char *uri, const char *mode)
const char *sep;
AFILE *af = new AFILE;
if (!af)
throw RuntimeError("Failed to allocate memory!");
memset(af, 0, sizeof(AFILE));
snprintf(af->mode, sizeof(af->mode), "%s", mode);

View file

@ -22,78 +22,74 @@
#include <cstring>
#include <villas/compat.h>
#include <villas/buffer.h>
#include <villas/common.h>
#include <villas/compat.hpp>
#include <villas/buffer.hpp>
#include <villas/common.hpp>
#include <villas/exceptions.hpp>
int buffer_init(struct buffer *b, size_t size)
using namespace villas;
Buffer::Buffer(size_t sz) :
len(0),
size(sz)
{
b->len = 0;
b->size = size;
b->buf = new char[size];
if (!b->buf)
return -1;
buf = new char[size];
if (!buf)
throw RuntimeError("Failed to allocate memory");
b->state = State::INITIALIZED;
return 0;
memset(buf, 0, size);
}
int buffer_destroy(struct buffer *b)
Buffer::~Buffer()
{
if (b->buf)
delete[] b->buf;
b->state = State::DESTROYED;
return 0;
delete[] buf;
}
void buffer_clear(struct buffer *b)
void Buffer::clear()
{
b->len = 0;
len = 0;
}
int buffer_append(struct buffer *b, const char *data, size_t len)
int Buffer::append(const char *data, size_t l)
{
if (b->len + len > b->size) {
b->size = b->len + len;
b->buf = (char *) realloc(b->buf, b->size);
if (!b->buf)
if (len + l > size) {
size = len + l;
buf = (char *) realloc(buf, size);
if (!buf)
return -1;
}
memcpy(b->buf + b->len, data, len);
memcpy(buf + len, data, l);
b->len += len;
len += l;
return 0;
}
int buffer_parse_json(struct buffer *b, json_t **j)
int Buffer::parseJson(json_t **j)
{
*j = json_loadb(b->buf, b->len, 0, nullptr);
*j = json_loadb(buf, len, 0, nullptr);
if (!*j)
return -1;
return 0;
}
int buffer_append_json(struct buffer *b, json_t *j)
int Buffer::appendJson(json_t *j)
{
size_t len;
size_t l;
retry: len = json_dumpb(j, b->buf + b->len, b->size - b->len, 0);
if (b->size < b->len + len) {
b->buf = (char *) realloc(b->buf, b->len + len);
if (!b->buf)
retry: l = json_dumpb(j, buf + len, size - len, 0);
if (size < len + l) {
buf = (char *) realloc(buf, len + l);
if (!buf)
return -1;
b->size = b->len + len;
size = len + l;
goto retry;
}
b->len += len;
len += l;
return 0;
}

View file

@ -21,7 +21,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************************/
#include <villas/common.h>
#include <villas/common.hpp>
#include <cstdlib>

View file

@ -24,7 +24,7 @@
#include <jansson.h>
#include <unistd.h>
#include <villas/compat.h>
#include <villas/compat.hpp>
#if JANSSON_VERSION_HEX < 0x020A00
size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags)

View file

@ -28,6 +28,7 @@
#include <villas/hist.hpp>
#include <villas/config.h>
#include <villas/table.hpp>
#include <villas/exceptions.hpp>
using namespace villas::utils;
@ -188,6 +189,10 @@ void Hist::plot() const
char * Hist::dump() const
{
char *buf = new char[128];
if (!buf)
throw RuntimeError("Failed to allocate memory!");
memset(buf, 0, 128);
strcatf(&buf, "[ ");

View file

@ -20,7 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************************/
#include <villas/compat.h>
#include <villas/compat.hpp>
#include <villas/json_buffer.hpp>
using namespace villas;
@ -47,7 +47,7 @@ int JsonBuffer::encode(json_t *j)
int JsonBuffer::callback(const char *data, size_t len, void *ctx)
{
Buffer *b = static_cast<Buffer *>(ctx);
JsonBuffer *b = static_cast<JsonBuffer *>(ctx);
/* Append junk of JSON to buffer */
b->insert(b->end(), &data[0], &data[len]);

View file

@ -34,7 +34,7 @@
#include <villas/utils.hpp>
#include <villas/config.h>
#include <villas/kernel/kernel.h>
#include <villas/kernel/kernel.hpp>
#include <villas/kernel/kernel.hpp>
#include <villas/exceptions.hpp>
@ -57,7 +57,7 @@ Version villas::kernel::getVersion()
return Version(ver);
}
int kernel_get_cacheline_size()
int villas::kernel::get_cacheline_size()
{
#if defined(__linux__) && defined(__x86_64__)
return sysconf(_SC_LEVEL1_ICACHE_LINESIZE);
@ -80,7 +80,7 @@ int kernel_get_cacheline_size()
}
#if defined(__linux__) || defined(__APPLE__)
int kernel_get_page_size()
int villas::kernel::get_page_size()
{
return sysconf(_SC_PAGESIZE);
}
@ -89,7 +89,7 @@ int kernel_get_page_size()
#endif
/* There is no sysconf interface to get the hugepage size */
int kernel_get_hugepage_size()
int villas::kernel::get_hugepage_size()
{
#ifdef __linux__
char *key, *value, *unit, *line = nullptr, *lasts;
@ -127,7 +127,7 @@ int kernel_get_hugepage_size()
#ifdef __linux__
int kernel_module_set_param(const char *module, const char *param, const char *value)
int villas::kernel::module_set_param(const char *module, const char *param, const char *value)
{
FILE *f;
char fn[256];
@ -144,11 +144,11 @@ int kernel_module_set_param(const char *module, const char *param, const char *v
return 0;
}
int kernel_module_load(const char *module)
int villas::kernel::module_load(const char *module)
{
int ret;
ret = kernel_module_loaded(module);
ret = module_loaded(module);
if (!ret) {
debug(LOG_KERNEL | 5, "Kernel module %s already loaded...", module);
return 0;
@ -166,11 +166,11 @@ int kernel_module_load(const char *module)
default:
wait(&ret);
return kernel_module_loaded(module);
return module_loaded(module);
}
}
int kernel_module_loaded(const char *module)
int villas::kernel::module_loaded(const char *module)
{
FILE *f;
int ret = -1;
@ -194,7 +194,7 @@ int kernel_module_loaded(const char *module)
return ret;
}
int kernel_get_cmdline_param(const char *param, char *buf, size_t len)
int villas::kernel::get_cmdline_param(const char *param, char *buf, size_t len)
{
int ret;
char cmdline[512], key[128], value[128], *lasts, *tok;
@ -230,7 +230,7 @@ out:
return -1; /* not found or error */
}
int kernel_get_nr_hugepages()
int villas::kernel::get_nr_hugepages()
{
FILE *f;
int nr, ret;
@ -248,7 +248,7 @@ int kernel_get_nr_hugepages()
return nr;
}
int kernel_set_nr_hugepages(int nr)
int villas::kernel::set_nr_hugepages(int nr)
{
FILE *f;
int ret;
@ -272,7 +272,7 @@ int kernel_set_nr_hugepages(int nr)
return 0;
}
int kernel_irq_setaffinity(unsigned irq, uintmax_t aff, uintmax_t *old)
int villas::kernel::irq_setaffinity(unsigned irq, uintmax_t aff, uintmax_t *old)
{
char fn[64];
FILE *f;
@ -293,7 +293,7 @@ int kernel_irq_setaffinity(unsigned irq, uintmax_t aff, uintmax_t *old)
return ret;
}
int kernel_get_cpu_frequency(uint64_t *freq)
int villas::kernel::get_cpu_frequency(uint64_t *freq)
{
char *line = nullptr, *sep, *end;
size_t len = 0;

View file

@ -26,11 +26,13 @@
#include <unistd.h>
#include <linux/limits.h>
#include <villas/log.h>
#include <villas/log.hpp>
#include <villas/utils.hpp>
#include <villas/exceptions.hpp>
#include <villas/config.h>
#include <villas/kernel/pci.h>
using namespace villas;
using namespace villas::utils;
int pci_init(struct pci *p)
@ -58,6 +60,10 @@ int pci_init(struct pci *p)
continue;
struct pci_device *d = new struct pci_device;
if (!d)
throw RuntimeError("Failed to allocate memory!");
memset(d, 0, sizeof(struct pci_device));
struct { const char *s; int *p; } map[] = {
{ "vendor", &d->id.vendor },
@ -314,6 +320,9 @@ size_t pci_get_regions(const struct pci_device *d, struct pci_region** regions)
if (valid_regions > 0) {
*regions = new struct pci_region[valid_regions];
if (!*regions)
throw RuntimeError("Failed to allocate memory!");
memcpy(*regions, _regions, valid_regions * sizeof (struct pci_region));
}

View file

@ -29,7 +29,7 @@
#include <villas/utils.hpp>
#include <villas/exceptions.hpp>
#include <villas/kernel/kernel.h>
#include <villas/kernel/kernel.hpp>
#include <villas/kernel/kernel.hpp>
#include <villas/kernel/rt.hpp>
@ -83,7 +83,7 @@ void setAffinity(int affinity)
/* Pin threads to CPUs by setting the affinity */
CpuSet cset_pin(affinity);
is_isol = kernel_get_cmdline_param("isolcpus", isolcpus, sizeof(isolcpus));
is_isol = get_cmdline_param("isolcpus", isolcpus, sizeof(isolcpus));
if (is_isol)
logger->warn("You should reserve some cores for " PROJECT_NAME " (see 'isolcpus')");
else {

View file

@ -46,7 +46,7 @@
#include <villas/log.hpp>
#include <villas/kernel/pci.h>
#include <villas/kernel/kernel.h>
#include <villas/kernel/kernel.hpp>
#include <villas/kernel/vfio.hpp>
using namespace villas;
@ -84,8 +84,8 @@ VfioContainer::VfioContainer()
"vfio", "vfio_pci", "vfio_iommu_type1"
};
for(const char* module : requiredKernelModules) {
if(kernel_module_load(module) != 0) {
for (const char* module : requiredKernelModules) {
if (kernel::module_load(module) != 0) {
logger->error("Kernel module '{}' required but could not be loaded. "
"Please load manually!", module);
throw std::exception();
@ -299,7 +299,7 @@ VfioContainer::attachDevice(const pci_device* pdev)
Logger logger = logging.get("kernel:vfio");
/* Load PCI bus driver for VFIO */
if (kernel_module_load("vfio_pci")) {
if (kernel::module_load("vfio_pci")) {
logger->error("Failed to load kernel driver: vfio_pci");
throw std::exception();
}
@ -318,7 +318,7 @@ VfioContainer::attachDevice(const pci_device* pdev)
/* Get IOMMU group of device */
int index = isIommuEnabled() ? pci_get_iommu_group(pdev) : 0;
if (index < 0) {
ret = kernel_get_cmdline_param("intel_iommu", iommu_state, sizeof(iommu_state));
ret = kernel::get_cmdline_param("intel_iommu", iommu_state, sizeof(iommu_state));
if(ret != 0 || strcmp("on", iommu_state) != 0)
logger->warn("Kernel booted without command line parameter "
"'intel_iommu' set to 'on'. Please check documentation "

View file

@ -17,7 +17,7 @@
#include <villas/utils.hpp>
#include <villas/log.h>
#include <villas/config.h>
#include <villas/kernel/kernel.h>
#include <villas/kernel/kernel.hpp>
#include <villas/kernel/vfio.h>
#include <villas/kernel/pci.h>
@ -134,7 +134,7 @@ int vfio_init(struct vfio_container *v)
vlist_init(&v->groups);
/* Load VFIO kernel module */
if (kernel_module_load("vfio"))
if (module_load("vfio"))
error("Failed to load kernel module: %s", "vfio");
/* Open VFIO API */
@ -207,7 +207,7 @@ int vfio_pci_attach(struct vfio_device *d, struct vfio_container *c, struct pci_
int ret;
/* Load PCI bus driver for VFIO */
if (kernel_module_load("vfio_pci"))
if (module_load("vfio_pci"))
error("Failed to load kernel driver: %s", "vfio_pci");
/* Bind PCI card to vfio-pci driver*/
@ -253,6 +253,10 @@ int vfio_device_attach(struct vfio_device *d, struct vfio_container *c, const ch
if (!g) {
g = new struct vfio_group;
if (!g)
throw RuntimeError("Failed to allocate memory!");
memset(g, 0, sizeof(struct vfio_group));
/* Aquire group ownership */
ret = vfio_group_attach(g, c, index);

View file

@ -190,13 +190,11 @@ void * vlist_lookup(struct vlist *l, const char *name)
return vlist_search(l, cmp_lookup, (void *) name);
}
ssize_t vlist_lookup_index(struct vlist *l, const char *name)
ssize_t vlist_lookup_index(struct vlist *l, const void *ptr)
{
void *ptr = vlist_lookup(l, name);
if (!ptr)
return -1;
void *found = vlist_lookup(l, (char *) ptr);
return vlist_index(l, ptr);
return found ? vlist_index(l, found) : -1;
}
int vlist_contains(struct vlist *l, void *p)

View file

@ -27,6 +27,7 @@
#include <spdlog/sinks/basic_file_sink.h>
#include <villas/log.hpp>
#include <villas/terminal.hpp>
#include <villas/exceptions.hpp>
using namespace villas;
@ -36,6 +37,7 @@ Log villas::logging;
Log::Log(Level lvl) :
level(lvl),
// pattern("%+")
pattern("%H:%M:%S %^%l%$ %n: %v")
{
char *p = getenv("VILLAS_LOG_PREFIX");
@ -91,7 +93,7 @@ void Log::parse(json_t *cfg)
json_error_t err;
json_t *json_expressions = nullptr;
ret = json_unpack_ex(cfg, &err, JSON_STRICT, "{ s?: s, s?: s, s?: s, s?: b, s?: s }",
ret = json_unpack_ex(cfg, &err, JSON_STRICT, "{ s?: s, s?: s, s?: o, s?: b, s?: s }",
"level", &level,
"file", &path,
"expressions", &json_expressions,

View file

@ -100,12 +100,12 @@ Plugin::dump()
logger->info("Name: '{}' Description: '{}'", name, description);
}
std::string Plugin::getName()
const std::string & Plugin::getName() const
{
return name;
}
std::string Plugin::getDescription()
const std::string & Plugin::getDescription() const
{
return description;
}

View file

@ -25,113 +25,101 @@
#include <cerrno>
#include <villas/utils.hpp>
#include <villas/task.h>
#include <villas/task.hpp>
#include <villas/timing.h>
#include <villas/exceptions.hpp>
using namespace villas;
#if PERIODIC_TASK_IMPL == TIMERFD
#include <sys/timerfd.h>
#endif /* PERIODIC_TASK_IMPL */
int task_init(struct task *t, double rate, int clock)
Task::Task(int clk) :
clock(clk)
{
int ret;
t->clock = clock;
#if PERIODIC_TASK_IMPL == TIMERFD
t->fd = timerfd_create(t->clock, 0);
if (t->fd < 0)
return -1;
fd = timerfd_create(clock, 0);
if (fd < 0)
throw SystemError("Failed to create timerfd");
#elif PERIODIC_TASK_IMPL == RDTSC
ret = tsc_init(&t->tsc);
int ret = tsc_init(&tsc);
if (ret)
return ret;
#endif /* PERIODIC_TASK_IMPL */
ret = task_set_rate(t, rate);
if (ret)
return ret;
return 0;
}
int task_set_timeout(struct task *t, double to)
void Task::setTimeout(double to)
{
struct timespec now;
clock_gettime(t->clock, &now);
clock_gettime(clock, &now);
struct timespec timeout = time_from_double(to);
struct timespec next = time_add(&now, &timeout);
return task_set_next(t, &next);
setNext(&next);
}
int task_set_next(struct task *t, struct timespec *next)
void Task::setNext(const struct timespec *nxt)
{
#if PERIODIC_TASK_IMPL != RDTSC
t->next = *next;
next = *nxt;
#if PERIODIC_TASK_IMPL == TIMERFD
int ret;
struct itimerspec its = {
.it_interval = (struct timespec) { 0, 0 },
.it_value = t->next
.it_value = next
};
ret = timerfd_settime(t->fd, TFD_TIMER_ABSTIME, &its, nullptr);
ret = timerfd_settime(fd, TFD_TIMER_ABSTIME, &its, nullptr);
if (ret)
return ret;
throw SystemError("Failed to set timerfd");
#endif /* PERIODIC_TASK_IMPL == TIMERFD */
#endif /* PERIODIC_TASK_IMPL != RDTSC */
return 0;
}
int task_set_rate(struct task *t, double rate)
void Task::setRate(double rate)
{
#if PERIODIC_TASK_IMPL == RDTSC
t->period = tsc_rate_to_cycles(&t->tsc, rate);
t->next = tsc_now(&t->tsc) + t->period;
period = tsc_rate_to_cycles(&tsc, rate);
next = tsc_now(&tsc) + period;
#else
/* A rate of 0 will disarm the timer */
t->period = rate ? time_from_double(1.0 / rate) : (struct timespec) { 0, 0 };
period = rate ? time_from_double(1.0 / rate) : (struct timespec) { 0, 0 };
#if PERIODIC_TASK_IMPL == CLOCK_NANOSLEEP || PERIODIC_TASK_IMPL == NANOSLEEP
struct timespec now, next;
clock_gettime(t->clock, &now);
clock_gettime(clock, &now);
next = time_add(&now, &t->period);
next = time_add(&now, &period);
return task_set_next(t, &next);
return setNext(&next);
#elif PERIODIC_TASK_IMPL == TIMERFD
int ret;
struct itimerspec its = {
.it_interval = t->period,
.it_value = t->period
.it_interval = period,
.it_value = period
};
ret = timerfd_settime(t->fd, 0, &its, nullptr);
ret = timerfd_settime(fd, 0, &its, nullptr);
if (ret)
return ret;
throw SystemError("Failed to set timerfd");
#endif /* PERIODIC_TASK_IMPL */
#endif /* PERIODIC_TASK_IMPL == RDTSC */
return 0;
}
int task_destroy(struct task *t)
Task::~Task()
{
#if PERIODIC_TASK_IMPL == TIMERFD
return close(t->fd);
#else
return 0;
close(fd);
#endif
}
uint64_t task_wait(struct task *t)
uint64_t Task::wait()
{
uint64_t runs;
@ -139,19 +127,19 @@ uint64_t task_wait(struct task *t)
int ret;
struct timespec now;
ret = clock_gettime(t->clock, &now);
ret = clock_gettime(clock, &now);
if (ret)
return ret;
for (runs = 0; time_cmp(&t->next, &now) < 0; runs++)
t->next = time_add(&t->next, &t->period);
for (runs = 0; time_cmp(&next, &now) < 0; runs++)
next = time_add(&next, &period);
#if PERIODIC_TASK_IMPL == CLOCK_NANOSLEEP
do {
ret = clock_nanosleep(t->clock, TIMER_ABSTIME, &t->next, nullptr);
ret = clock_nanosleep(clock, TIMER_ABSTIME, &next, nullptr);
} while (ret == EINTR);
#elif PERIODIC_TASK_IMPL == NANOSLEEP
struct timespec req, rem = time_diff(&now, &t->next);
struct timespec req, rem = time_diff(&now, &next);
do {
req = rem;
@ -161,28 +149,28 @@ uint64_t task_wait(struct task *t)
if (ret)
return 0;
ret = clock_gettime(t->clock, &now);
ret = clock_gettime(clock, &now);
if (ret)
return ret;
for (; time_cmp(&t->next, &now) < 0; runs++)
t->next = time_add(&t->next, &t->period);
for (; time_cmp(&next, &now) < 0; runs++)
next = time_add(&next, &period);
#elif PERIODIC_TASK_IMPL == TIMERFD
int ret;
ret = read(t->fd, &runs, sizeof(runs));
ret = read(fd, &runs, sizeof(runs));
if (ret < 0)
return 0;
#elif PERIODIC_TASK_IMPL == RDTSC
uint64_t now;
do {
now = tsc_now(&t->tsc);
} while (now < t->next);
now = tsc_now(&tsc);
} while (now < next);
for (runs = 0; t->next < now; runs++)
t->next += t->period;
for (runs = 0; next < now; runs++)
next += period;
#else
#error "Invalid period task implementation"
#endif
@ -190,10 +178,25 @@ uint64_t task_wait(struct task *t)
return runs;
}
int task_fd(struct task *t)
void Task::stop()
{
#if PERIODIC_TASK_IMPL == TIMERFD
return t->fd;
int ret;
struct itimerspec its = {
.it_interval = (struct timespec) { 0, 0 },
.it_value = (struct timespec) { 0, 0 }
};
ret = timerfd_settime(fd, 0, &its, nullptr);
if (ret)
throw SystemError("Failed to disarm timerfd");
#endif /* PERIODIC_TASK_IMPL == TIMERFD */
}
int Task::getFD() const
{
#if PERIODIC_TASK_IMPL == TIMERFD
return fd;
#else
return -1;
#endif

View file

@ -40,6 +40,8 @@ Terminal::Terminal()
isTty = isatty(fileno(stdin));
if (isTty) {
Logger logger = logging.get("terminal");
struct sigaction sa_resize;
sa_resize.sa_flags = SA_SIGINFO;
sa_resize.sa_sigaction = resize;
@ -53,7 +55,7 @@ Terminal::Terminal()
/* Try to get initial terminal dimensions */
ret = ioctl(STDERR_FILENO, TIOCGWINSZ, &window);
if (ret)
throw SystemError("Failed to get terminal dimensions");
logger->warn("Failed to get terminal dimensions");
}
/* Fallback if for some reason we can not determine a prober window size */

View file

@ -23,6 +23,8 @@
#include <villas/tsc.h>
using namespace villas;
int tsc_init(struct tsc *t)
{
uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
@ -50,7 +52,7 @@ int tsc_init(struct tsc *t)
else {
int ret;
#ifdef __linux__
ret = kernel_get_cpu_frequency(&t->frequency);
ret = kernel::get_cpu_frequency(&t->frequency);
if (ret)
return ret;
#elif defined(__APPLE__)

View file

@ -42,7 +42,6 @@
#include <villas/config.h>
#include <villas/utils.hpp>
#include <villas/colors.hpp>
#include <villas/config.h>
#include <villas/log.hpp>
static pthread_t main_thread;

View file

@ -25,7 +25,7 @@
#include <criterion/criterion.h>
#include <villas/utils.hpp>
#include <villas/advio.h>
#include <villas/advio.hpp>
using namespace villas;

View file

@ -30,7 +30,7 @@
using namespace villas;
using villas::Buffer;
using villas::JsonBuffer;
TestSuite(buffer, .description = "Buffer datastructure");

View file

@ -22,9 +22,10 @@
#include <criterion/criterion.h>
#include <villas/kernel/kernel.h>
#include <villas/kernel/kernel.hpp>
using namespace villas::kernel;
TestSuite(kernel, .description = "Kernel features");
#if defined(__x86_64__) || defined(__i386__)
@ -45,13 +46,13 @@ Test(kernel, sizes)
{
int sz;
sz = kernel_get_page_size();
sz = get_page_size();
cr_assert_eq(sz, PAGESIZE);
sz = kernel_get_hugepage_size();
sz = get_hugepage_size();
cr_assert(sz == HUGEPAGESIZE);
sz = kernel_get_cacheline_size();
sz = get_cacheline_size();
cr_assert_eq(sz, CACHELINESIZE);
}
@ -60,16 +61,16 @@ Test(kernel, hugepages)
{
int ret;
ret = kernel_set_nr_hugepages(25);
ret = set_nr_hugepages(25);
cr_assert_eq(ret, 0);
ret = kernel_get_nr_hugepages();
ret = get_nr_hugepages();
cr_assert_eq(ret, 25);
ret = kernel_set_nr_hugepages(10);
ret = set_nr_hugepages(10);
cr_assert_eq(ret, 0);
ret = kernel_get_nr_hugepages();
ret = get_nr_hugepages();
cr_assert_eq(ret, 10);
}
@ -89,10 +90,10 @@ Test(kernel, module, .disabled = true)
{
int ret;
ret = kernel_module_loaded("nf_nat");
ret = module_loaded("nf_nat");
cr_assert_eq(ret, 0);
ret = kernel_module_loaded("does_not_exist");
ret = module_loaded("does_not_exist");
cr_assert_neq(ret, 0);
}
@ -101,7 +102,7 @@ Test(kernel, frequency)
int ret;
uint64_t freq;
ret = kernel_get_cpu_frequency(&freq);
ret = get_cpu_frequency(&freq);
cr_assert_eq(ret, 0);
/* Check for plausability only */

View file

@ -24,27 +24,25 @@
#include <math.h>
#include <villas/task.h>
#include <villas/task.hpp>
#include <villas/timing.h>
TestSuite(task, .description = "Periodic timer tasks");
Test(task, rate, .timeout = 10)
{
int ret;
int runs = 10;
double rate = 5, waited;
struct timespec start, end;
struct task task;
Task task(CLOCK_MONOTONIC);
ret = task_init(&task, rate, CLOCK_MONOTONIC);
cr_assert_eq(ret, 0);
task.setRate(rate);
int i;
for (i = 0; i < runs; i++) {
clock_gettime(CLOCK_MONOTONIC, &start);
task_wait(&task);
task.wait();
clock_gettime(CLOCK_MONOTONIC, &end);
@ -56,19 +54,14 @@ Test(task, rate, .timeout = 10)
if (i < runs)
cr_assert_float_eq(waited, 1.0 / rate, 1e-2, "We slept for %f instead of %f secs in round %d", waited, 1.0 / rate, i);
ret = task_destroy(&task);
cr_assert_eq(ret, 0);
}
Test(task, wait_until, .timeout = 5)
{
int ret;
struct task task;
struct timespec start, end, diff, future;
ret = task_init(&task, 1, CLOCK_REALTIME);
cr_assert_eq(ret, 0);
Task task(CLOCK_REALTIME);
double waitfor = 3.423456789;
@ -76,10 +69,9 @@ Test(task, wait_until, .timeout = 5)
diff = time_from_double(waitfor);
future = time_add(&start, &diff);
ret = task_set_next(&task, &future);
cr_assert_eq(ret, 0);
task.setNext(&future);
ret = task_wait(&task);
ret = task.wait();
end = time_now();
@ -88,7 +80,4 @@ Test(task, wait_until, .timeout = 5)
double waited = time_delta(&start, &end);
cr_assert_float_eq(waited, waitfor, 1e-2, "We slept for %f instead of %f secs", waited, waitfor);
ret = task_destroy(&task);
cr_assert_eq(ret, 0);
}