/** * Some helper functions * * @author Steffen Vogel * @copyright 2014, Institute for Automation of Complex Power Systems, EONERC */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "cfg.h" #include "utils.h" static const char *log_prefix[] = { "Debug", "Info", "Warning", "Error" }; void print(enum log_level lvl, const char *fmt, ...) { struct timespec ts; va_list ap; va_start(ap, fmt); clock_gettime(CLOCK_REALTIME, &ts); printf("%17.6f [%-7s] ", ts.tv_sec + ts.tv_nsec / 1e9, log_prefix[lvl]); vprintf(fmt, ap); printf("\n"); va_end(ap); } 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); return 0; } void realtime_init(struct config *g) { /* Prefault stack */ char dummy[MAX_SAFE_STACK]; memset(dummy, 0, MAX_SAFE_STACK); debug(3, "Prefaulted 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, ¶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); }