Commit 7837d938 authored by Alessandro Rubini's avatar Alessandro Rubini

general: time operations are now per-instance

This commit moves the time operations inside the instance.  It
allows to have different time operations for each instance, which will be
useful in the future. For example, one ethernet card may White Rabbit,
and another may not be.

This commit, like moving network operations inside ppi, requires a
change in wrpc-sw.
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent 4a512fd8
/*
* Alessandro Rubini for CERN, 2013 -- LGPL 2.1 or later
*/
#include <ppsi/ppsi.h>
#include <ppsi/diag.h>
#include "bare-i386.h"
static int bare_time_get(TimeInternal *t)
{
struct bare_timeval tv;
if (sys_gettimeofday(&tv, NULL) < 0) {
PP_PRINTF("gettimeofday error");
sys_exit(1);
}
t->seconds = tv.tv_sec;
t->nanoseconds = tv.tv_usec * 1000;
if (pp_verbose_time && !(pp_global_flags & PP_FLAG_NOTIMELOG))
pp_printf("%s: %9li.%06li\n", __func__, tv.tv_sec, tv.tv_usec);
return 0;
}
static int bare_time_set(TimeInternal *t)
{
struct bare_timeval tv;
tv.tv_sec = t->seconds;
tv.tv_usec = t->nanoseconds / 1000;
if (sys_settimeofday(&tv, NULL) < 0) {
PP_PRINTF("settimeofday error");
sys_exit(1);
}
if (pp_verbose_time)
pp_printf("%s: %9li.%06li\n", __func__, tv.tv_sec, tv.tv_usec);
return 0;
}
static int bare_time_adjust(long offset_ns, long freq_ppm)
{
struct bare_timex t;
int ret;
if (freq_ppm > PP_ADJ_FREQ_MAX)
freq_ppm = PP_ADJ_FREQ_MAX;
if (freq_ppm < -PP_ADJ_FREQ_MAX)
freq_ppm = -PP_ADJ_FREQ_MAX;
t.offset = offset_ns / 1000;
t.freq = freq_ppm; /* was: "adj * ((1 << 16) / 1000)" */
t.modes = MOD_FREQUENCY | MOD_OFFSET;
ret = sys_adjtimex(&t);
if (pp_verbose_time)
pp_printf("%s: %li %li\n", __func__, offset_ns, freq_ppm);
return ret;
}
static unsigned long bare_calc_timeout(int millisec)
{
struct bare_timespec now;
uint64_t now_ms;
unsigned long result;
if (!millisec)
millisec = 1;
sys_clock_gettime(CLOCK_MONOTONIC, &now);
now_ms = 1000LL * now.tv_sec + now.tv_nsec / 1000 / 1000;
result = now_ms + millisec;
return result ? result : 1; /* cannot return 0 */
}
struct pp_time_operations bare_time_ops = {
.get = bare_time_get,
.set = bare_time_set,
.adjust = bare_time_adjust,
.calc_timeout = bare_calc_timeout,
};
......@@ -21,7 +21,8 @@
#include "posix.h"
/* posix_recv_msg uses recvmsg for timestamp query */
static int posix_recv_msg(int fd, void *pkt, int len, TimeInternal *t)
static int posix_recv_msg(struct pp_instance *ppi, int fd, void *pkt, int len,
TimeInternal *t)
{
ssize_t ret;
struct msghdr msg;
......@@ -84,7 +85,7 @@ static int posix_recv_msg(int fd, void *pkt, int len, TimeInternal *t)
* spike in the offset signal sent to the clock servo
*/
PP_VPRINTF("no receive time stamp, getting it in user space\n");
pp_t_ops.get(t);
ppi->t_ops->get(t);
}
return ret;
}
......@@ -98,8 +99,10 @@ static int posix_net_recv(struct pp_instance *ppi, void *pkt, int len,
int ret;
if (OPTS(ppi)->ethernet_mode) {
int fd = NP(ppi)->ch[PP_NP_GEN].fd;
hdr = PROTO_HDR(pkt);
ret = posix_recv_msg(NP(ppi)->ch[PP_NP_GEN].fd, hdr,
ret = posix_recv_msg(ppi, fd, hdr,
len + NP(ppi)->proto_ofst, t);
return ret <= 0 ? ret : ret - NP(ppi)->proto_ofst;
/* FIXME: check header */
......@@ -117,10 +120,10 @@ static int posix_net_recv(struct pp_instance *ppi, void *pkt, int len,
POSIX_ARCH(ppi)->rcv_switch = !POSIX_ARCH(ppi)->rcv_switch;
if (ch1->pkt_present)
return posix_recv_msg(ch1->fd, pkt, len, t);
return posix_recv_msg(ppi, ch1->fd, pkt, len, t);
if (ch2->pkt_present)
return posix_recv_msg(ch2->fd, pkt, len, t);
return posix_recv_msg(ppi, ch2->fd, pkt, len, t);
return -1;
}
......@@ -150,7 +153,7 @@ static int posix_net_send(struct pp_instance *ppi, void *pkt, int len,
addr.sin_addr.s_addr = NP(ppi)->mcast_addr;
if (t)
pp_t_ops.get(t);
ppi->t_ops->get(t);
return sendto(NP(ppi)->ch[chtype].fd, pkt, len, 0,
(struct sockaddr *)&addr, sizeof(struct sockaddr_in));
......
......@@ -47,6 +47,7 @@ int main(int argc, char **argv)
ppi->arch_data = calloc(1, sizeof(struct posix_arch_data));
ppi->n_ops = &posix_net_ops;
ppi->t_ops = &posix_time_ops;
if ((!ppi->defaultDS) || (!ppi->currentDS) || (!ppi->parentDS)
|| (!ppi->portDS) || (!ppi->timePropertiesDS)
......
......@@ -77,7 +77,7 @@ static unsigned long posix_calc_timeout(int millisec)
return result ? result : 1; /* cannot return 0 */
}
struct pp_time_operations pp_t_ops = {
struct pp_time_operations posix_time_ops = {
.get = posix_time_get,
.set = posix_time_set,
.adjust = posix_time_adjust,
......
......@@ -17,3 +17,4 @@ extern int posix_net_check_pkt(struct pp_instance *ppi, int delay_ms);
extern void posix_main_loop(struct pp_instance *ppi);
extern struct pp_network_operations posix_net_ops;
extern struct pp_time_operations posix_time_ops;
......@@ -66,7 +66,7 @@ void pp_timed_printf(struct pp_instance *ppi, char *fmt, ...)
/* temporarily set NOTIMELOG, as we'll print the time ourselves */
pp_global_flags |= PP_FLAG_NOTIMELOG;
pp_t_ops.get(&t);
ppi->t_ops->get(&t);
pp_global_flags = oflags;
pp_printf("%09d.%03d ", (int)t.seconds,
......
......@@ -151,6 +151,7 @@ struct pp_instance {
/* Operations that may be different in each instance */
struct pp_network_operations *n_ops;
struct pp_time_operations *t_ops;
/* Data sets */
DSDefault *defaultDS; /* page 65 */
......@@ -301,8 +302,6 @@ struct pp_time_operations {
/* In geeneral, we can't adjust the rate by more than 200ppm */
#define PP_ADJ_FREQ_MAX (200 << 16)
extern struct pp_time_operations pp_t_ops;
/*
* Timeouts. I renamed from "timer" to "timeout" to avoid
......@@ -315,7 +314,7 @@ extern struct pp_time_operations pp_t_ops;
static inline void pp_timeout_set(struct pp_instance *ppi, int index,
int millisec)
{
ppi->timeouts[index] = pp_t_ops.calc_timeout(millisec);
ppi->timeouts[index] = ppi->t_ops->calc_timeout(millisec);
}
extern void pp_timeout_rand(struct pp_instance *ppi, int index, int logval);
......@@ -330,7 +329,8 @@ extern void pp_timeout_log(struct pp_instance *ppi, int index);
static inline int pp_timeout(struct pp_instance *ppi, int index)
{
int ret = ppi->timeouts[index] &&
time_after_eq(pp_t_ops.calc_timeout(0), ppi->timeouts[index]);
time_after_eq(ppi->t_ops->calc_timeout(0),
ppi->timeouts[index]);
if (ret && pp_verbose_time)
pp_timeout_log(ppi, index);
......
......@@ -9,6 +9,7 @@
extern void bare_main_loop(struct pp_instance *ppi);
extern struct pp_network_operations bare_net_ops;
extern struct pp_time_operations bare_time_ops;
/* syscalls */
struct bare_sockaddr;
......
......@@ -15,7 +15,7 @@ static int bare_net_recv(struct pp_instance *ppi, void *pkt, int len,
TimeInternal *t)
{
if (t)
pp_t_ops.get(t);
ppi->t_ops->get(t);
return sys_recv(NP(ppi)->ch[PP_NP_GEN].fd,
pkt - NP(ppi)->proto_ofst, len, 0);
......@@ -34,7 +34,7 @@ static int bare_net_send(struct pp_instance *ppi, void *pkt, int len,
memcpy(hdr->h_source, NP(ppi)->ch[PP_NP_GEN].addr, 6);
if (t)
pp_t_ops.get(t);
ppi->t_ops->get(t);
return sys_send(NP(ppi)->ch[chtype].fd, hdr,
len + NP(ppi)->proto_ofst, 0);
......
......@@ -49,6 +49,7 @@ int ppsi_main(int argc, char **argv)
ppi->frgn_master = &frgn_master;
ppi->arch_data = NULL;
ppi->n_ops = &bare_net_ops;
ppi->t_ops = &bare_time_ops;
/* This just llocates the stuff */
pp_open_instance(ppi, NULL);
......
......@@ -71,7 +71,7 @@ static unsigned long bare_calc_timeout(int millisec)
return result ? result : 1; /* cannot return 0 */
}
struct pp_time_operations pp_t_ops = {
struct pp_time_operations bare_time_ops = {
.get = bare_time_get,
.set = bare_time_set,
.adjust = bare_time_adjust,
......
......@@ -455,7 +455,7 @@ int msg_issue_sync(struct pp_instance *ppi)
{
Timestamp orig_tstamp;
TimeInternal now;
pp_t_ops.get(&now);
ppi->t_ops->get(&now);
from_TimeInternal(&now, &orig_tstamp);
msg_pack_sync(ppi, &orig_tstamp);
......@@ -480,7 +480,7 @@ int msg_issue_delay_req(struct pp_instance *ppi)
{
Timestamp orig_tstamp;
TimeInternal now;
pp_t_ops.get(&now);
ppi->t_ops->get(&now);
from_TimeInternal(&now, &orig_tstamp);
msg_pack_delay_req(ppi, &orig_tstamp);
......
......@@ -19,7 +19,7 @@ void pp_init_clock(struct pp_instance *ppi)
/* level clock */
if (!OPTS(ppi)->no_adjust)
pp_t_ops.adjust(0, 0);
ppi->t_ops->adjust(0, 0);
}
void pp_update_delay(struct pp_instance *ppi, TimeInternal *correction_field)
......@@ -189,15 +189,15 @@ void pp_update_clock(struct pp_instance *ppi)
if (!OPTS(ppi)->no_adjust) {
if (!OPTS(ppi)->no_rst_clk) {
/* FIXME: use adjust instead of set? */
pp_t_ops.get(&time_tmp);
ppi->t_ops->get(&time_tmp);
sub_TimeInternal(&time_tmp, &time_tmp,
&DSCUR(ppi)->offsetFromMaster);
pp_t_ops.set(&time_tmp);
ppi->t_ops->set(&time_tmp);
pp_init_clock(ppi);
} else {
adj = DSCUR(ppi)->offsetFromMaster.nanoseconds
> 0 ? PP_ADJ_NS_MAX:-PP_ADJ_NS_MAX;
pp_t_ops.adjust(-adj, 0);
ppi->t_ops->adjust(-adj, 0);
}
}
} else {
......@@ -226,7 +226,7 @@ void pp_update_clock(struct pp_instance *ppi)
/* apply controller output as a clock tick rate adjustment */
if (!OPTS(ppi)->no_adjust)
pp_t_ops.adjust(0, -adj);
ppi->t_ops->adjust(0, -adj);
dc++;
if (dc % 2 == 0) { /* Prints statistics every 8s */
......
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