2014-06-05 09:34:29 +00:00
|
|
|
/**
|
|
|
|
* Some helper functions
|
|
|
|
*
|
|
|
|
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
|
|
|
* @copyright 2014, Institute for Automation of Complex Power Systems, EONERC
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2014-06-05 09:34:56 +00:00
|
|
|
#include <string.h>
|
2014-06-05 09:34:29 +00:00
|
|
|
#include <time.h>
|
2014-06-05 09:34:56 +00:00
|
|
|
#include <errno.h>
|
2014-06-05 09:35:23 +00:00
|
|
|
#include <sched.h>
|
|
|
|
#include <unistd.h>
|
2014-06-05 09:34:56 +00:00
|
|
|
#include <netdb.h>
|
2014-06-05 09:35:23 +00:00
|
|
|
#include <sched.h>
|
|
|
|
|
2014-06-05 09:34:56 +00:00
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <arpa/inet.h>
|
2014-06-05 09:35:23 +00:00
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
2014-06-05 09:34:29 +00:00
|
|
|
|
|
|
|
#include "config.h"
|
2014-06-05 09:35:23 +00:00
|
|
|
#include "cfg.h"
|
2014-06-05 09:34:29 +00:00
|
|
|
#include "utils.h"
|
|
|
|
|
|
|
|
static const char *log_prefix[] = {
|
|
|
|
"Debug",
|
|
|
|
"Info",
|
|
|
|
"Warning",
|
2014-06-05 09:34:46 +00:00
|
|
|
"Error"
|
2014-06-05 09:34:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
void print(enum log_level lvl, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
struct timespec ts;
|
|
|
|
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
|
|
|
|
|
|
clock_gettime(CLOCK_REALTIME, &ts);
|
|
|
|
|
2014-06-05 09:34:48 +00:00
|
|
|
printf("%17.6f [%-7s] ", ts.tv_sec + ts.tv_nsec / 1e9, log_prefix[lvl]);
|
2014-06-05 09:34:29 +00:00
|
|
|
vprintf(fmt, ap);
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
va_end(ap);
|
2014-06-05 09:34:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int resolve(const char *addr, struct sockaddr_in *sa, int flags)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
char *node;
|
|
|
|
char *service;
|
|
|
|
|
|
|
|
/* Split addr into node:service */
|
|
|
|
if (sscanf(addr, "%m[^:]:%ms", &node, &service) != 2)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
/* Check for wildcards */
|
|
|
|
if (!strcmp(node, "*")) {
|
|
|
|
free(node);
|
|
|
|
node = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcmp(service, "*")) {
|
|
|
|
free(service);
|
|
|
|
service = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get IP */
|
|
|
|
struct addrinfo *result;
|
|
|
|
struct addrinfo hint = {
|
|
|
|
.ai_flags = flags,
|
|
|
|
.ai_family = AF_INET,
|
|
|
|
.ai_socktype = SOCK_DGRAM,
|
|
|
|
.ai_protocol = 0
|
|
|
|
};
|
|
|
|
|
|
|
|
if (getaddrinfo(node, service, &hint, &result))
|
|
|
|
error("Failed to lookup address: %s", gai_strerror(ret));
|
|
|
|
|
|
|
|
memcpy(sa, result->ai_addr, result->ai_addrlen);
|
|
|
|
|
|
|
|
free(node);
|
|
|
|
free(service);
|
|
|
|
freeaddrinfo(result);
|
2014-06-05 09:34:29 +00:00
|
|
|
|
2014-06-05 09:34:56 +00:00
|
|
|
return 0;
|
2014-06-05 09:34:29 +00:00
|
|
|
}
|
2014-06-05 09:35:23 +00:00
|
|
|
|
|
|
|
void realtime_init(struct config *g)
|
|
|
|
{
|
|
|
|
/* Prefault stack */
|
|
|
|
char dummy[MAX_SAFE_STACK];
|
|
|
|
memset(dummy, 0, MAX_SAFE_STACK);
|
2014-06-05 09:35:25 +00:00
|
|
|
debug(3, "Prefaulted stack");
|
2014-06-05 09:35:23 +00:00
|
|
|
|
|
|
|
/* Lock memory */
|
|
|
|
if(mlockall(MCL_CURRENT | MCL_FUTURE))
|
|
|
|
perror("Failed mlockall");
|
|
|
|
else
|
|
|
|
debug(3, "Locked memory");
|
|
|
|
|
|
|
|
/* Check for realtime kernel patch */
|
|
|
|
struct stat st;
|
|
|
|
if (stat("/sys/kernel/realtime", &st))
|
2014-06-05 09:35:25 +00:00
|
|
|
warn("This is not a a realtime patched kernel!");
|
2014-06-05 09:35:23 +00:00
|
|
|
else
|
|
|
|
debug(3 ,"This is a realtime patched kernel");
|
|
|
|
|
|
|
|
/* Use FIFO scheduler with realtime priority */
|
|
|
|
struct sched_param param;
|
|
|
|
param.sched_priority = g->priority;
|
|
|
|
if (sched_setscheduler(0, SCHED_FIFO, ¶m))
|
|
|
|
perror("Failed to set realtime priority");
|
|
|
|
else
|
|
|
|
debug(3, "Set task priority to %u", g->priority);
|
|
|
|
|
|
|
|
/* Pin threads to CPUs by setting the affinity */
|
|
|
|
size_t cset = g->affinity;
|
|
|
|
pid_t pid = getpid();
|
|
|
|
if (sched_setaffinity(pid, sizeof(cset), (const struct cpu_set_t *) &cset))
|
|
|
|
perror("Failed to set CPU affinity");
|
|
|
|
else
|
|
|
|
debug(3, "Set affinity to %#x", g->affinity);
|
|
|
|
}
|