static void process_reading(time_t rtc_time, struct timeval *system_time) { double rtc_fast; accumulate_sample(rtc_time, system_time); switch (operating_mode) { case OM_NORMAL: if (n_samples_since_regression >= N_SAMPLES_PER_REGRESSION) { run_regression(1, &coefs_valid, &coef_ref_time, &coef_seconds_fast, &coef_gain_rate); n_samples_since_regression = 0; maybe_autotrim(); } break; case OM_INITIAL: if (n_samples_since_regression >= 8) { handle_initial_trim(); } break; case OM_AFTERTRIM: if (n_samples_since_regression >= 8) { handle_relock_after_trim(); } break; default: assert(0); break; } if (logfileid != -1) { rtc_fast = (double)(rtc_time - system_time->tv_sec) - 1.0e-6 * (double) system_time->tv_usec; LOG_FileWrite(logfileid, "%s %14.6f %1d %14.6f %12.3f %2d %2d %4d", UTI_TimeToLogForm(system_time->tv_sec), rtc_fast, coefs_valid, coef_seconds_fast, coef_gain_rate * 1.0e6, n_samples, n_runs, measurement_period); } }
void SST_DoNewRegression(SST_Stats inst) { double times_back[MAX_SAMPLES * REGRESS_RUNS_RATIO]; double offsets[MAX_SAMPLES * REGRESS_RUNS_RATIO]; double peer_distances[MAX_SAMPLES]; double weights[MAX_SAMPLES]; int degrees_of_freedom; int best_start, times_back_start; double est_intercept, est_slope, est_var, est_intercept_sd, est_slope_sd; int i, j, nruns; double min_distance, mean_distance; double sd_weight, sd; double old_skew, old_freq, stress; convert_to_intervals(inst, times_back + inst->runs_samples); if (inst->n_samples > 0) { for (i = -inst->runs_samples; i < inst->n_samples; i++) { offsets[i + inst->runs_samples] = inst->offsets[get_runsbuf_index(inst, i)]; } for (i = 0, mean_distance = 0.0, min_distance = DBL_MAX; i < inst->n_samples; i++) { j = get_buf_index(inst, i); peer_distances[i] = 0.5 * inst->peer_delays[j] + inst->peer_dispersions[j]; mean_distance += peer_distances[i]; if (peer_distances[i] < min_distance) { min_distance = peer_distances[i]; } } mean_distance /= inst->n_samples; /* And now, work out the weight vector */ sd = mean_distance - min_distance; if (sd > min_distance || sd <= 0.0) sd = min_distance; for (i=0; i<inst->n_samples; i++) { sd_weight = 1.0 + SD_TO_DIST_RATIO * (peer_distances[i] - min_distance) / sd; weights[i] = sd_weight * sd_weight; } } inst->regression_ok = RGR_FindBestRegression(times_back + inst->runs_samples, offsets + inst->runs_samples, weights, inst->n_samples, inst->runs_samples, min_samples, &est_intercept, &est_slope, &est_var, &est_intercept_sd, &est_slope_sd, &best_start, &nruns, °rees_of_freedom); if (inst->regression_ok) { old_skew = inst->skew; old_freq = inst->estimated_frequency; inst->estimated_frequency = est_slope; inst->skew = est_slope_sd * RGR_GetTCoef(degrees_of_freedom); inst->estimated_offset = est_intercept; inst->offset_time = inst->sample_times[inst->last_sample]; inst->estimated_offset_sd = est_intercept_sd; inst->variance = est_var; inst->nruns = nruns; if (inst->skew < MIN_SKEW) inst->skew = MIN_SKEW; stress = fabs(old_freq - inst->estimated_frequency) / old_skew; if (best_start > 0) { /* If we are throwing old data away, retain the current assumptions about the skew */ inst->skew_dirn = SST_Skew_Nochange; } else { if (inst->skew < old_skew) { inst->skew_dirn = SST_Skew_Decrease; } else { inst->skew_dirn = SST_Skew_Increase; } } if (logfileid != -1) { LOG_FileWrite(logfileid, "%s %-15s %10.3e %10.3e %10.3e %10.3e %10.3e %7.1e %3d %3d %3d", UTI_TimeToLogForm(inst->offset_time.tv_sec), inst->ip_addr ? UTI_IPToString(inst->ip_addr) : UTI_RefidToString(inst->refid), sqrt(inst->variance), inst->estimated_offset, inst->estimated_offset_sd, inst->estimated_frequency, inst->skew, stress, inst->n_samples, best_start, nruns); } times_back_start = inst->runs_samples + best_start; prune_register(inst, best_start); } else { inst->estimated_frequency = 0.0; inst->skew = WORST_CASE_FREQ_BOUND; times_back_start = 0; } find_best_sample_index(inst, times_back + times_back_start); }