mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
use C++ compiler
This commit is contained in:
parent
f5e4c61fb8
commit
73cb4f8512
27 changed files with 655 additions and 644 deletions
|
@ -121,7 +121,7 @@ int vlist_contains(struct vlist *l, void *p);
|
|||
void vlist_sort(struct vlist *l, cmp_cb_t cmp);
|
||||
|
||||
/** Set single element in list */
|
||||
int vlist_set(struct vlist *l, int index, void *value);
|
||||
int vlist_set(struct vlist *l, unsigned index, void *value);
|
||||
|
||||
/** Return index in list for value.
|
||||
*
|
||||
|
|
|
@ -27,38 +27,72 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
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. */
|
||||
class Table;
|
||||
|
||||
enum {
|
||||
TABLE_ALIGN_LEFT,
|
||||
TABLE_ALIGN_RIGHT
|
||||
} align;
|
||||
class TableColumn {
|
||||
|
||||
friend Table;
|
||||
|
||||
public:
|
||||
enum align {
|
||||
LEFT,
|
||||
RIGHT
|
||||
};
|
||||
|
||||
protected:
|
||||
int _width; /**< The real width of this column. Calculated by table_header() */
|
||||
|
||||
int width; /**< Width of the column. */
|
||||
|
||||
public:
|
||||
TableColumn(int w, enum align a, const std::string &t, const std::string &f, const std::string &u = "") :
|
||||
width(w),
|
||||
title(t),
|
||||
format(f),
|
||||
unit(u),
|
||||
align(a)
|
||||
{ }
|
||||
|
||||
std::string title; /**< The title as shown in the table header. */
|
||||
std::string format; /**< The format which is used to print the table rows. */
|
||||
std::string unit; /**< An optional unit which will be shown in the table header. */
|
||||
|
||||
enum align align;
|
||||
|
||||
int getWidth() const
|
||||
{
|
||||
return _width;
|
||||
}
|
||||
};
|
||||
|
||||
struct table {
|
||||
int ncols;
|
||||
class Table {
|
||||
|
||||
protected:
|
||||
int resize(int w);
|
||||
|
||||
int width;
|
||||
struct table_column *cols;
|
||||
|
||||
std::vector<TableColumn> columns;
|
||||
|
||||
public:
|
||||
Table(const std::vector<TableColumn> &cols) :
|
||||
width(-1),
|
||||
columns(cols)
|
||||
{ }
|
||||
|
||||
/** Print a table header consisting of \p n columns. */
|
||||
void header();
|
||||
|
||||
/** Print table rows. */
|
||||
void row(int count, ...);
|
||||
|
||||
int getWidth() const
|
||||
{
|
||||
return width;
|
||||
}
|
||||
};
|
||||
|
||||
/** Print a table header consisting of \p n columns. */
|
||||
void table_header(struct table *t);
|
||||
|
||||
/** Print table rows. */
|
||||
void table_row(struct table *t, ...);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/** @} */
|
|
@ -21,34 +21,33 @@
|
|||
##############################################################################
|
||||
|
||||
add_library(villas-common SHARED
|
||||
advio.c
|
||||
bitset.c
|
||||
buffer.c
|
||||
advio.cpp
|
||||
bitset.cpp
|
||||
buffer.cpp
|
||||
json_buffer.cpp
|
||||
compat.c
|
||||
crypt.c
|
||||
hash_table.c
|
||||
hist.c
|
||||
kernel/kernel.c
|
||||
compat.cpp
|
||||
crypt.cpp
|
||||
hash_table.cpp
|
||||
hist.cpp
|
||||
kernel/kernel.cpp
|
||||
kernel/kernel.cpp
|
||||
kernel/rt.cpp
|
||||
list.c
|
||||
list.cpp
|
||||
log.cpp
|
||||
log_legacy.cpp
|
||||
memory.cpp
|
||||
memory_manager.cpp
|
||||
plugin.cpp
|
||||
table.c
|
||||
task.c
|
||||
timing.c
|
||||
utils.c
|
||||
table.cpp
|
||||
task.cpp
|
||||
timing.cpp
|
||||
utils.cpp
|
||||
cpuset.cpp
|
||||
terminal.cpp
|
||||
version.cpp
|
||||
copyright.cpp
|
||||
common.c
|
||||
window.c
|
||||
common.cpp
|
||||
window.cpp
|
||||
)
|
||||
|
||||
execute_process(
|
||||
|
@ -58,13 +57,14 @@ execute_process(
|
|||
)
|
||||
|
||||
if(ARCH STREQUAL "x86_64")
|
||||
target_sources(villas-common PRIVATE tsc.c)
|
||||
target_sources(villas-common PRIVATE tsc.cpp)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Linux)
|
||||
target_sources(villas-common PRIVATE
|
||||
kernel/pci.c
|
||||
kernel/pci.cpp
|
||||
kernel/vfio.cpp
|
||||
# kernel/vfio_legacy.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
#define BAR_WIDTH 60 /**< How wide you want the progress meter to be. */
|
||||
|
||||
static int advio_trace(CURL *handle, curl_infotype type, char *data, size_t size, void *userp)
|
||||
static int advio_trace(CURL * /* handle */, curl_infotype type, char *data, size_t size, void * /* userp */)
|
||||
{
|
||||
const char *text;
|
||||
|
||||
|
@ -83,7 +83,7 @@ static int advio_trace(CURL *handle, curl_infotype type, char *data, size_t size
|
|||
|
||||
static char * advio_human_time(double t, char *buf, size_t len)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned i = 0;
|
||||
const char *units[] = { "secs", "mins", "hrs", "days", "weeks", "months", "years" };
|
||||
int divs[] = { 60, 60, 24, 7, 4, 12 };
|
||||
|
||||
|
@ -99,7 +99,7 @@ static char * advio_human_time(double t, char *buf, size_t len)
|
|||
|
||||
static char * advio_human_size(double s, char *buf, size_t len)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned i = 0;
|
||||
const char *units[] = { "B", "kiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB" };
|
||||
|
||||
while (s > 1024 && i < ARRAY_LEN(units)) {
|
||||
|
@ -180,14 +180,14 @@ static int advio_xferinfo(void *p, curl_off_t dl_total_bytes, curl_off_t dl_byte
|
|||
|
||||
int aislocal(const char *uri)
|
||||
{
|
||||
char *sep;
|
||||
const char *sep;
|
||||
const char *supported_schemas[] = { "file", "http", "https", "tftp", "ftp", "scp", "sftp", "smb", "smbs" };
|
||||
|
||||
sep = strstr(uri, "://");
|
||||
if (!sep)
|
||||
return 1; /* no schema, we assume its a local file */
|
||||
|
||||
for (int i = 0; i < ARRAY_LEN(supported_schemas); i++) {
|
||||
for (unsigned i = 0; i < ARRAY_LEN(supported_schemas); i++) {
|
||||
if (!strncmp(supported_schemas[i], uri, sep - uri))
|
||||
return 0;
|
||||
}
|
||||
|
@ -198,9 +198,10 @@ int aislocal(const char *uri)
|
|||
AFILE * afopen(const char *uri, const char *mode)
|
||||
{
|
||||
int ret;
|
||||
char *sep, *cwd;
|
||||
char *cwd;
|
||||
const char *sep;
|
||||
|
||||
AFILE *af = alloc(sizeof(AFILE));
|
||||
AFILE *af = (AFILE *) alloc(sizeof(AFILE));
|
||||
|
||||
snprintf(af->mode, sizeof(af->mode), "%s", mode);
|
||||
|
||||
|
@ -290,29 +291,29 @@ int afclose(AFILE *af)
|
|||
|
||||
int afseek(AFILE *af, long offset, int origin)
|
||||
{
|
||||
long new, cur = aftell(af);
|
||||
long new_seek, cur_seek = aftell(af);
|
||||
|
||||
switch (origin) {
|
||||
case SEEK_SET:
|
||||
new = offset;
|
||||
new_seek = offset;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
fseek(af->file, 0, SEEK_END);
|
||||
new = aftell(af);
|
||||
fseek(af->file, cur, SEEK_SET);
|
||||
new_seek = aftell(af);
|
||||
fseek(af->file, cur_seek, SEEK_SET);
|
||||
break;
|
||||
|
||||
case SEEK_CUR:
|
||||
new = cur + offset;
|
||||
new_seek = cur_seek + offset;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (new < af->uploaded)
|
||||
af->uploaded = new;
|
||||
if (new_seek < af->uploaded)
|
||||
af->uploaded = new_seek;
|
||||
|
||||
return fseek(af->file, offset, origin);
|
||||
}
|
||||
|
@ -403,6 +404,7 @@ int adownload(AFILE *af, int resume)
|
|||
|
||||
double total_bytes = 0, total_time = 0;
|
||||
char buf[2][32];
|
||||
char *total_bytes_human, *total_time_human;
|
||||
|
||||
pos = aftell(af);
|
||||
|
||||
|
@ -428,8 +430,8 @@ int adownload(AFILE *af, int resume)
|
|||
curl_easy_getinfo(af->curl, CURLINFO_SIZE_DOWNLOAD, &total_bytes);
|
||||
curl_easy_getinfo(af->curl, CURLINFO_TOTAL_TIME, &total_time);
|
||||
|
||||
char *total_bytes_human = advio_human_size(total_bytes, buf[0], sizeof(buf[0]));
|
||||
char *total_time_human = advio_human_time(total_time, buf[1], sizeof(buf[1]));
|
||||
total_bytes_human = advio_human_size(total_bytes, buf[0], sizeof(buf[0]));
|
||||
total_time_human = advio_human_time(total_time, buf[1], sizeof(buf[1]));
|
||||
|
||||
info("Finished download of %s in %s", total_bytes_human, total_time_human);
|
||||
|
||||
|
@ -460,6 +462,7 @@ int adownload(AFILE *af, int resume)
|
|||
af->file = fopen(af->uri, af->mode);
|
||||
if (!af->file)
|
||||
return -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
error("Failed to download file: %s: %s", af->uri, curl_easy_strerror(res));
|
|
@ -34,7 +34,7 @@ int bitset_init(struct bitset *b, size_t dim)
|
|||
{
|
||||
int s = bitset_nslots(dim);
|
||||
|
||||
b->set = alloc(s * CHAR_BIT);
|
||||
b->set = (char *) alloc(s * CHAR_BIT);
|
||||
b->dimension = dim;
|
||||
|
||||
return 0;
|
||||
|
@ -163,7 +163,7 @@ char * bitset_dump(struct bitset *b)
|
|||
{
|
||||
char *str = NULL;
|
||||
|
||||
for (int i = 0; i < b->dimension; i++)
|
||||
for (unsigned i = 0; i < b->dimension; i++)
|
||||
strcatf(&str, "%d", bitset_test(b, i));
|
||||
|
||||
return str;
|
|
@ -30,7 +30,7 @@ int buffer_init(struct buffer *b, size_t size)
|
|||
{
|
||||
b->len = 0;
|
||||
b->size = size;
|
||||
b->buf = malloc(size);
|
||||
b->buf = (char *) malloc(size);
|
||||
if (!b->buf)
|
||||
return -1;
|
||||
|
||||
|
@ -58,7 +58,7 @@ int buffer_append(struct buffer *b, const char *data, size_t len)
|
|||
{
|
||||
if (b->len + len > b->size) {
|
||||
b->size = b->len + len;
|
||||
b->buf = realloc(b->buf, b->size);
|
||||
b->buf = (char *) realloc(b->buf, b->size);
|
||||
if (!b->buf)
|
||||
return -1;
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ int buffer_append_json(struct buffer *b, json_t *j)
|
|||
|
||||
retry: len = json_dumpb(j, b->buf + b->len, b->size - b->len, 0);
|
||||
if (b->size < b->len + len) {
|
||||
b->buf = realloc(b->buf, b->len + len);
|
||||
b->buf = (char *) realloc(b->buf, b->len + len);
|
||||
if (!b->buf)
|
||||
return -1;
|
||||
|
|
@ -43,7 +43,7 @@ int hash_table_init(struct hash_table *ht, size_t size)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ht->table = alloc(len);
|
||||
ht->table = (struct hash_table_entry **) alloc(len);
|
||||
|
||||
memset(ht->table, 0, len);
|
||||
|
||||
|
@ -62,7 +62,7 @@ int hash_table_destroy(struct hash_table *ht, dtor_cb_t dtor, bool release)
|
|||
|
||||
pthread_mutex_lock(&ht->lock);
|
||||
|
||||
for (int i = 0; i < ht->size; i++) {
|
||||
for (unsigned i = 0; i < ht->size; i++) {
|
||||
for (cur = ht->table[i]; cur; cur = next) {
|
||||
if (dtor)
|
||||
dtor(cur->data);
|
||||
|
@ -106,7 +106,7 @@ int hash_table_insert(struct hash_table *ht, const void *key, void *data)
|
|||
if (cur)
|
||||
ret = -1;
|
||||
else {
|
||||
hte = alloc(sizeof(struct hash_table_entry));
|
||||
hte = (struct hash_table_entry *) alloc(sizeof(struct hash_table_entry));
|
||||
if (hte) {
|
||||
hte->key = key;
|
||||
hte->data = data;
|
||||
|
@ -191,7 +191,7 @@ void hash_table_dump(struct hash_table *ht)
|
|||
|
||||
pthread_mutex_lock(&ht->lock);
|
||||
|
||||
for (int i = 0; i < ht->size; i++) {
|
||||
for (unsigned i = 0; i < ht->size; i++) {
|
||||
char *strlst = NULL;
|
||||
|
||||
for (hte = ht->table[i]; hte; hte = hte->next)
|
|
@ -28,9 +28,9 @@
|
|||
#include <time.h>
|
||||
|
||||
#include <villas/utils.h>
|
||||
#include <villas/hist.h>
|
||||
#include <villas/hist.hpp>
|
||||
#include <villas/config.h>
|
||||
#include <villas/table.h>
|
||||
#include <villas/table.hpp>
|
||||
|
||||
#define VAL(h, i) ((h)->low + (i) * (h)->resolution)
|
||||
#define INDEX(h, v) round((v - (h)->low) / (h)->resolution)
|
||||
|
@ -40,7 +40,7 @@ int hist_init(struct hist *h, int buckets, hist_cnt_t warmup)
|
|||
h->length = buckets;
|
||||
h->warmup = warmup;
|
||||
|
||||
h->data = buckets ? alloc(h->length * sizeof(hist_cnt_t)) : NULL;
|
||||
h->data = (hist_cnt_t *) (buckets ? alloc(h->length * sizeof(hist_cnt_t)) : nullptr);
|
||||
|
||||
hist_reset(h);
|
||||
|
||||
|
@ -51,7 +51,7 @@ int hist_destroy(struct hist *h)
|
|||
{
|
||||
if (h->data) {
|
||||
free(h->data);
|
||||
h->data = NULL;
|
||||
h->data = nullptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -83,7 +83,7 @@ void hist_put(struct hist *h, double value)
|
|||
h->higher++;
|
||||
else if (idx < 0)
|
||||
h->lower++;
|
||||
else if (h->data != NULL)
|
||||
else if (h->data != nullptr)
|
||||
h->data[idx]++;
|
||||
}
|
||||
|
||||
|
@ -169,30 +169,27 @@ void hist_plot(const struct hist *h)
|
|||
max = h->data[i];
|
||||
}
|
||||
|
||||
struct table_column cols[] = {
|
||||
{ -9, "Value", "%+9.3g", NULL, TABLE_ALIGN_RIGHT },
|
||||
{ -6, "Count", "%6ju", NULL, TABLE_ALIGN_RIGHT },
|
||||
{ 0, "Plot", "%s", "occurences", TABLE_ALIGN_LEFT }
|
||||
std::vector<TableColumn> cols = {
|
||||
{ -9, TableColumn::align::RIGHT, "Value", "%+9.3g" },
|
||||
{ -6, TableColumn::align::RIGHT, "Count", "%6ju" },
|
||||
{ 0, TableColumn::align::LEFT, "Plot", "%s", "occurences" }
|
||||
};
|
||||
|
||||
struct table table = {
|
||||
.ncols = ARRAY_LEN(cols),
|
||||
.cols = cols
|
||||
};
|
||||
Table table = Table(cols);
|
||||
|
||||
/* Print plot */
|
||||
table_header(&table);
|
||||
table.header();
|
||||
|
||||
for (int i = 0; i < h->length; i++) {
|
||||
double value = VAL(h, i);
|
||||
hist_cnt_t cnt = h->data[i];
|
||||
int bar = cols[2]._width * ((double) cnt / max);
|
||||
int bar = cols[2].getWidth() * ((double) cnt / max);
|
||||
|
||||
char *buf = strf("%s", "");
|
||||
for (int i = 0; i < bar; i++)
|
||||
buf = strcatf(&buf, "\u2588");
|
||||
|
||||
table_row(&table, value, cnt, buf);
|
||||
table.row(value, cnt, buf);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
@ -200,7 +197,7 @@ void hist_plot(const struct hist *h)
|
|||
|
||||
char * hist_dump(const struct hist *h)
|
||||
{
|
||||
char *buf = alloc(128);
|
||||
char *buf = (char *) alloc(128);
|
||||
|
||||
strcatf(&buf, "[ ");
|
||||
|
|
@ -1,326 +0,0 @@
|
|||
/** Linux kernel related functions.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2019, 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/>.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <villas/utils.h>
|
||||
#include <villas/config.h>
|
||||
#include <villas/kernel/kernel.h>
|
||||
|
||||
int kernel_get_cacheline_size()
|
||||
{
|
||||
#if defined(__linux__) && defined(__x86_64__)
|
||||
return sysconf(_SC_LEVEL1_ICACHE_LINESIZE);
|
||||
#elif defined(__MACH__)
|
||||
/* Open the command for reading. */
|
||||
FILE *fp = popen("sysctl -n machdep.cpu.cache.linesize", "r");
|
||||
if (fp == NULL)
|
||||
return -1;
|
||||
|
||||
int ret, size;
|
||||
|
||||
ret = fscanf(fp, "%d", &size);
|
||||
|
||||
pclose(fp);
|
||||
|
||||
return ret == 1 ? size : -1;
|
||||
#else
|
||||
return CACHELINE_SIZE;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
int kernel_get_page_size()
|
||||
{
|
||||
return sysconf(_SC_PAGESIZE);
|
||||
}
|
||||
#else
|
||||
#error "Unsupported platform"
|
||||
#endif
|
||||
|
||||
/* There is no sysconf interface to get the hugepage size */
|
||||
int kernel_get_hugepage_size()
|
||||
{
|
||||
#ifdef __linux__
|
||||
char *key, *value, *unit, *line = NULL, *lasts;
|
||||
int sz = -1;
|
||||
size_t len = 0;
|
||||
FILE *f;
|
||||
|
||||
f = fopen(PROCFS_PATH "/meminfo", "r");
|
||||
if (!f)
|
||||
return -1;
|
||||
|
||||
while (getline(&line, &len, f) != -1) {
|
||||
key = strtok_r(line, ": ", &lasts);
|
||||
value = strtok_r(NULL, " ", &lasts);
|
||||
unit = strtok_r(NULL, "\n", &lasts);
|
||||
|
||||
if (!strcmp(key, "Hugepagesize") && !strcmp(unit, "kB")) {
|
||||
sz = strtoul(value, NULL, 10) * 1024;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(f);
|
||||
|
||||
return sz;
|
||||
#elif defined(__x86_64__)
|
||||
return 1 << 21;
|
||||
#elif defined(__i386__)
|
||||
return 1 << 22;
|
||||
#else
|
||||
#error "Unsupported architecture"
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
int kernel_module_set_param(const char *module, const char *param, const char *value)
|
||||
{
|
||||
FILE *f;
|
||||
char fn[256];
|
||||
|
||||
snprintf(fn, sizeof(fn), "%s/module/%s/parameters/%s", SYSFS_PATH, module, param);
|
||||
f = fopen(fn, "w");
|
||||
if (!f)
|
||||
serror("Failed set parameter %s for kernel module %s to %s", module, param, value);
|
||||
|
||||
debug(LOG_KERNEL | 5, "Set parameter %s of kernel module %s to %s", module, param, value);
|
||||
fprintf(f, "%s", value);
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kernel_module_load(const char *module)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = kernel_module_loaded(module);
|
||||
if (!ret) {
|
||||
debug(LOG_KERNEL | 5, "Kernel module %s already loaded...", module);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pid_t pid = fork();
|
||||
switch (pid) {
|
||||
case -1: /* error */
|
||||
return -1;
|
||||
|
||||
case 0: /* child */
|
||||
execlp("modprobe", "modprobe", module, (char *) 0);
|
||||
exit(EXIT_FAILURE); /* exec never returns */
|
||||
|
||||
default:
|
||||
wait(&ret);
|
||||
|
||||
return kernel_module_loaded(module);
|
||||
}
|
||||
}
|
||||
|
||||
int kernel_module_loaded(const char *module)
|
||||
{
|
||||
FILE *f;
|
||||
int ret = -1;
|
||||
char *line = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
f = fopen(PROCFS_PATH "/modules", "r");
|
||||
if (!f)
|
||||
return -1;
|
||||
|
||||
while (getline(&line, &len, f) >= 0) {
|
||||
if (strstr(line, module) == line) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(f);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int kernel_get_cmdline_param(const char *param, char *buf, size_t len)
|
||||
{
|
||||
int ret;
|
||||
char cmdline[512], *lasts;
|
||||
|
||||
FILE *f = fopen(PROCFS_PATH "/cmdline", "r");
|
||||
if (!f)
|
||||
return -1;
|
||||
|
||||
if (!fgets(cmdline, sizeof(cmdline), f))
|
||||
goto out;
|
||||
|
||||
char *tok = strtok_r(cmdline, " \t", &lasts);
|
||||
do {
|
||||
char key[128], value[128];
|
||||
|
||||
ret = sscanf(tok, "%127[^=]=%127s", key, value);
|
||||
if (ret >= 1) {
|
||||
if (ret >= 2)
|
||||
debug(30, "Found kernel param: %s=%s", key, value);
|
||||
else
|
||||
debug(30, "Found kernel param: %s", key);
|
||||
|
||||
if (strcmp(param, key) == 0) {
|
||||
if (ret >= 2 && buf)
|
||||
snprintf(buf, len, "%s", value);
|
||||
|
||||
return 0; /* found */
|
||||
}
|
||||
}
|
||||
} while ((tok = strtok_r(NULL, " \t", &lasts)));
|
||||
|
||||
out:
|
||||
fclose(f);
|
||||
|
||||
return -1; /* not found or error */
|
||||
}
|
||||
|
||||
int kernel_get_nr_hugepages()
|
||||
{
|
||||
FILE *f;
|
||||
int nr, ret;
|
||||
|
||||
f = fopen(PROCFS_PATH "/sys/vm/nr_hugepages", "r");
|
||||
if (!f)
|
||||
serror("Failed to open %s", PROCFS_PATH "/sys/vm/nr_hugepages");
|
||||
|
||||
ret = fscanf(f, "%d", &nr);
|
||||
if (ret != 1)
|
||||
nr = -1;
|
||||
|
||||
fclose(f);
|
||||
|
||||
return nr;
|
||||
}
|
||||
|
||||
int kernel_set_nr_hugepages(int nr)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
f = fopen(PROCFS_PATH "/sys/vm/nr_hugepages", "w");
|
||||
if (!f)
|
||||
serror("Failed to open %s", PROCFS_PATH "/sys/vm/nr_hugepages");
|
||||
|
||||
fprintf(f, "%d\n", nr);
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kernel_irq_setaffinity(unsigned irq, uintmax_t aff, uintmax_t *old)
|
||||
{
|
||||
char fn[64];
|
||||
FILE *f;
|
||||
int ret = 0;
|
||||
|
||||
snprintf(fn, sizeof(fn), "/proc/irq/%u/smp_affinity", irq);
|
||||
|
||||
f = fopen(fn, "w+");
|
||||
if (!f)
|
||||
return -1; /* IRQ does not exist */
|
||||
|
||||
if (old)
|
||||
ret = fscanf(f, "%jx", old);
|
||||
|
||||
fprintf(f, "%jx", aff);
|
||||
fclose(f);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int kernel_get_cpu_frequency(uint64_t *freq)
|
||||
{
|
||||
char *line = NULL, *sep, *end;
|
||||
size_t len = 0;
|
||||
double dfreq;
|
||||
int ret;
|
||||
FILE *f;
|
||||
|
||||
/* Try to get CPU frequency from cpufreq module */
|
||||
f = fopen(SYSFS_PATH "/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", "r");
|
||||
if (!f)
|
||||
goto cpuinfo;
|
||||
|
||||
ret = fscanf(f, "%" PRIu64, freq);
|
||||
fclose(f);
|
||||
if (ret != 1)
|
||||
return -1;
|
||||
|
||||
/* cpufreq reports kHz */
|
||||
*freq = *freq * 1000;
|
||||
|
||||
return 0;
|
||||
|
||||
cpuinfo:
|
||||
/* Try to read CPU frequency from /proc/cpuinfo */
|
||||
f = fopen(PROCFS_PATH "/cpuinfo", "r");
|
||||
if (!f)
|
||||
return -1; /* We give up here */
|
||||
|
||||
ret = -1;
|
||||
while (getline(&line, &len, f) >= 0) {
|
||||
if (strstr(line, "cpu MHz") == line) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
sep = strchr(line, ':');
|
||||
if (!sep) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dfreq = strtod(sep+1, &end);
|
||||
|
||||
if (end == sep+1) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Frequency is given in MHz */
|
||||
*freq = dfreq * 1e6;
|
||||
|
||||
out: fclose(f);
|
||||
free(line);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* __linux__ */
|
|
@ -21,6 +21,20 @@
|
|||
*********************************************************************************/
|
||||
|
||||
#include <sys/utsname.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <villas/utils.h>
|
||||
#include <villas/config.h>
|
||||
#include <villas/kernel/kernel.h>
|
||||
|
||||
#include <villas/kernel/kernel.hpp>
|
||||
#include <villas/exceptions.hpp>
|
||||
|
@ -42,3 +56,291 @@ Version villas::kernel::getVersion()
|
|||
|
||||
return Version(ver);
|
||||
}
|
||||
|
||||
int kernel_get_cacheline_size()
|
||||
{
|
||||
#if defined(__linux__) && defined(__x86_64__)
|
||||
return sysconf(_SC_LEVEL1_ICACHE_LINESIZE);
|
||||
#elif defined(__MACH__)
|
||||
/* Open the command for reading. */
|
||||
FILE *fp = popen("sysctl -n machdep.cpu.cache.linesize", "r");
|
||||
if (fp == NULL)
|
||||
return -1;
|
||||
|
||||
int ret, size;
|
||||
|
||||
ret = fscanf(fp, "%d", &size);
|
||||
|
||||
pclose(fp);
|
||||
|
||||
return ret == 1 ? size : -1;
|
||||
#else
|
||||
return CACHELINE_SIZE;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
int kernel_get_page_size()
|
||||
{
|
||||
return sysconf(_SC_PAGESIZE);
|
||||
}
|
||||
#else
|
||||
#error "Unsupported platform"
|
||||
#endif
|
||||
|
||||
/* There is no sysconf interface to get the hugepage size */
|
||||
int kernel_get_hugepage_size()
|
||||
{
|
||||
#ifdef __linux__
|
||||
char *key, *value, *unit, *line = NULL, *lasts;
|
||||
int sz = -1;
|
||||
size_t len = 0;
|
||||
FILE *f;
|
||||
|
||||
f = fopen(PROCFS_PATH "/meminfo", "r");
|
||||
if (!f)
|
||||
return -1;
|
||||
|
||||
while (getline(&line, &len, f) != -1) {
|
||||
key = strtok_r(line, ": ", &lasts);
|
||||
value = strtok_r(NULL, " ", &lasts);
|
||||
unit = strtok_r(NULL, "\n", &lasts);
|
||||
|
||||
if (!strcmp(key, "Hugepagesize") && !strcmp(unit, "kB")) {
|
||||
sz = strtoul(value, NULL, 10) * 1024;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(f);
|
||||
|
||||
return sz;
|
||||
#elif defined(__x86_64__)
|
||||
return 1 << 21;
|
||||
#elif defined(__i386__)
|
||||
return 1 << 22;
|
||||
#else
|
||||
#error "Unsupported architecture"
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
int kernel_module_set_param(const char *module, const char *param, const char *value)
|
||||
{
|
||||
FILE *f;
|
||||
char fn[256];
|
||||
|
||||
snprintf(fn, sizeof(fn), "%s/module/%s/parameters/%s", SYSFS_PATH, module, param);
|
||||
f = fopen(fn, "w");
|
||||
if (!f)
|
||||
serror("Failed set parameter %s for kernel module %s to %s", module, param, value);
|
||||
|
||||
debug(LOG_KERNEL | 5, "Set parameter %s of kernel module %s to %s", module, param, value);
|
||||
fprintf(f, "%s", value);
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kernel_module_load(const char *module)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = kernel_module_loaded(module);
|
||||
if (!ret) {
|
||||
debug(LOG_KERNEL | 5, "Kernel module %s already loaded...", module);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pid_t pid = fork();
|
||||
switch (pid) {
|
||||
case -1: /* error */
|
||||
return -1;
|
||||
|
||||
case 0: /* child */
|
||||
execlp("modprobe", "modprobe", module, (char *) 0);
|
||||
exit(EXIT_FAILURE); /* exec never returns */
|
||||
|
||||
default:
|
||||
wait(&ret);
|
||||
|
||||
return kernel_module_loaded(module);
|
||||
}
|
||||
}
|
||||
|
||||
int kernel_module_loaded(const char *module)
|
||||
{
|
||||
FILE *f;
|
||||
int ret = -1;
|
||||
char *line = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
f = fopen(PROCFS_PATH "/modules", "r");
|
||||
if (!f)
|
||||
return -1;
|
||||
|
||||
while (getline(&line, &len, f) >= 0) {
|
||||
if (strstr(line, module) == line) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(f);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int kernel_get_cmdline_param(const char *param, char *buf, size_t len)
|
||||
{
|
||||
int ret;
|
||||
char cmdline[512], key[128], value[128], *lasts, *tok;
|
||||
|
||||
FILE *f = fopen(PROCFS_PATH "/cmdline", "r");
|
||||
if (!f)
|
||||
return -1;
|
||||
|
||||
if (!fgets(cmdline, sizeof(cmdline), f))
|
||||
goto out;
|
||||
|
||||
tok = strtok_r(cmdline, " \t", &lasts);
|
||||
do {
|
||||
ret = sscanf(tok, "%127[^=]=%127s", key, value);
|
||||
if (ret >= 1) {
|
||||
if (ret >= 2)
|
||||
debug(30, "Found kernel param: %s=%s", key, value);
|
||||
else
|
||||
debug(30, "Found kernel param: %s", key);
|
||||
|
||||
if (strcmp(param, key) == 0) {
|
||||
if (ret >= 2 && buf)
|
||||
snprintf(buf, len, "%s", value);
|
||||
|
||||
return 0; /* found */
|
||||
}
|
||||
}
|
||||
} while ((tok = strtok_r(NULL, " \t", &lasts)));
|
||||
|
||||
out:
|
||||
fclose(f);
|
||||
|
||||
return -1; /* not found or error */
|
||||
}
|
||||
|
||||
int kernel_get_nr_hugepages()
|
||||
{
|
||||
FILE *f;
|
||||
int nr, ret;
|
||||
|
||||
f = fopen(PROCFS_PATH "/sys/vm/nr_hugepages", "r");
|
||||
if (!f)
|
||||
serror("Failed to open %s", PROCFS_PATH "/sys/vm/nr_hugepages");
|
||||
|
||||
ret = fscanf(f, "%d", &nr);
|
||||
if (ret != 1)
|
||||
nr = -1;
|
||||
|
||||
fclose(f);
|
||||
|
||||
return nr;
|
||||
}
|
||||
|
||||
int kernel_set_nr_hugepages(int nr)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
f = fopen(PROCFS_PATH "/sys/vm/nr_hugepages", "w");
|
||||
if (!f)
|
||||
serror("Failed to open %s", PROCFS_PATH "/sys/vm/nr_hugepages");
|
||||
|
||||
fprintf(f, "%d\n", nr);
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kernel_irq_setaffinity(unsigned irq, uintmax_t aff, uintmax_t *old)
|
||||
{
|
||||
char fn[64];
|
||||
FILE *f;
|
||||
int ret = 0;
|
||||
|
||||
snprintf(fn, sizeof(fn), "/proc/irq/%u/smp_affinity", irq);
|
||||
|
||||
f = fopen(fn, "w+");
|
||||
if (!f)
|
||||
return -1; /* IRQ does not exist */
|
||||
|
||||
if (old)
|
||||
ret = fscanf(f, "%jx", old);
|
||||
|
||||
fprintf(f, "%jx", aff);
|
||||
fclose(f);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int kernel_get_cpu_frequency(uint64_t *freq)
|
||||
{
|
||||
char *line = NULL, *sep, *end;
|
||||
size_t len = 0;
|
||||
double dfreq;
|
||||
int ret;
|
||||
FILE *f;
|
||||
|
||||
/* Try to get CPU frequency from cpufreq module */
|
||||
f = fopen(SYSFS_PATH "/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", "r");
|
||||
if (!f)
|
||||
goto cpuinfo;
|
||||
|
||||
ret = fscanf(f, "%" PRIu64, freq);
|
||||
fclose(f);
|
||||
if (ret != 1)
|
||||
return -1;
|
||||
|
||||
/* cpufreq reports kHz */
|
||||
*freq = *freq * 1000;
|
||||
|
||||
return 0;
|
||||
|
||||
cpuinfo:
|
||||
/* Try to read CPU frequency from /proc/cpuinfo */
|
||||
f = fopen(PROCFS_PATH "/cpuinfo", "r");
|
||||
if (!f)
|
||||
return -1; /* We give up here */
|
||||
|
||||
ret = -1;
|
||||
while (getline(&line, &len, f) >= 0) {
|
||||
if (strstr(line, "cpu MHz") == line) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
sep = strchr(line, ':');
|
||||
if (!sep) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dfreq = strtod(sep+1, &end);
|
||||
|
||||
if (end == sep+1) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Frequency is given in MHz */
|
||||
*freq = dfreq * 1e6;
|
||||
|
||||
out: fclose(f);
|
||||
free(line);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
|
|
|
@ -175,19 +175,20 @@ fail:
|
|||
int pci_device_parse_id(struct pci_device *f, const char *str, const char **error)
|
||||
{
|
||||
char *s, *c, *e;
|
||||
char *tmp = strdup(str);
|
||||
|
||||
if (!*str)
|
||||
if (!*tmp)
|
||||
return 0;
|
||||
|
||||
s = strchr(str, ':');
|
||||
s = strchr(tmp, ':');
|
||||
if (!s) {
|
||||
*error = "':' expected";
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*s++ = 0;
|
||||
if (str[0] && strcmp(str, "*")) {
|
||||
long int x = strtol(str, &e, 16);
|
||||
if (tmp[0] && strcmp(tmp, "*")) {
|
||||
long int x = strtol(tmp, &e, 16);
|
||||
|
||||
if ((e && *e) || (x < 0 || x > 0xffff)) {
|
||||
*error = "Invalid vendor ID";
|
||||
|
@ -225,6 +226,7 @@ int pci_device_parse_id(struct pci_device *f, const char *str, const char **erro
|
|||
return 0;
|
||||
|
||||
fail:
|
||||
free(tmp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -248,7 +250,7 @@ int pci_device_compare(const struct pci_device *d, const struct pci_device *f)
|
|||
|
||||
struct pci_device * pci_lookup_device(struct pci *p, struct pci_device *f)
|
||||
{
|
||||
return vlist_search(&p->devices, (cmp_cb_t) pci_device_compare, (void *) f);
|
||||
return (struct pci_device *) vlist_search(&p->devices, (cmp_cb_t) pci_device_compare, (void *) f);
|
||||
}
|
||||
|
||||
size_t pci_get_regions(const struct pci_device *d, struct pci_region** regions)
|
||||
|
@ -276,10 +278,10 @@ size_t pci_get_regions(const struct pci_device *d, struct pci_region** regions)
|
|||
int region = 0;
|
||||
|
||||
/* Cap to 8 regions, just because we don't know how many may exist. */
|
||||
while(region < 8 && (bytesRead = getline(&line, &len, f)) != -1) {
|
||||
while (region < 8 && (bytesRead = getline(&line, &len, f)) != -1) {
|
||||
unsigned long long tokens[3];
|
||||
char* s = line;
|
||||
for(int i = 0; i < 3; i++) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
char* end;
|
||||
tokens[i] = strtoull(s, &end, 16);
|
||||
if(s == end) {
|
||||
|
@ -296,7 +298,7 @@ size_t pci_get_regions(const struct pci_device *d, struct pci_region** regions)
|
|||
line = NULL;
|
||||
len = 0;
|
||||
|
||||
if(tokens[0] != tokens[1]) {
|
||||
if (tokens[0] != tokens[1]) {
|
||||
/* This is a valid region */
|
||||
cur_region->num = region;
|
||||
cur_region->start = tokens[0];
|
||||
|
@ -309,9 +311,9 @@ size_t pci_get_regions(const struct pci_device *d, struct pci_region** regions)
|
|||
region++;
|
||||
}
|
||||
|
||||
if(valid_regions > 0) {
|
||||
if (valid_regions > 0) {
|
||||
const size_t len = valid_regions * sizeof (struct pci_region);
|
||||
*regions = malloc(len);
|
||||
*regions = (struct pci_region *) malloc(len);
|
||||
memcpy(*regions, _regions, len);
|
||||
}
|
||||
|
|
@ -30,11 +30,13 @@
|
|||
|
||||
/* Compare functions */
|
||||
static int cmp_lookup(const void *a, const void *b) {
|
||||
const struct {
|
||||
struct name_tag {
|
||||
char *name;
|
||||
} *obj = a;
|
||||
};
|
||||
|
||||
return strcmp(obj->name, b);
|
||||
const name_tag *obj = (struct name_tag *) a;
|
||||
|
||||
return strcmp(obj->name, (char *) b);
|
||||
}
|
||||
|
||||
static int cmp_contains(const void *a, const void *b) {
|
||||
|
@ -102,7 +104,7 @@ void vlist_push(struct vlist *l, void *p)
|
|||
/* Resize array if out of capacity */
|
||||
if (l->length >= l->capacity) {
|
||||
l->capacity += LIST_CHUNKSIZE;
|
||||
l->array = realloc(l->array, l->capacity * sizeof(void *));
|
||||
l->array = (void **) realloc(l->array, l->capacity * sizeof(void *));
|
||||
}
|
||||
|
||||
l->array[l->length] = p;
|
||||
|
@ -145,7 +147,7 @@ int vlist_insert(struct vlist *l, size_t idx, void *p)
|
|||
/* Resize array if out of capacity */
|
||||
if (l->length + 1 > l->capacity) {
|
||||
l->capacity += LIST_CHUNKSIZE;
|
||||
l->array = realloc(l->array, l->capacity * sizeof(void *));
|
||||
l->array = (void **) realloc(l->array, l->capacity * sizeof(void *));
|
||||
}
|
||||
|
||||
o = p;
|
||||
|
@ -258,7 +260,7 @@ void vlist_sort(struct vlist *l, cmp_cb_t cmp)
|
|||
pthread_mutex_unlock(&l->lock);
|
||||
}
|
||||
|
||||
int vlist_set(struct vlist *l, int index, void *value)
|
||||
int vlist_set(struct vlist *l, unsigned index, void *value)
|
||||
{
|
||||
if (index >= l->length)
|
||||
return -1;
|
|
@ -81,9 +81,9 @@ Logger Log::get(const std::string &name)
|
|||
|
||||
void Log::parse(json_t *cfg)
|
||||
{
|
||||
const char *level = NULL;
|
||||
const char *path = NULL;
|
||||
const char *pattern = NULL;
|
||||
const char *level = nullptr;
|
||||
const char *path = nullptr;
|
||||
const char *pattern = nullptr;
|
||||
|
||||
int syslog;
|
||||
int ret;
|
||||
|
|
|
@ -24,62 +24,62 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <villas/utils.h>
|
||||
#include <villas/table.h>
|
||||
#include <villas/table.hpp>
|
||||
#include <villas/log.h>
|
||||
|
||||
static int table_resize(struct table *t, int width)
|
||||
int Table::resize(int w)
|
||||
{
|
||||
int norm, flex, fixed, total;
|
||||
|
||||
t->width = width;
|
||||
width = w;
|
||||
|
||||
norm = 0;
|
||||
flex = 0;
|
||||
fixed = 0;
|
||||
total = t->width - t->ncols * 2;
|
||||
total = width - columns.size() * 2;
|
||||
|
||||
/* Normalize width */
|
||||
for (int i = 0; i < t->ncols; i++) {
|
||||
if (t->cols[i].width > 0)
|
||||
norm += t->cols[i].width;
|
||||
if (t->cols[i].width == 0)
|
||||
for (unsigned i = 0; i < columns.size(); i++) {
|
||||
if (columns[i].width > 0)
|
||||
norm += columns[i].width;
|
||||
if (columns[i].width == 0)
|
||||
flex++;
|
||||
if (t->cols[i].width < 0)
|
||||
fixed += -1 * t->cols[i].width;
|
||||
if (columns[i].width < 0)
|
||||
fixed += -1 * columns[i].width;
|
||||
}
|
||||
|
||||
for (int i = 0; i < t->ncols; i++) {
|
||||
if (t->cols[i].width > 0)
|
||||
t->cols[i]._width = t->cols[i].width * (float) (total - fixed) / norm;
|
||||
if (t->cols[i].width == 0)
|
||||
t->cols[i]._width = (float) (total - fixed) / flex;
|
||||
if (t->cols[i].width < 0)
|
||||
t->cols[i]._width = -1 * t->cols[i].width;
|
||||
for (unsigned i = 0; i < columns.size(); i++) {
|
||||
if (columns[i].width > 0)
|
||||
columns[i]._width = columns[i].width * (float) (total - fixed) / norm;
|
||||
if (columns[i].width == 0)
|
||||
columns[i]._width = (float) (total - fixed) / flex;
|
||||
if (columns[i].width < 0)
|
||||
columns[i]._width = -1 * columns[i].width;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void table_header(struct table *t)
|
||||
void Table::header()
|
||||
{
|
||||
if (t->width != log_get_width())
|
||||
table_resize(t, log_get_width());
|
||||
if (width != log_get_width())
|
||||
resize(log_get_width());
|
||||
|
||||
char *line1 = NULL;
|
||||
char *line2 = NULL;
|
||||
char *line3 = NULL;
|
||||
char *line1 = nullptr;
|
||||
char *line2 = nullptr;
|
||||
char *line3 = nullptr;
|
||||
|
||||
for (int i = 0; i < t->ncols; i++) {
|
||||
for (unsigned i = 0; i < columns.size(); i++) {
|
||||
int w, u;
|
||||
char *col, *unit;
|
||||
|
||||
col = strf(CLR_BLD("%s"), t->cols[i].title);
|
||||
unit = t->cols[i].unit ? strf(CLR_YEL("%s"), t->cols[i].unit) : "";
|
||||
col = strf(CLR_BLD("%s"), columns[i].title.c_str());
|
||||
unit = columns[i].unit.size() ? strf(CLR_YEL("%s"), columns[i].unit.c_str()) : strf("");
|
||||
|
||||
w = t->cols[i]._width + strlen(col) - strlenp(col);
|
||||
u = t->cols[i]._width + strlen(unit) - strlenp(unit);
|
||||
w = columns[i]._width + strlen(col) - strlenp(col);
|
||||
u = columns[i]._width + strlen(unit) - strlenp(unit);
|
||||
|
||||
if (t->cols[i].align == TABLE_ALIGN_LEFT) {
|
||||
if (columns[i].align == TableColumn::align::LEFT) {
|
||||
strcatf(&line1, " %-*.*s\e[0m", w, w, col);
|
||||
strcatf(&line2, " %-*.*s\e[0m", u, u, unit);
|
||||
}
|
||||
|
@ -88,11 +88,11 @@ void table_header(struct table *t)
|
|||
strcatf(&line2, " %*.*s\e[0m", u, u, unit);
|
||||
}
|
||||
|
||||
for (int j = 0; j < t->cols[i]._width + 2; j++) {
|
||||
for (int j = 0; j < columns[i]._width + 2; j++) {
|
||||
strcatf(&line3, "%s", BOX_LR);
|
||||
}
|
||||
|
||||
if (i != t->ncols - 1) {
|
||||
if (i != columns.size() - 1) {
|
||||
strcatf(&line1, " %s", BOX_UD);
|
||||
strcatf(&line2, " %s", BOX_UD);
|
||||
strcatf(&line3, "%s", BOX_UDLR);
|
||||
|
@ -110,31 +110,31 @@ void table_header(struct table *t)
|
|||
free(line3);
|
||||
}
|
||||
|
||||
void table_row(struct table *t, ...)
|
||||
void Table::row(int count, ...)
|
||||
{
|
||||
if (t->width != log_get_width()) {
|
||||
table_resize(t, log_get_width());
|
||||
table_header(t);
|
||||
if (width != log_get_width()) {
|
||||
resize(log_get_width());
|
||||
header();
|
||||
}
|
||||
|
||||
va_list args;
|
||||
va_start(args, t);
|
||||
va_start(args, count);
|
||||
|
||||
char *line = NULL;
|
||||
char *line = nullptr;
|
||||
|
||||
for (int i = 0; i < t->ncols; ++i) {
|
||||
char *col = vstrf(t->cols[i].format, args);
|
||||
for (unsigned i = 0; i < columns.size(); ++i) {
|
||||
char *col = vstrf(columns[i].format.c_str(), args);
|
||||
|
||||
int l = strlenp(col);
|
||||
int r = strlen(col);
|
||||
int w = t->cols[i]._width + r - l;
|
||||
int w = columns[i]._width + r - l;
|
||||
|
||||
if (t->cols[i].align == TABLE_ALIGN_LEFT)
|
||||
if (columns[i].align == TableColumn::align::LEFT)
|
||||
strcatf(&line, " %-*.*s\e[0m ", w, w, col);
|
||||
else
|
||||
strcatf(&line, " %*.*s\e[0m ", w, w, col);
|
||||
|
||||
if (i != t->ncols - 1)
|
||||
if (i != columns.size() - 1)
|
||||
strcatf(&line, BOX_UD);
|
||||
|
||||
free(col);
|
|
@ -46,7 +46,7 @@ Terminal::Terminal()
|
|||
|
||||
sigemptyset(&sa_resize.sa_mask);
|
||||
|
||||
ret = sigaction(SIGWINCH, &sa_resize, NULL);
|
||||
ret = sigaction(SIGWINCH, &sa_resize, nullptr);
|
||||
if (ret)
|
||||
throw SystemError("Failed to register signal handler");
|
||||
|
||||
|
|
|
@ -20,166 +20,3 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <pthread.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <villas/config.h>
|
||||
#include <villas/utils.h>
|
||||
|
||||
double box_muller(float m, float s)
|
||||
{
|
||||
double x1, x2, y1;
|
||||
static double y2;
|
||||
static int use_last = 0;
|
||||
|
||||
if (use_last) { /* use value from previous call */
|
||||
y1 = y2;
|
||||
use_last = 0;
|
||||
}
|
||||
else {
|
||||
double w;
|
||||
do {
|
||||
x1 = 2.0 * randf() - 1.0;
|
||||
x2 = 2.0 * randf() - 1.0;
|
||||
w = x1*x1 + x2*x2;
|
||||
} while (w >= 1.0);
|
||||
|
||||
w = sqrt(-2.0 * log(w) / w);
|
||||
y1 = x1 * w;
|
||||
y2 = x2 * w;
|
||||
use_last = 1;
|
||||
}
|
||||
|
||||
return m + y1 * s;
|
||||
}
|
||||
|
||||
double randf()
|
||||
{
|
||||
return (double) random() / RAND_MAX;
|
||||
}
|
||||
|
||||
char * strcatf(char **dest, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vstrcatf(dest, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return *dest;
|
||||
}
|
||||
|
||||
char * vstrcatf(char **dest, const char *fmt, va_list ap)
|
||||
{
|
||||
char *tmp;
|
||||
int n = *dest ? strlen(*dest) : 0;
|
||||
int i = vasprintf(&tmp, fmt, ap);
|
||||
|
||||
*dest = (char *)(realloc(*dest, n + i + 1));
|
||||
if (*dest != NULL)
|
||||
strncpy(*dest+n, tmp, i + 1);
|
||||
|
||||
free(tmp);
|
||||
|
||||
return *dest;
|
||||
}
|
||||
|
||||
char * strf(const char *fmt, ...)
|
||||
{
|
||||
char *buf = NULL;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vstrcatf(&buf, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
char * vstrf(const char *fmt, va_list va)
|
||||
{
|
||||
char *buf = NULL;
|
||||
|
||||
vstrcatf(&buf, fmt, va);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void * alloc(size_t bytes)
|
||||
{
|
||||
void *p = malloc(bytes);
|
||||
if (!p)
|
||||
error("Failed to allocate memory");
|
||||
|
||||
memset(p, 0, bytes);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void * memdup(const void *src, size_t bytes)
|
||||
{
|
||||
void *dst = alloc(bytes);
|
||||
|
||||
memcpy(dst, src, bytes);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
pid_t spawn(const char* name, char *const argv[])
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
pid = fork();
|
||||
switch (pid) {
|
||||
case -1: return -1;
|
||||
case 0: return execvp(name, (char * const*) argv);
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
size_t strlenp(const char *str)
|
||||
{
|
||||
size_t sz = 0;
|
||||
|
||||
for (const char *d = str; *d; d++) {
|
||||
const unsigned char *c = (const unsigned char *) d;
|
||||
|
||||
if (isprint(*c))
|
||||
sz++;
|
||||
else if (c[0] == '\b')
|
||||
sz--;
|
||||
else if (c[0] == '\t')
|
||||
sz += 4; /* tab width == 4 */
|
||||
/* CSI sequence */
|
||||
else if (c[0] == '\e' && c[1] == '[') {
|
||||
c += 2;
|
||||
while (*c && *c != 'm')
|
||||
c++;
|
||||
}
|
||||
/* UTF-8 */
|
||||
else if (c[0] >= 0xc2 && c[0] <= 0xdf) {
|
||||
sz++;
|
||||
c += 1;
|
||||
}
|
||||
else if (c[0] >= 0xe0 && c[0] <= 0xef) {
|
||||
sz++;
|
||||
c += 2;
|
||||
}
|
||||
else if (c[0] >= 0xf0 && c[0] <= 0xf4) {
|
||||
sz++;
|
||||
c += 3;
|
||||
}
|
||||
|
||||
d = (const char *) c;
|
||||
}
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
|
|
@ -24,9 +24,19 @@
|
|||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <pthread.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <villas/config.h>
|
||||
#include <villas/utils.h>
|
||||
#include <villas/utils.hpp>
|
||||
#include <villas/config.h>
|
||||
|
@ -107,19 +117,19 @@ int signals_init(void (*cb)(int signal, siginfo_t *sinfo, void *ctx))
|
|||
sigemptyset(&sa_quit.sa_mask);
|
||||
sigemptyset(&sa_chld.sa_mask);
|
||||
|
||||
ret = sigaction(SIGINT, &sa_quit, NULL);
|
||||
ret = sigaction(SIGINT, &sa_quit, nullptr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = sigaction(SIGTERM, &sa_quit, NULL);
|
||||
ret = sigaction(SIGTERM, &sa_quit, nullptr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = sigaction(SIGALRM, &sa_quit, NULL);
|
||||
ret = sigaction(SIGALRM, &sa_quit, nullptr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = sigaction(SIGCHLD, &sa_chld, NULL);
|
||||
ret = sigaction(SIGCHLD, &sa_chld, nullptr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -174,3 +184,153 @@ void killme(int sig)
|
|||
|
||||
} /* namespace utils */
|
||||
} /* namespace villas */
|
||||
|
||||
double box_muller(float m, float s)
|
||||
{
|
||||
double x1, x2, y1;
|
||||
static double y2;
|
||||
static int use_last = 0;
|
||||
|
||||
if (use_last) { /* use value from previous call */
|
||||
y1 = y2;
|
||||
use_last = 0;
|
||||
}
|
||||
else {
|
||||
double w;
|
||||
do {
|
||||
x1 = 2.0 * randf() - 1.0;
|
||||
x2 = 2.0 * randf() - 1.0;
|
||||
w = x1*x1 + x2*x2;
|
||||
} while (w >= 1.0);
|
||||
|
||||
w = sqrt(-2.0 * log(w) / w);
|
||||
y1 = x1 * w;
|
||||
y2 = x2 * w;
|
||||
use_last = 1;
|
||||
}
|
||||
|
||||
return m + y1 * s;
|
||||
}
|
||||
|
||||
double randf()
|
||||
{
|
||||
return (double) random() / RAND_MAX;
|
||||
}
|
||||
|
||||
char * strcatf(char **dest, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vstrcatf(dest, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return *dest;
|
||||
}
|
||||
|
||||
char * vstrcatf(char **dest, const char *fmt, va_list ap)
|
||||
{
|
||||
char *tmp;
|
||||
int n = *dest ? strlen(*dest) : 0;
|
||||
int i = vasprintf(&tmp, fmt, ap);
|
||||
|
||||
*dest = (char *)(realloc(*dest, n + i + 1));
|
||||
if (*dest != NULL)
|
||||
strncpy(*dest+n, tmp, i + 1);
|
||||
|
||||
free(tmp);
|
||||
|
||||
return *dest;
|
||||
}
|
||||
|
||||
char * strf(const char *fmt, ...)
|
||||
{
|
||||
char *buf = NULL;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vstrcatf(&buf, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
char * vstrf(const char *fmt, va_list va)
|
||||
{
|
||||
char *buf = NULL;
|
||||
|
||||
vstrcatf(&buf, fmt, va);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void * alloc(size_t bytes)
|
||||
{
|
||||
void *p = malloc(bytes);
|
||||
if (!p)
|
||||
error("Failed to allocate memory");
|
||||
|
||||
memset(p, 0, bytes);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void * memdup(const void *src, size_t bytes)
|
||||
{
|
||||
void *dst = alloc(bytes);
|
||||
|
||||
memcpy(dst, src, bytes);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
pid_t spawn(const char* name, char *const argv[])
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
pid = fork();
|
||||
switch (pid) {
|
||||
case -1: return -1;
|
||||
case 0: return execvp(name, (char * const*) argv);
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
size_t strlenp(const char *str)
|
||||
{
|
||||
size_t sz = 0;
|
||||
|
||||
for (const char *d = str; *d; d++) {
|
||||
const unsigned char *c = (const unsigned char *) d;
|
||||
|
||||
if (isprint(*c))
|
||||
sz++;
|
||||
else if (c[0] == '\b')
|
||||
sz--;
|
||||
else if (c[0] == '\t')
|
||||
sz += 4; /* tab width == 4 */
|
||||
/* CSI sequence */
|
||||
else if (c[0] == '\e' && c[1] == '[') {
|
||||
c += 2;
|
||||
while (*c && *c != 'm')
|
||||
c++;
|
||||
}
|
||||
/* UTF-8 */
|
||||
else if (c[0] >= 0xc2 && c[0] <= 0xdf) {
|
||||
sz++;
|
||||
c += 1;
|
||||
}
|
||||
else if (c[0] >= 0xe0 && c[0] <= 0xef) {
|
||||
sz++;
|
||||
c += 2;
|
||||
}
|
||||
else if (c[0] >= 0xf0 && c[0] <= 0xf4) {
|
||||
sz++;
|
||||
c += 3;
|
||||
}
|
||||
|
||||
d = (const char *) c;
|
||||
}
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ int window_init(struct window *w, size_t steps, double init)
|
|||
size_t len = LOG2_CEIL(steps);
|
||||
|
||||
/* Allocate memory for ciruclar history buffer */
|
||||
w->data = alloc(len * sizeof(double));
|
||||
w->data = (double *) alloc(len * sizeof(double));
|
||||
if (!w->data)
|
||||
return -1;
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include <criterion/criterion.h>
|
||||
|
||||
#include <villas/hist.h>
|
||||
#include <villas/hist.hpp>
|
||||
#include <villas/utils.h>
|
||||
|
||||
const double test_data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
|
|
Loading…
Add table
Reference in a new issue