sourcestats: add fixed asymmetry
Rework the code to allow the jitter asymmetry to be specified.
This commit is contained in:
parent
d0964ffa83
commit
b06d74ab73
7 changed files with 59 additions and 32 deletions
|
@ -586,7 +586,7 @@ NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourcePar
|
||||||
SRC_NTP, params->sel_options,
|
SRC_NTP, params->sel_options,
|
||||||
&result->remote_addr.ip_addr,
|
&result->remote_addr.ip_addr,
|
||||||
params->min_samples, params->max_samples,
|
params->min_samples, params->max_samples,
|
||||||
0.0);
|
0.0, 1.0);
|
||||||
|
|
||||||
result->rx_timeout_id = 0;
|
result->rx_timeout_id = 0;
|
||||||
result->tx_timeout_id = 0;
|
result->tx_timeout_id = 0;
|
||||||
|
|
|
@ -260,7 +260,7 @@ RCL_AddRefclock(RefclockParameters *params)
|
||||||
filter_init(&inst->filter, params->filter_length, params->max_dispersion);
|
filter_init(&inst->filter, params->filter_length, params->max_dispersion);
|
||||||
|
|
||||||
inst->source = SRC_CreateNewInstance(inst->ref_id, SRC_REFCLOCK, params->sel_options, NULL,
|
inst->source = SRC_CreateNewInstance(inst->ref_id, SRC_REFCLOCK, params->sel_options, NULL,
|
||||||
params->min_samples, params->max_samples, 0.0);
|
params->min_samples, params->max_samples, 0.0, 0.0);
|
||||||
|
|
||||||
DEBUG_LOG("refclock %s refid=%s poll=%d dpoll=%d filter=%d",
|
DEBUG_LOG("refclock %s refid=%s poll=%d dpoll=%d filter=%d",
|
||||||
params->driver_name, UTI_RefidToString(inst->ref_id),
|
params->driver_name, UTI_RefidToString(inst->ref_id),
|
||||||
|
|
|
@ -213,8 +213,9 @@ void SRC_Finalise(void)
|
||||||
/* Function to create a new instance. This would be called by one of
|
/* Function to create a new instance. This would be called by one of
|
||||||
the individual source-type instance creation routines. */
|
the individual source-type instance creation routines. */
|
||||||
|
|
||||||
SRC_Instance SRC_CreateNewInstance(uint32_t ref_id, SRC_Type type, int sel_options, IPAddr *addr,
|
SRC_Instance SRC_CreateNewInstance(uint32_t ref_id, SRC_Type type, int sel_options,
|
||||||
int min_samples, int max_samples, double min_delay)
|
IPAddr *addr, int min_samples, int max_samples,
|
||||||
|
double min_delay, double asymmetry)
|
||||||
{
|
{
|
||||||
SRC_Instance result;
|
SRC_Instance result;
|
||||||
|
|
||||||
|
@ -226,7 +227,8 @@ SRC_Instance SRC_CreateNewInstance(uint32_t ref_id, SRC_Type type, int sel_optio
|
||||||
max_samples = CNF_GetMaxSamples();
|
max_samples = CNF_GetMaxSamples();
|
||||||
|
|
||||||
result = MallocNew(struct SRC_Instance_Record);
|
result = MallocNew(struct SRC_Instance_Record);
|
||||||
result->stats = SST_CreateInstance(ref_id, addr, min_samples, max_samples, min_delay);
|
result->stats = SST_CreateInstance(ref_id, addr, min_samples, max_samples,
|
||||||
|
min_delay, asymmetry);
|
||||||
|
|
||||||
if (n_sources == max_n_sources) {
|
if (n_sources == max_n_sources) {
|
||||||
/* Reallocate memory */
|
/* Reallocate memory */
|
||||||
|
|
|
@ -59,8 +59,9 @@ typedef enum {
|
||||||
/* Function to create a new instance. This would be called by one of
|
/* Function to create a new instance. This would be called by one of
|
||||||
the individual source-type instance creation routines. */
|
the individual source-type instance creation routines. */
|
||||||
|
|
||||||
extern SRC_Instance SRC_CreateNewInstance(uint32_t ref_id, SRC_Type type, int sel_options, IPAddr *addr,
|
extern SRC_Instance SRC_CreateNewInstance(uint32_t ref_id, SRC_Type type, int sel_options,
|
||||||
int min_samples, int max_samples, double min_delay);
|
IPAddr *addr, int min_samples, int max_samples,
|
||||||
|
double min_delay, double asymmetry);
|
||||||
|
|
||||||
/* Function to get rid of a source when it is being unconfigured.
|
/* Function to get rid of a source when it is being unconfigured.
|
||||||
This may cause the current reference source to be reselected, if this
|
This may cause the current reference source to be reselected, if this
|
||||||
|
|
|
@ -85,6 +85,9 @@ struct SST_Stats_Record {
|
||||||
/* User defined minimum delay */
|
/* User defined minimum delay */
|
||||||
double fixed_min_delay;
|
double fixed_min_delay;
|
||||||
|
|
||||||
|
/* User defined asymmetry of network jitter */
|
||||||
|
double fixed_asymmetry;
|
||||||
|
|
||||||
/* Number of samples currently stored. The samples are stored in circular
|
/* Number of samples currently stored. The samples are stored in circular
|
||||||
buffer. */
|
buffer. */
|
||||||
int n_samples;
|
int n_samples;
|
||||||
|
@ -200,7 +203,8 @@ SST_Finalise(void)
|
||||||
/* This function creates a new instance of the statistics handler */
|
/* This function creates a new instance of the statistics handler */
|
||||||
|
|
||||||
SST_Stats
|
SST_Stats
|
||||||
SST_CreateInstance(uint32_t refid, IPAddr *addr, int min_samples, int max_samples, double min_delay)
|
SST_CreateInstance(uint32_t refid, IPAddr *addr, int min_samples, int max_samples,
|
||||||
|
double min_delay, double asymmetry)
|
||||||
{
|
{
|
||||||
SST_Stats inst;
|
SST_Stats inst;
|
||||||
inst = MallocNew(struct SST_Stats_Record);
|
inst = MallocNew(struct SST_Stats_Record);
|
||||||
|
@ -208,6 +212,7 @@ SST_CreateInstance(uint32_t refid, IPAddr *addr, int min_samples, int max_sample
|
||||||
inst->min_samples = min_samples;
|
inst->min_samples = min_samples;
|
||||||
inst->max_samples = max_samples;
|
inst->max_samples = max_samples;
|
||||||
inst->fixed_min_delay = min_delay;
|
inst->fixed_min_delay = min_delay;
|
||||||
|
inst->fixed_asymmetry = asymmetry;
|
||||||
|
|
||||||
SST_SetRefid(inst, refid, addr);
|
SST_SetRefid(inst, refid, addr);
|
||||||
SST_ResetInstance(inst);
|
SST_ResetInstance(inst);
|
||||||
|
@ -422,14 +427,43 @@ find_min_delay_sample(SST_Stats inst)
|
||||||
minimum network delay. This can significantly improve the accuracy and
|
minimum network delay. This can significantly improve the accuracy and
|
||||||
stability of the estimated offset and frequency. */
|
stability of the estimated offset and frequency. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
estimate_asymmetry(double *times_back, double *offsets, double *delays, int n,
|
||||||
|
double *asymmetry, int *asymmetry_run)
|
||||||
|
{
|
||||||
|
double a;
|
||||||
|
|
||||||
|
/* Reset the counter when the regression fails or the sign changes */
|
||||||
|
if (!RGR_MultipleRegress(times_back, delays, offsets, n, &a) ||
|
||||||
|
a * *asymmetry_run < 0.0) {
|
||||||
|
*asymmetry = 0;
|
||||||
|
*asymmetry_run = 0.0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a <= -MIN_ASYMMETRY && *asymmetry_run > -MAX_ASYMMETRY_RUN)
|
||||||
|
(*asymmetry_run)--;
|
||||||
|
else if (a >= MIN_ASYMMETRY && *asymmetry_run < MAX_ASYMMETRY_RUN)
|
||||||
|
(*asymmetry_run)++;
|
||||||
|
|
||||||
|
if (abs(*asymmetry_run) < MIN_ASYMMETRY_RUN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*asymmetry = CLAMP(-MAX_ASYMMETRY, a, MAX_ASYMMETRY);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
correct_asymmetry(SST_Stats inst, double *times_back, double *offsets)
|
correct_asymmetry(SST_Stats inst, double *times_back, double *offsets)
|
||||||
{
|
{
|
||||||
double asymmetry, min_delay, delays[MAX_SAMPLES * REGRESS_RUNS_RATIO];
|
double min_delay, delays[MAX_SAMPLES * REGRESS_RUNS_RATIO];
|
||||||
int i, n;
|
int i, n;
|
||||||
|
|
||||||
/* Don't try to estimate the asymmetry with reference clocks */
|
/* Check if the asymmetry was not specified to be zero */
|
||||||
if (!inst->ip_addr)
|
if (inst->fixed_asymmetry == 0.0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
min_delay = SST_MinRoundTripDelay(inst);
|
min_delay = SST_MinRoundTripDelay(inst);
|
||||||
|
@ -439,29 +473,17 @@ correct_asymmetry(SST_Stats inst, double *times_back, double *offsets)
|
||||||
delays[i] = inst->peer_delays[get_runsbuf_index(inst, i - inst->runs_samples)] -
|
delays[i] = inst->peer_delays[get_runsbuf_index(inst, i - inst->runs_samples)] -
|
||||||
min_delay;
|
min_delay;
|
||||||
|
|
||||||
/* Reset the counter when the regression fails or the sign changes */
|
if (fabs(inst->fixed_asymmetry) <= MAX_ASYMMETRY) {
|
||||||
if (!RGR_MultipleRegress(times_back, delays, offsets, n, &asymmetry) ||
|
inst->asymmetry = inst->fixed_asymmetry;
|
||||||
asymmetry * inst->asymmetry_run < 0.0) {
|
} else {
|
||||||
inst->asymmetry_run = 0;
|
if (!estimate_asymmetry(times_back, offsets, delays, n,
|
||||||
inst->asymmetry = 0.0;
|
&inst->asymmetry, &inst->asymmetry_run))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
asymmetry = CLAMP(-MAX_ASYMMETRY, asymmetry, MAX_ASYMMETRY);
|
|
||||||
|
|
||||||
if (asymmetry <= -MIN_ASYMMETRY && inst->asymmetry_run > -MAX_ASYMMETRY_RUN)
|
|
||||||
inst->asymmetry_run--;
|
|
||||||
else if (asymmetry >= MIN_ASYMMETRY && inst->asymmetry_run < MAX_ASYMMETRY_RUN)
|
|
||||||
inst->asymmetry_run++;
|
|
||||||
|
|
||||||
if (abs(inst->asymmetry_run) < MIN_ASYMMETRY_RUN)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Correct the offsets */
|
/* Correct the offsets */
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
offsets[i] -= asymmetry * delays[i];
|
offsets[i] -= inst->asymmetry * delays[i];
|
||||||
|
|
||||||
inst->asymmetry = asymmetry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
|
@ -39,7 +39,8 @@ extern void SST_Finalise(void);
|
||||||
|
|
||||||
/* This function creates a new instance of the statistics handler */
|
/* This function creates a new instance of the statistics handler */
|
||||||
extern SST_Stats SST_CreateInstance(uint32_t refid, IPAddr *addr,
|
extern SST_Stats SST_CreateInstance(uint32_t refid, IPAddr *addr,
|
||||||
int min_samples, int max_samples, double min_delay);
|
int min_samples, int max_samples,
|
||||||
|
double min_delay, double asymmetry);
|
||||||
|
|
||||||
/* This function deletes an instance of the statistics handler. */
|
/* This function deletes an instance of the statistics handler. */
|
||||||
extern void SST_DeleteInstance(SST_Stats inst);
|
extern void SST_DeleteInstance(SST_Stats inst);
|
||||||
|
|
|
@ -53,7 +53,8 @@ test_unit(void)
|
||||||
|
|
||||||
DEBUG_LOG("added source %d options %d", j, sel_options);
|
DEBUG_LOG("added source %d options %d", j, sel_options);
|
||||||
srcs[j] = SRC_CreateNewInstance(UTI_IPToRefid(&addr), SRC_NTP, sel_options, &addr,
|
srcs[j] = SRC_CreateNewInstance(UTI_IPToRefid(&addr), SRC_NTP, sel_options, &addr,
|
||||||
SRC_DEFAULT_MINSAMPLES, SRC_DEFAULT_MAXSAMPLES, 0.0);
|
SRC_DEFAULT_MINSAMPLES, SRC_DEFAULT_MAXSAMPLES,
|
||||||
|
0.0, 1.0);
|
||||||
SRC_UpdateReachability(srcs[j], 1);
|
SRC_UpdateReachability(srcs[j], 1);
|
||||||
|
|
||||||
samples = (i + j) % 5 + 3;
|
samples = (i + j) % 5 + 3;
|
||||||
|
|
Loading…
Reference in a new issue