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

added realtime initialization

git-svn-id: https://zerberus.eonerc.rwth-aachen.de:8443/svn/s2ss/trunk@48 8ec27952-4edc-4aab-86aa-e87bb2611832
This commit is contained in:
Steffen Vogel 2014-06-05 09:35:23 +00:00
parent e5cdf0757d
commit 207d904054
9 changed files with 73 additions and 66 deletions

View file

@ -12,7 +12,7 @@ GIT_REV = $(shell git rev-parse --short HEAD)
V ?= 4
LDFLAGS = -pthread -lrt -lm -lconfig -lnl-3 -lnl-route-3
CFLAGS = -g -std=c99 -Iinclude/ -D_XOPEN_SOURCE=500 -DV=$(V)
CFLAGS = -g -std=c99 -Iinclude/ -D_XOPEN_SOURCE=500 -D_GNU_SOURCE -DV=$(V)
CFLAGS += -D__GIT_REV__='"$(GIT_REV)"' -D__GIT_TAG__='"$(GIT_TAG)"'
.PHONY: all clean doc

1
Readme
View file

@ -27,6 +27,7 @@ Contacts:
- CAP_NET_ADMIN to increase the socket priority
- CAP_SYS_NICE to set the realtime priority and cpu affinity
- CAP_IPC_LOC to lock pages for better realtime
3. Examples
--------------------------------------------------------------------------------

View file

@ -2,11 +2,8 @@
name = "s2ss"; # The name of this node
# TODO: this has to be implmented
# debug = 10; # The debugging level (0 - 10)
# affinity = 0xC0; # Mask of cores the server should run on
# nice = -20; # Scheduler priority for the server
# protocol = 0; # Protocol version for UDP message format
affinity = 0x02; # Mask of cores the server should run on
priority = 50; # Scheduler priority for the server
nodes = {
acs = {

View file

@ -10,8 +10,8 @@
#include <libconfig.h>
#include "path.h"
#include "node.h"
struct node;
struct path;
struct config {
/// Name of this node
@ -21,7 +21,7 @@ struct config {
/// Verbosity level
int debug;
/// Task priority (lower is better)
int nice;
int priority;
/// Core affinity of this task
int affinity;
/// Protocol version of UDP packages

View file

@ -13,7 +13,8 @@
#include <errno.h>
#include <string.h>
#include <netinet/ip.h>
struct config;
struct sockaddr_in;
enum log_level
{
@ -41,6 +42,18 @@ void print(enum log_level lvl, const char *fmt, ...);
*/
int resolve(const char *addr, struct sockaddr_in *sa, int flags);
/**
* @brief Setup various realtime realated things
*
* - Prefault the stack
* - Lock memory
* - Use FIFO scheduler with realtime priority
* - Set CPU affinity
*
* @param g The global configuration
*/
void realtime_init(struct config *g);
/// Check assertion and exit if failed
#define assert(exp) do { \
if (!(exp)) { \

View file

@ -11,6 +11,8 @@
#include <stdlib.h>
#include "cfg.h"
#include "node.h"
#include "path.h"
#include "utils.h"
int config_parse(config_t *cfg, struct config *g)
@ -71,7 +73,7 @@ int config_parse_global(config_setting_t *c, struct config *g)
config_setting_lookup_int(c, "debug", &g->debug);
config_setting_lookup_int(c, "affinity", &g->affinity);
config_setting_lookup_int(c, "nice", &g->nice);
config_setting_lookup_int(c, "priority", &g->priority);
config_setting_lookup_int(c, "protocol", &g->protocol);
return CONFIG_TRUE;
@ -96,8 +98,6 @@ int config_parse_path(config_setting_t *c, struct config *g)
if (!config_setting_lookup_string(c, "out", &out_str))
cerror(c, "Missing output node for path");
if (!config_setting_lookup_int)
info("Loading path from '%s' to '%s'", in_str, out_str);
in = node_lookup_name(in_str, g->nodes, g->node_count);

View file

@ -1,50 +0,0 @@
/**
* Realtime related functions
*
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014, Institute for Automation of Complex Power Systems, EONERC
*/
#include <string.h>
#include <sched.h>
#include "config.h"
#include "utils.h"
void rt_stack_prefault()
{
unsigned char dummy[MAX_SAFE_STACK];
memset(dummy, 0, MAX_SAFE_STACK);
}
void rt_set_priority()
{
struct sched_param param;
param.sched_priority = PRIORITY;
if (sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
perror("sched_setscheduler failed");
exit(-1);
}
}
void rt_lock_memory()
{
// TODO
}
void rt_set_affinity()
{
// TODO
}
void rt_init()
{
rt_set_priority();
rt_set_affinity();
rt_lock_memory();
rt_stack_prefault();
}

View file

@ -90,16 +90,19 @@ int main(int argc, char *argv[])
info("This is s2ss %s", VERSION);
// Default settings
/* Default settings */
config.filename = argv[1];
config.debug = 0;
config.nice = 0;
config.priority = 0;
config.affinity = 0xC0;
config.protocol = 0;
config_init(&config.obj);
config_parse(&config.obj, &config);
/* Setup various realtime related things */
realtime_init(&config);
if (config.path_count)
info("Parsed %u nodes and %u paths", config.node_count, config.path_count);
else

View file

@ -10,12 +10,19 @@
#include <string.h>
#include <time.h>
#include <errno.h>
#include <sched.h>
#include <unistd.h>
#include <netdb.h>
#include <sched.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "config.h"
#include "cfg.h"
#include "utils.h"
static const char *log_prefix[] = {
@ -82,3 +89,39 @@ int resolve(const char *addr, struct sockaddr_in *sa, int flags)
return 0;
}
void realtime_init(struct config *g)
{
/* Prefault stack */
char dummy[MAX_SAFE_STACK];
memset(dummy, 0, MAX_SAFE_STACK);
/* 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))
warn("This is not a a realtime patched kernel");
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, &param))
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);
}