Add modular filter interface.
Similarly to the servo interface, allow multiple filters to be used for delay filtering. Convert mave to the new interface. Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
This commit is contained in:
		
							parent
							
								
									7bd59737d3
								
							
						
					
					
						commit
						2c9718f3c2
					
				
							
								
								
									
										16
									
								
								clock.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								clock.c
									
									
									
									
									
								
							@ -27,7 +27,7 @@
 | 
			
		||||
#include "clockadj.h"
 | 
			
		||||
#include "clockcheck.h"
 | 
			
		||||
#include "foreign.h"
 | 
			
		||||
#include "mave.h"
 | 
			
		||||
#include "filter.h"
 | 
			
		||||
#include "missing.h"
 | 
			
		||||
#include "msg.h"
 | 
			
		||||
#include "phc.h"
 | 
			
		||||
@ -86,7 +86,7 @@ struct clock {
 | 
			
		||||
	enum servo_state servo_state;
 | 
			
		||||
	tmv_t master_offset;
 | 
			
		||||
	tmv_t path_delay;
 | 
			
		||||
	struct mave *avg_delay;
 | 
			
		||||
	struct filter *delay_filter;
 | 
			
		||||
	struct freq_estimator fest;
 | 
			
		||||
	struct time_status_np status;
 | 
			
		||||
	double nrr;
 | 
			
		||||
@ -121,7 +121,7 @@ void clock_destroy(struct clock *c)
 | 
			
		||||
		phc_close(c->clkid);
 | 
			
		||||
	}
 | 
			
		||||
	servo_destroy(c->servo);
 | 
			
		||||
	mave_destroy(c->avg_delay);
 | 
			
		||||
	filter_destroy(c->delay_filter);
 | 
			
		||||
	stats_destroy(c->stats.offset);
 | 
			
		||||
	stats_destroy(c->stats.freq);
 | 
			
		||||
	stats_destroy(c->stats.delay);
 | 
			
		||||
@ -632,9 +632,9 @@ struct clock *clock_create(int phc_index, struct interface *iface, int count,
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	c->servo_state = SERVO_UNLOCKED;
 | 
			
		||||
	c->avg_delay = mave_create(MAVE_LENGTH);
 | 
			
		||||
	if (!c->avg_delay) {
 | 
			
		||||
		pr_err("Failed to create moving average");
 | 
			
		||||
	c->delay_filter = filter_create(FILTER_MOVING_AVERAGE, MAVE_LENGTH);
 | 
			
		||||
	if (!c->delay_filter) {
 | 
			
		||||
		pr_err("Failed to create delay filter");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	c->stats_interval = dds->stats_interval;
 | 
			
		||||
@ -992,7 +992,7 @@ void clock_path_delay(struct clock *c, struct timespec req, struct timestamp rx,
 | 
			
		||||
		pr_warning("c3 %10lld", c3);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c->path_delay = mave_accumulate(c->avg_delay, pd);
 | 
			
		||||
	c->path_delay = filter_sample(c->delay_filter, pd);
 | 
			
		||||
 | 
			
		||||
	c->cur.meanPathDelay = tmv_to_TimeInterval(c->path_delay);
 | 
			
		||||
 | 
			
		||||
@ -1170,7 +1170,7 @@ static void handle_state_decision_event(struct clock *c)
 | 
			
		||||
 | 
			
		||||
	if (!cid_eq(&best_id, &c->best_id)) {
 | 
			
		||||
		clock_freq_est_reset(c);
 | 
			
		||||
		mave_reset(c->avg_delay);
 | 
			
		||||
		filter_reset(c->delay_filter);
 | 
			
		||||
		c->t1 = tmv_zero();
 | 
			
		||||
		c->t2 = tmv_zero();
 | 
			
		||||
		c->path_delay = 0;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										46
									
								
								filter.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								filter.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,46 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @file filter.c
 | 
			
		||||
 * @note Copyright (C) 2013 Miroslav Lichvar <mlichvar@redhat.com>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License along
 | 
			
		||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "filter_private.h"
 | 
			
		||||
#include "mave.h"
 | 
			
		||||
 | 
			
		||||
struct filter *filter_create(enum filter_type type, int length)
 | 
			
		||||
{
 | 
			
		||||
	switch (type) {
 | 
			
		||||
	case FILTER_MOVING_AVERAGE:
 | 
			
		||||
		return mave_create(length);
 | 
			
		||||
	default:
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void filter_destroy(struct filter *filter)
 | 
			
		||||
{
 | 
			
		||||
	filter->destroy(filter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
tmv_t filter_sample(struct filter *filter, tmv_t sample)
 | 
			
		||||
{
 | 
			
		||||
	return filter->sample(filter, sample);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void filter_reset(struct filter *filter)
 | 
			
		||||
{
 | 
			
		||||
	filter->reset(filter);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										63
									
								
								filter.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								filter.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,63 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @file filter.h
 | 
			
		||||
 * @brief Implements a generic filter interface.
 | 
			
		||||
 * @note Copyright (C) 2013 Miroslav Lichvar <mlichvar@redhat.com>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License along
 | 
			
		||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef HAVE_FILTER_H
 | 
			
		||||
#define HAVE_FILTER_H
 | 
			
		||||
 | 
			
		||||
#include "tmv.h"
 | 
			
		||||
 | 
			
		||||
/** Opaque type */
 | 
			
		||||
struct filter;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Defines the available filters.
 | 
			
		||||
 */
 | 
			
		||||
enum filter_type {
 | 
			
		||||
	FILTER_MOVING_AVERAGE,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a new instance of a filter.
 | 
			
		||||
 * @param type    The type of the filter to create.
 | 
			
		||||
 * @param length  The filter's length.
 | 
			
		||||
 * @return A pointer to a new filter on success, NULL otherwise.
 | 
			
		||||
 */
 | 
			
		||||
struct filter *filter_create(enum filter_type type, int length);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Destroy an instance of a filter.
 | 
			
		||||
 * @param filter Pointer to a filter obtained via @ref filter_create().
 | 
			
		||||
 */
 | 
			
		||||
void filter_destroy(struct filter *filter);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Feed a sample into a filter.
 | 
			
		||||
 * @param filter    Pointer to a filter obtained via @ref filter_create().
 | 
			
		||||
 * @param sample    The input sample.
 | 
			
		||||
 * @return The output value.
 | 
			
		||||
 */
 | 
			
		||||
tmv_t filter_sample(struct filter *filter, tmv_t sample);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reset a filter.
 | 
			
		||||
 * @param filter   Pointer to a filter obtained via @ref filter_create().
 | 
			
		||||
 */
 | 
			
		||||
void filter_reset(struct filter *filter);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										33
									
								
								filter_private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								filter_private.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @file filter_private.h
 | 
			
		||||
 * @note Copyright (C) 2013 Miroslav Lichvar <mlichvar@redhat.com>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License along
 | 
			
		||||
 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef HAVE_FILTER_PRIVATE_H
 | 
			
		||||
#define HAVE_FILTER_PRIVATE_H
 | 
			
		||||
 | 
			
		||||
#include "tmv.h"
 | 
			
		||||
#include "contain.h"
 | 
			
		||||
 | 
			
		||||
struct filter {
 | 
			
		||||
	void (*destroy)(struct filter *filter);
 | 
			
		||||
 | 
			
		||||
	tmv_t (*sample)(struct filter *filter, tmv_t sample);
 | 
			
		||||
 | 
			
		||||
	void (*reset)(struct filter *filter);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										5
									
								
								makefile
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								makefile
									
									
									
									
									
								
							@ -24,8 +24,9 @@ CFLAGS	= -Wall $(VER) $(incdefs) $(DEBUG) $(EXTRA_CFLAGS)
 | 
			
		||||
LDLIBS	= -lm -lrt $(EXTRA_LDFLAGS)
 | 
			
		||||
PRG	= ptp4l pmc phc2sys hwstamp_ctl
 | 
			
		||||
OBJ     = bmc.o clock.o clockadj.o clockcheck.o config.o fault.o \
 | 
			
		||||
 fsm.o ptp4l.o mave.o msg.o phc.o pi.o port.o print.o raw.o servo.o \
 | 
			
		||||
 sk.o stats.o tlv.o tmtab.o transport.o udp.o udp6.o uds.o util.o version.o
 | 
			
		||||
 filter.o fsm.o mave.o msg.o phc.o pi.o port.o print.o \
 | 
			
		||||
 ptp4l.o raw.o servo.o sk.o stats.o tlv.o tmtab.o transport.o udp.o \
 | 
			
		||||
 udp6.o uds.o util.o version.o
 | 
			
		||||
 | 
			
		||||
OBJECTS	= $(OBJ) hwstamp_ctl.o phc2sys.o pmc.o pmc_common.o sysoff.o
 | 
			
		||||
SRC	= $(OBJECTS:.o=.c)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										48
									
								
								mave.c
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								mave.c
									
									
									
									
									
								
							@ -20,8 +20,10 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "mave.h"
 | 
			
		||||
#include "filter_private.h"
 | 
			
		||||
 | 
			
		||||
struct mave {
 | 
			
		||||
	struct filter filter;
 | 
			
		||||
	int cnt;
 | 
			
		||||
	int len;
 | 
			
		||||
	int index;
 | 
			
		||||
@ -29,30 +31,17 @@ struct mave {
 | 
			
		||||
	tmv_t *val;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct mave *mave_create(int length)
 | 
			
		||||
{
 | 
			
		||||
	struct mave *m;
 | 
			
		||||
	m = calloc(1, sizeof(*m));
 | 
			
		||||
	if (!m) {
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	m->val = calloc(1, length * sizeof(*m->val));
 | 
			
		||||
	if (!m->val) {
 | 
			
		||||
		free(m);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	m->len = length;
 | 
			
		||||
	return m;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mave_destroy(struct mave *m)
 | 
			
		||||
static void mave_destroy(struct filter *filter)
 | 
			
		||||
{
 | 
			
		||||
	struct mave *m = container_of(filter, struct mave, filter);
 | 
			
		||||
	free(m->val);
 | 
			
		||||
	free(m);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
tmv_t mave_accumulate(struct mave *m, tmv_t val)
 | 
			
		||||
static tmv_t mave_accumulate(struct filter *filter, tmv_t val)
 | 
			
		||||
{
 | 
			
		||||
	struct mave *m = container_of(filter, struct mave, filter);
 | 
			
		||||
 | 
			
		||||
	m->sum = tmv_sub(m->sum, m->val[m->index]);
 | 
			
		||||
	m->val[m->index] = val;
 | 
			
		||||
	m->index = (1 + m->index) % m->len;
 | 
			
		||||
@ -63,10 +52,31 @@ tmv_t mave_accumulate(struct mave *m, tmv_t val)
 | 
			
		||||
	return tmv_div(m->sum, m->cnt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mave_reset(struct mave *m)
 | 
			
		||||
static void mave_reset(struct filter *filter)
 | 
			
		||||
{
 | 
			
		||||
	struct mave *m = container_of(filter, struct mave, filter);
 | 
			
		||||
 | 
			
		||||
	m->cnt = 0;
 | 
			
		||||
	m->index = 0;
 | 
			
		||||
	m->sum = 0;
 | 
			
		||||
	memset(m->val, 0, m->len * sizeof(*m->val));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct filter *mave_create(int length)
 | 
			
		||||
{
 | 
			
		||||
	struct mave *m;
 | 
			
		||||
	m = calloc(1, sizeof(*m));
 | 
			
		||||
	if (!m) {
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	m->filter.destroy = mave_destroy;
 | 
			
		||||
	m->filter.sample = mave_accumulate;
 | 
			
		||||
	m->filter.reset = mave_reset;
 | 
			
		||||
	m->val = calloc(1, length * sizeof(*m->val));
 | 
			
		||||
	if (!m->val) {
 | 
			
		||||
		free(m);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	m->len = length;
 | 
			
		||||
	return &m->filter;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								mave.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								mave.h
									
									
									
									
									
								
							@ -20,16 +20,8 @@
 | 
			
		||||
#ifndef HAVE_MAVE_H
 | 
			
		||||
#define HAVE_MAVE_H
 | 
			
		||||
 | 
			
		||||
#include "tmv.h"
 | 
			
		||||
#include "filter.h"
 | 
			
		||||
 | 
			
		||||
struct mave;
 | 
			
		||||
 | 
			
		||||
struct mave *mave_create(int length);
 | 
			
		||||
 | 
			
		||||
void mave_destroy(struct mave *m);
 | 
			
		||||
 | 
			
		||||
tmv_t mave_accumulate(struct mave *m, tmv_t val);
 | 
			
		||||
 | 
			
		||||
void mave_reset(struct mave *m);
 | 
			
		||||
struct filter *mave_create(int length);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										14
									
								
								port.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								port.c
									
									
									
									
									
								
							@ -25,7 +25,7 @@
 | 
			
		||||
 | 
			
		||||
#include "bmc.h"
 | 
			
		||||
#include "clock.h"
 | 
			
		||||
#include "mave.h"
 | 
			
		||||
#include "filter.h"
 | 
			
		||||
#include "missing.h"
 | 
			
		||||
#include "msg.h"
 | 
			
		||||
#include "port.h"
 | 
			
		||||
@ -82,7 +82,7 @@ struct port {
 | 
			
		||||
	} seqnum;
 | 
			
		||||
	struct tmtab tmtab;
 | 
			
		||||
	tmv_t peer_delay;
 | 
			
		||||
	struct mave *avg_delay;
 | 
			
		||||
	struct filter *delay_filter;
 | 
			
		||||
	int log_sync_interval;
 | 
			
		||||
	struct nrate_estimator nrate;
 | 
			
		||||
	unsigned int pdr_missing;
 | 
			
		||||
@ -1716,7 +1716,7 @@ calc:
 | 
			
		||||
	pd = tmv_sub(pd, c2);
 | 
			
		||||
	pd = tmv_div(pd, 2);
 | 
			
		||||
 | 
			
		||||
	p->peer_delay = mave_accumulate(p->avg_delay, pd);
 | 
			
		||||
	p->peer_delay = filter_sample(p->delay_filter, pd);
 | 
			
		||||
 | 
			
		||||
	p->peerMeanPathDelay = tmv_to_TimeInterval(p->peer_delay);
 | 
			
		||||
 | 
			
		||||
@ -1845,7 +1845,7 @@ void port_close(struct port *p)
 | 
			
		||||
		port_disable(p);
 | 
			
		||||
	}
 | 
			
		||||
	transport_destroy(p->trp);
 | 
			
		||||
	mave_destroy(p->avg_delay);
 | 
			
		||||
	filter_destroy(p->delay_filter);
 | 
			
		||||
	free(p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2306,9 +2306,9 @@ struct port *port_open(int phc_index,
 | 
			
		||||
	p->delayMechanism = interface->dm;
 | 
			
		||||
	p->versionNumber = PTP_VERSION;
 | 
			
		||||
 | 
			
		||||
	p->avg_delay = mave_create(PORT_MAVE_LENGTH);
 | 
			
		||||
	if (!p->avg_delay) {
 | 
			
		||||
		pr_err("Failed to create moving average");
 | 
			
		||||
	p->delay_filter = filter_create(FILTER_MOVING_AVERAGE, PORT_MAVE_LENGTH);
 | 
			
		||||
	if (!p->delay_filter) {
 | 
			
		||||
		pr_err("Failed to create delay filter");
 | 
			
		||||
		transport_destroy(p->trp);
 | 
			
		||||
		free(p);
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user