Implement the port master qualification timer.

Signed-off-by: Richard Cochran <richardcochran@gmail.com>
master
Richard Cochran 2011-12-27 11:54:08 +01:00
parent 62afef45db
commit da17f75359
2 changed files with 29 additions and 1 deletions

1
fd.h
View File

@ -25,6 +25,7 @@ enum {
FD_GENERAL, FD_GENERAL,
FD_ANNOUNCE_TIMER, FD_ANNOUNCE_TIMER,
FD_DELAY_TIMER, FD_DELAY_TIMER,
FD_QUALIFICATION_TIMER,
N_POLLFD, N_POLLFD,
}; };

29
port.c
View File

@ -240,6 +240,18 @@ static int port_set_delay_tmo(struct port *p)
return timerfd_settime(p->fda.fd[FD_DELAY_TIMER], 0, &tmo, NULL); return timerfd_settime(p->fda.fd[FD_DELAY_TIMER], 0, &tmo, NULL);
} }
static int port_set_qualification_tmo(struct port *p)
{
struct itimerspec tmo = {
{0, 0}, {0, 0}
};
tmo.it_value.tv_sec = (1 + clock_steps_removed(p->clock)) *
(1 << p->logAnnounceInterval);
return timerfd_settime(p->fda.fd[FD_QUALIFICATION_TIMER], 0, &tmo, NULL);
}
static void port_synchronize(struct port *p, static void port_synchronize(struct port *p,
struct timespec ingress_ts, struct timespec ingress_ts,
struct timestamp origin_ts, struct timestamp origin_ts,
@ -301,7 +313,7 @@ out:
static int port_initialize(struct port *p) static int port_initialize(struct port *p)
{ {
int fd1, fd2; int fd1, fd2, fd3;
p->logMinDelayReqInterval = LOG_MIN_DELAY_REQ_INTERVAL; p->logMinDelayReqInterval = LOG_MIN_DELAY_REQ_INTERVAL;
p->peerMeanPathDelay = 0; p->peerMeanPathDelay = 0;
@ -322,6 +334,11 @@ static int port_initialize(struct port *p)
pr_err("timerfd_create: %s", strerror(errno)); pr_err("timerfd_create: %s", strerror(errno));
goto no_timer2; goto no_timer2;
} }
fd3 = timerfd_create(CLOCK_MONOTONIC, 0);
if (fd3 < 0) {
pr_err("timerfd_create: %s", strerror(errno));
goto no_timer3;
}
if (p->transport->open(p->name, &p->fda, p->timestamping)) if (p->transport->open(p->name, &p->fda, p->timestamping))
goto no_tropen; goto no_tropen;
@ -329,6 +346,8 @@ static int port_initialize(struct port *p)
p->fda.cnt++; p->fda.cnt++;
p->fda.fd[FD_DELAY_TIMER] = fd2; p->fda.fd[FD_DELAY_TIMER] = fd2;
p->fda.cnt++; p->fda.cnt++;
p->fda.fd[FD_QUALIFICATION_TIMER] = fd3;
p->fda.cnt++;
if (port_set_announce_tmo(p)) if (port_set_announce_tmo(p))
goto no_tmo; goto no_tmo;
@ -339,6 +358,7 @@ static int port_initialize(struct port *p)
no_tmo: no_tmo:
p->transport->close(&p->fda); p->transport->close(&p->fda);
no_tropen: no_tropen:
no_timer3:
close(fd2); close(fd2);
no_timer2: no_timer2:
close(fd1); close(fd1);
@ -574,6 +594,7 @@ void port_close(struct port *p)
p->transport->close(&p->fda); p->transport->close(&p->fda);
close(p->fda.fd[FD_ANNOUNCE_TIMER]); close(p->fda.fd[FD_ANNOUNCE_TIMER]);
close(p->fda.fd[FD_DELAY_TIMER]); close(p->fda.fd[FD_DELAY_TIMER]);
close(p->fda.fd[FD_QUALIFICATION_TIMER]);
free(p); free(p);
} }
@ -641,6 +662,8 @@ void port_dispatch(struct port *p, enum fsm_event event)
port_set_announce_tmo(p); port_set_announce_tmo(p);
break; break;
case PS_PRE_MASTER: case PS_PRE_MASTER:
port_set_qualification_tmo(p);
break;
case PS_MASTER: case PS_MASTER:
case PS_GRAND_MASTER: case PS_GRAND_MASTER:
break; break;
@ -674,6 +697,10 @@ enum fsm_event port_event(struct port *p, int fd_index)
pr_debug("port %hu: delay timeout", portnum(p)); pr_debug("port %hu: delay timeout", portnum(p));
port_set_delay_tmo(p); port_set_delay_tmo(p);
return port_delay_request(p) ? EV_FAULT_DETECTED : EV_NONE; return port_delay_request(p) ? EV_FAULT_DETECTED : EV_NONE;
case FD_QUALIFICATION_TIMER:
pr_debug("port %hu: qualification timeout", portnum(p));
return EV_QUALIFICATION_TIMEOUT_EXPIRES;
} }
msg = msg_allocate(); msg = msg_allocate();