refclocks: allocate refclock instances dynamically

This commit is contained in:
Miroslav Lichvar 2014-09-24 13:56:45 +02:00
parent cd27860e55
commit d92583ed33

View file

@ -27,6 +27,7 @@
#include "config.h" #include "config.h"
#include "array.h"
#include "refclock.h" #include "refclock.h"
#include "reference.h" #include "reference.h"
#include "conf.h" #include "conf.h"
@ -86,10 +87,8 @@ struct RCL_Instance_Record {
SRC_Instance source; SRC_Instance source;
}; };
#define MAX_RCL_SOURCES 8 /* Array of RCL_Instance_Record */
static ARR_Instance refclocks;
static struct RCL_Instance_Record refclocks[MAX_RCL_SOURCES];
static int n_sources = 0;
static LOG_FileID logfileid; static LOG_FileID logfileid;
@ -112,12 +111,20 @@ static int filter_get_sample(struct MedianFilter *filter, struct timeval *sample
static void filter_slew_samples(struct MedianFilter *filter, struct timeval *when, double dfreq, double doffset); static void filter_slew_samples(struct MedianFilter *filter, struct timeval *when, double dfreq, double doffset);
static void filter_add_dispersion(struct MedianFilter *filter, double dispersion); static void filter_add_dispersion(struct MedianFilter *filter, double dispersion);
static RCL_Instance
get_refclock(unsigned int index)
{
return (RCL_Instance)ARR_GetElement(refclocks, index);
}
void void
RCL_Initialise(void) RCL_Initialise(void)
{ {
refclocks = ARR_CreateInstance(sizeof (struct RCL_Instance_Record));
CNF_AddRefclocks(); CNF_AddRefclocks();
if (n_sources > 0) { if (ARR_GetSize(refclocks) > 0) {
LCL_AddParameterChangeHandler(slew_samples, NULL); LCL_AddParameterChangeHandler(slew_samples, NULL);
LCL_AddDispersionNotifyHandler(add_dispersion, NULL); LCL_AddDispersionNotifyHandler(add_dispersion, NULL);
} }
@ -130,10 +137,10 @@ RCL_Initialise(void)
void void
RCL_Finalise(void) RCL_Finalise(void)
{ {
int i; unsigned int i;
for (i = 0; i < n_sources; i++) { for (i = 0; i < ARR_GetSize(refclocks); i++) {
RCL_Instance inst = (RCL_Instance)&refclocks[i]; RCL_Instance inst = get_refclock(i);
if (inst->driver->fini) if (inst->driver->fini)
inst->driver->fini(inst); inst->driver->fini(inst);
@ -143,10 +150,12 @@ RCL_Finalise(void)
SRC_DestroyInstance(inst->source); SRC_DestroyInstance(inst->source);
} }
if (n_sources > 0) { if (ARR_GetSize(refclocks) > 0) {
LCL_RemoveParameterChangeHandler(slew_samples, NULL); LCL_RemoveParameterChangeHandler(slew_samples, NULL);
LCL_RemoveDispersionNotifyHandler(add_dispersion, NULL); LCL_RemoveDispersionNotifyHandler(add_dispersion, NULL);
} }
ARR_DestroyInstance(refclocks);
} }
int int
@ -154,10 +163,7 @@ RCL_AddRefclock(RefclockParameters *params)
{ {
int pps_source = 0; int pps_source = 0;
RCL_Instance inst = &refclocks[n_sources]; RCL_Instance inst = ARR_GetNewElement(refclocks);
if (n_sources == MAX_RCL_SOURCES)
return 0;
if (strcmp(params->driver_name, "SHM") == 0) { if (strcmp(params->driver_name, "SHM") == 0) {
inst->driver = &RCL_SHM_driver; inst->driver = &RCL_SHM_driver;
@ -220,8 +226,13 @@ RCL_AddRefclock(RefclockParameters *params)
inst->ref_id = params->ref_id; inst->ref_id = params->ref_id;
else { else {
unsigned char ref[5] = { 0, 0, 0, 0, 0 }; unsigned char ref[5] = { 0, 0, 0, 0, 0 };
unsigned int index = ARR_GetSize(refclocks);
snprintf((char *)ref, sizeof (ref), "%3.3s", params->driver_name);
ref[3] = index % 10 + '0';
if (index >= 10)
ref[2] = (index / 10) % 10 + '0';
snprintf((char *)ref, 5, "%3.3s%d", params->driver_name, n_sources % 10);
inst->ref_id = ref[0] << 24 | ref[1] << 16 | ref[2] << 8 | ref[3]; inst->ref_id = ref[0] << 24 | ref[1] << 16 | ref[2] << 8 | ref[3];
} }
@ -253,7 +264,6 @@ RCL_AddRefclock(RefclockParameters *params)
DEBUG_LOG(LOGF_Refclock, "refclock %s added poll=%d dpoll=%d filter=%d", DEBUG_LOG(LOGF_Refclock, "refclock %s added poll=%d dpoll=%d filter=%d",
params->driver_name, inst->poll, inst->driver_poll, params->filter_length); params->driver_name, inst->poll, inst->driver_poll, params->filter_length);
n_sources++;
Free(params->driver_name); Free(params->driver_name);
@ -263,10 +273,12 @@ RCL_AddRefclock(RefclockParameters *params)
void void
RCL_StartRefclocks(void) RCL_StartRefclocks(void)
{ {
int i, j; unsigned int i, j, n;
for (i = 0; i < n_sources; i++) { n = ARR_GetSize(refclocks);
RCL_Instance inst = &refclocks[i];
for (i = 0; i < n; i++) {
RCL_Instance inst = get_refclock(i);
SRC_SetSelectable(inst->source); SRC_SetSelectable(inst->source);
SRC_SetActive(inst->source); SRC_SetActive(inst->source);
@ -274,9 +286,9 @@ RCL_StartRefclocks(void)
if (inst->lock_ref) { if (inst->lock_ref) {
/* Replace lock refid with index to refclocks */ /* Replace lock refid with index to refclocks */
for (j = 0; j < n_sources && refclocks[j].ref_id != inst->lock_ref; j++) for (j = 0; j < n && get_refclock(j)->ref_id != inst->lock_ref; j++)
; ;
inst->lock_ref = (j < n_sources) ? j : -1; inst->lock_ref = j < n ? j : -1;
} else } else
inst->lock_ref = -1; inst->lock_ref = -1;
} }
@ -285,14 +297,14 @@ RCL_StartRefclocks(void)
void void
RCL_ReportSource(RPT_SourceReport *report, struct timeval *now) RCL_ReportSource(RPT_SourceReport *report, struct timeval *now)
{ {
int i; unsigned int i;
uint32_t ref_id; uint32_t ref_id;
assert(report->ip_addr.family == IPADDR_INET4); assert(report->ip_addr.family == IPADDR_INET4);
ref_id = report->ip_addr.addr.in4; ref_id = report->ip_addr.addr.in4;
for (i = 0; i < n_sources; i++) { for (i = 0; i < ARR_GetSize(refclocks); i++) {
RCL_Instance inst = &refclocks[i]; RCL_Instance inst = get_refclock(i);
if (inst->ref_id == ref_id) { if (inst->ref_id == ref_id) {
report->poll = inst->poll; report->poll = inst->poll;
report->mode = RPT_LOCAL_REFERENCE; report->mode = RPT_LOCAL_REFERENCE;
@ -410,16 +422,19 @@ RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second)
offset -= 1.0 / rate; offset -= 1.0 / rate;
if (instance->lock_ref != -1) { if (instance->lock_ref != -1) {
RCL_Instance lock_refclock;
struct timeval ref_sample_time; struct timeval ref_sample_time;
double sample_diff, ref_offset, ref_dispersion, shift; double sample_diff, ref_offset, ref_dispersion, shift;
if (!filter_get_last_sample(&refclocks[instance->lock_ref].filter, lock_refclock = get_refclock(instance->lock_ref);
if (!filter_get_last_sample(&lock_refclock->filter,
&ref_sample_time, &ref_offset, &ref_dispersion)) { &ref_sample_time, &ref_offset, &ref_dispersion)) {
DEBUG_LOG(LOGF_Refclock, "refclock pulse ignored no ref sample"); DEBUG_LOG(LOGF_Refclock, "refclock pulse ignored no ref sample");
return 0; return 0;
} }
ref_dispersion += filter_get_avg_sample_dispersion(&refclocks[instance->lock_ref].filter); ref_dispersion += filter_get_avg_sample_dispersion(&lock_refclock->filter);
UTI_DiffTimevalsToDouble(&sample_diff, &cooked_time, &ref_sample_time); UTI_DiffTimevalsToDouble(&sample_diff, &cooked_time, &ref_sample_time);
if (fabs(sample_diff) >= 2.0 / rate) { if (fabs(sample_diff) >= 2.0 / rate) {
@ -442,7 +457,7 @@ RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second)
return 0; return 0;
} }
leap = refclocks[instance->lock_ref].leap_status; leap = lock_refclock->leap_status;
DEBUG_LOG(LOGF_Refclock, "refclock pulse second=%.9f offset=%.9f offdiff=%.9f samplediff=%.9f", DEBUG_LOG(LOGF_Refclock, "refclock pulse second=%.9f offset=%.9f offdiff=%.9f samplediff=%.9f",
second, offset, ref_offset - offset, sample_diff); second, offset, ref_offset - offset, sample_diff);
@ -509,10 +524,12 @@ static int
pps_stratum(RCL_Instance instance, struct timeval *tv) pps_stratum(RCL_Instance instance, struct timeval *tv)
{ {
struct timeval ref_time; struct timeval ref_time;
int is_synchronised, stratum, i; int is_synchronised, stratum;
unsigned int i;
double root_delay, root_dispersion; double root_delay, root_dispersion;
NTP_Leap leap; NTP_Leap leap;
uint32_t ref_id; uint32_t ref_id;
RCL_Instance refclock;
REF_GetReferenceParams(tv, &is_synchronised, &leap, &stratum, REF_GetReferenceParams(tv, &is_synchronised, &leap, &stratum,
&ref_id, &ref_time, &root_delay, &root_dispersion); &ref_id, &ref_time, &root_delay, &root_dispersion);
@ -523,9 +540,10 @@ pps_stratum(RCL_Instance instance, struct timeval *tv)
return stratum - 1; return stratum - 1;
/* Or the current source is another PPS refclock */ /* Or the current source is another PPS refclock */
for (i = 0; i < n_sources; i++) { for (i = 0; i < ARR_GetSize(refclocks); i++) {
if (refclocks[i].ref_id == ref_id && refclock = get_refclock(i);
refclocks[i].pps_active && refclocks[i].lock_ref == -1) if (refclock->ref_id == ref_id &&
refclock->pps_active && refclock->lock_ref == -1)
return stratum - 1; return stratum - 1;
} }
@ -580,23 +598,23 @@ static void
slew_samples(struct timeval *raw, struct timeval *cooked, double dfreq, slew_samples(struct timeval *raw, struct timeval *cooked, double dfreq,
double doffset, LCL_ChangeType change_type, void *anything) double doffset, LCL_ChangeType change_type, void *anything)
{ {
int i; unsigned int i;
for (i = 0; i < n_sources; i++) { for (i = 0; i < ARR_GetSize(refclocks); i++) {
if (change_type == LCL_ChangeUnknownStep) if (change_type == LCL_ChangeUnknownStep)
filter_reset(&refclocks[i].filter); filter_reset(&get_refclock(i)->filter);
else else
filter_slew_samples(&refclocks[i].filter, cooked, dfreq, doffset); filter_slew_samples(&get_refclock(i)->filter, cooked, dfreq, doffset);
} }
} }
static void static void
add_dispersion(double dispersion, void *anything) add_dispersion(double dispersion, void *anything)
{ {
int i; unsigned int i;
for (i = 0; i < n_sources; i++) for (i = 0; i < ARR_GetSize(refclocks); i++)
filter_add_dispersion(&refclocks[i].filter, dispersion); filter_add_dispersion(&get_refclock(i)->filter, dispersion);
} }
static void static void