Commit dadd7e7b authored by Joanne Hugé's avatar Joanne Hugé

Remove ptptime program

parent 3ac9a1a7
PROG = ptptime
SRCDIR = ../src
SRCS = main.c
OBJS = $(SRCS:%.c=%.o)
ifeq ($(DEBUG),)
CFLAGS = -O2
else
CFLAGS = -Og -g -Wall -Wextra
endif
CFLAGS += -MD -MP
CFLAGS += -I $(SRCDIR)
CFLAGS += -std=gnu99
LLIBS = -pthread
vpath %.c $(SRCDIR)
$(PROG): $(OBJS)
$(CC) $(LDFLAGS) $(LDIRS) $^ $(LLIBS) -o $@
-include $(subst .c,.d,$(SRCS))
clean:
$(RM) $(OBJS) $(PROG) $(subst .c,.d,$(SRCS))
.PHONY: clean
/*
* Get PTP time
*
* Large portions taken from cyclictest
*
*/
#define _GNU_SOURCE
#include <errno.h>
#include <error.h>
#include <inttypes.h>
#include <limits.h>
#include <pthread.h>
#include <sched.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <time.h>
#include <unistd.h>
#define NSEC_PER_SEC UINT64_C(1000000000)
// Structs
typedef struct thread_param {
int interval;
int priority;
} thread_param_t;
// Static functions
static void process_options(int argc, char *argv[]);
static void add_ns(struct timespec *t, uint64_t ns);
static uint64_t ts_to_uint(struct timespec t);
// Static variables
static thread_param_t thread_params;
static uint64_t ptptime;
static void help(char *argv[]) {
printf(
"Usage: %s [-h] [-i USEC]\n"
" -h Show help\n"
" -i USEC Wake up the real time thread every "
"USEC "
"microseconds (Default: 10ms)\n"
"\n",
argv[0]);
}
/*
* Real-time thread: Sends packets at a regular intervall
*/
static void *packet_sending_thread(void *p) {
(void)p;
struct timespec next, ptptime_ts;
cpu_set_t mask;
// Set thread CPU affinity
CPU_ZERO(&mask);
CPU_SET(1, &mask);
if (sched_setaffinity(0, sizeof(mask), &mask))
error(EXIT_FAILURE, errno,
"Could not set CPU affinity to CPU #1\n");
clock_gettime(CLOCK_MONOTONIC, &next);
// Packet sending loop
for (;;) {
clock_gettime(CLOCK_REALTIME, &ptptime_ts);
ptptime = ts_to_uint(ptptime_ts);
add_ns(&next, thread_params.interval);
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL);
}
return NULL;
}
/*
* Main thread, has non-real time priority
* Handles the IO and creates the real time thread
*/
int main(int argc, char *argv[]) {
pthread_t thread;
struct sched_param param;
pthread_attr_t attr;
// Default configuration values
thread_params.interval = 100000 * 1000;
thread_params.priority = 99;
/* Lock all current and future pages from preventing of being paged to
* swap */
if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
perror("mlockall failed");
/* exit(-1) or do error handling */
}
// Process bash options
process_options(argc, argv);
/* Initialize pthread attributes (default values) */
if (pthread_attr_init(&attr)) {
fprintf(stderr, "init pthread attributes failed\n");
exit(EXIT_FAILURE);
}
/* Set a specific stack size */
if (pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN)) {
fprintf(stderr, "pthread setstacksize failed\n");
exit(EXIT_FAILURE);
}
/* Set scheduler policy and priority of pthread */
if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) {
fprintf(stderr, "pthread setschedpolicy failed\n");
exit(EXIT_FAILURE);
}
param.sched_priority = thread_params.priority;
if (pthread_attr_setschedparam(&attr, &param)) {
fprintf(stderr, "pthread setschedparam failed\n");
exit(EXIT_FAILURE);
}
/* Use scheduling parameters of attr */
if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)) {
fprintf(stderr, "pthread setinheritsched failed\n");
exit(EXIT_FAILURE);
}
// Create the real time thread
if (pthread_create(&thread, &attr, packet_sending_thread, NULL))
error(EXIT_FAILURE, errno,
"Couldn't create packet sending thread");
// Verbose loop
for (;;) {
usleep(1000);
printf("%9" PRIu64 ": \n", ptptime);
printf("\033[%dA", 1);
}
exit(EXIT_SUCCESS);
}
// Process bash options
static void process_options(int argc, char *argv[]) {
int network_if_specified = 0;
for (;;) {
int c = getopt(argc, argv, "hi:");
if (c == -1) break;
switch (c) {
case 'h':
help(argv);
exit(EXIT_SUCCESS);
break;
case 'i':
thread_params.interval = atoi(optarg) * 1000;
break;
}
}
}
static void add_ns(struct timespec *t, uint64_t ns) {
t->tv_nsec += ns;
while ((unsigned int)t->tv_nsec >= NSEC_PER_SEC) {
t->tv_sec += 1;
t->tv_nsec -= NSEC_PER_SEC;
}
}
static uint64_t ts_to_uint(struct timespec t) {
return t.tv_sec * NSEC_PER_SEC + t.tv_nsec;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment