80 lines
2.6 KiB
Diff
80 lines
2.6 KiB
Diff
commit b4c146daa086436807abcd75157bd9d0a44971cb
|
|
Author: Miroslav Lichvar <mlichvar@redhat.com>
|
|
Date: Thu Aug 28 15:14:01 2025 +0200
|
|
|
|
ts2phc: Better handle missing pulses with multiple sinks.
|
|
|
|
The ts2phc_pps_sink_poll() function waits until it has collected pulses
|
|
for all active sinks, or a timeout of 2 seconds between events is
|
|
reached.
|
|
|
|
If a sink missed a pulse (e.g. after a port state change and switching
|
|
PPS signal direction in the external PPS mode) and the next pulse of
|
|
that sink came before pulses of the other sinks, it was mixed with
|
|
events of the previous pulse and the measured offset had an error of
|
|
1/rate seconds.
|
|
|
|
To avoid mixing events corresponding to different pulses, adjust the
|
|
poll() timeout so that it waits only up to a third of the pulse period
|
|
after the first received event.
|
|
|
|
(Rebased to 4.4)
|
|
|
|
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
|
|
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
|
|
|
|
diff --git a/ts2phc_pps_sink.c b/ts2phc_pps_sink.c
|
|
index 9076de9..72d8ea4 100644
|
|
--- a/ts2phc_pps_sink.c
|
|
+++ b/ts2phc_pps_sink.c
|
|
@@ -381,10 +381,11 @@ void ts2phc_pps_sink_cleanup(struct ts2phc_private *priv)
|
|
int ts2phc_pps_sink_poll(struct ts2phc_private *priv)
|
|
{
|
|
struct ts2phc_sink_array *polling_array = priv->polling_array;
|
|
+ bool first_poll = true, ignore_any = false;
|
|
bool all_sinks_have_events = false;
|
|
- bool ignore_any = false;
|
|
+ struct timespec first_ts = {0}, ts;
|
|
+ int cnt, timeout;
|
|
unsigned int i;
|
|
- int cnt;
|
|
|
|
for (i = 0; i < priv->n_sinks; i++)
|
|
polling_array->collected_events[i] = 0;
|
|
@@ -395,7 +396,22 @@ int ts2phc_pps_sink_poll(struct ts2phc_private *priv)
|
|
if (!is_running())
|
|
return 0;
|
|
|
|
- cnt = poll(polling_array->pfd, priv->n_sinks, 2000);
|
|
+ /*
|
|
+ * Collect only events within a third of the pulse period to
|
|
+ * avoid mixing events corresponding to different pulses.
|
|
+ */
|
|
+ if (first_poll) {
|
|
+ timeout = 2000;
|
|
+ } else {
|
|
+ clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
+ timeout = 333;
|
|
+ timeout -= (ts.tv_sec - first_ts.tv_sec) * 1000 +
|
|
+ (ts.tv_nsec - first_ts.tv_nsec) / 1000000;
|
|
+ if (timeout < 0)
|
|
+ timeout = 0;
|
|
+ }
|
|
+
|
|
+ cnt = poll(polling_array->pfd, priv->n_sinks, timeout);
|
|
if (cnt < 0) {
|
|
if (errno == EINTR) {
|
|
return 0;
|
|
@@ -408,6 +424,11 @@ int ts2phc_pps_sink_poll(struct ts2phc_private *priv)
|
|
return 0;
|
|
}
|
|
|
|
+ if (first_poll) {
|
|
+ clock_gettime(CLOCK_MONOTONIC, &first_ts);
|
|
+ first_poll = false;
|
|
+ }
|
|
+
|
|
for (i = 0; i < priv->n_sinks; i++) {
|
|
if (polling_array->pfd[i].revents & POLLERR) {
|
|
sink = polling_array->sink[i];
|