Example #1
0
int
MNL_DeleteSample(int index)
{
  int i;
  struct timeval now;

  if ((index < 0) || (index >= n_samples)) {
    return 0;
  }

  /* Crunch the samples down onto the one being deleted */

  for (i=index; i<(n_samples-1); i++) {
    samples[i] = samples[i+1];
  }
  
  n_samples -= 1;

  /* Now re-estimate.  NULLs because we don't want the parameters back
     in this case. */
  LCL_ReadCookedTime(&now, NULL);
  estimate_and_set_system(&now, 0, 0.0, NULL, NULL, NULL);

  return 1;

}
Example #2
0
int
MNL_AcceptTimestamp(struct timeval *ts, long *offset_cs, double *dfreq_ppm, double *new_afreq_ppm)
{
  struct timeval now;
  double offset, diff;
  int i;

  if (enabled) {
    LCL_ReadCookedTime(&now, NULL);

    /* Make sure the provided timestamp is sane and the sample
       is not too close to the last one */

    if (!UTI_IsTimeOffsetSane(ts, 0.0))
     return 0;

    if (n_samples) {
      UTI_DiffTimevalsToDouble(&diff, &now, &samples[n_samples - 1].when);
      if (diff < MIN_SAMPLE_SEPARATION)
        return 0;
    }

    UTI_DiffTimevalsToDouble(&offset, &now, ts);

    /* Check if buffer full up */
    if (n_samples == MAX_SAMPLES) {
      /* Shift samples down */
      for (i=1; i<n_samples; i++) {
        samples[i-1] = samples[i];
      }
      --n_samples;
    }
    
    samples[n_samples].when = now;
    samples[n_samples].offset = offset;
    samples[n_samples].orig_offset = offset;
    ++n_samples;

    estimate_and_set_system(&now, 1, offset, offset_cs, dfreq_ppm, new_afreq_ppm);

    return 1;

  } else {
  
    return 0;

  }
}
Example #3
0
int
RTC_Linux_Trim(void)
{
  struct timeval now;


  /* Remember the slope coefficient - we won't be able to determine a
     good one in a few seconds when we determine the new offset! */
  saved_coef_gain_rate = coef_gain_rate;

  if (fabs(coef_seconds_fast) > 1.0) {

    LOG(LOGS_INFO, LOGF_RtcLinux, "Trimming RTC, error = %.3f seconds", coef_seconds_fast);

    /* Do processing to set clock.  Let R be the value we set the
       RTC to, then in 500ms the RTC ticks (R+1) (see comments in
       arch/i386/kernel/time.c about the behaviour of the real time
       clock chip).  If S is the system time now, the error at the
       next RTC tick is given by E = (R+1) - (S+0.5).  Ideally we
       want |E| <= 0.5, which implies R <= S <= R+1, i.e. R is just
       the rounded down part of S, i.e. the seconds part. */

    LCL_ReadCookedTime(&now, NULL);
    
    set_rtc(now.tv_sec);

    /* All old samples will now look bogus under the new
           regime. */
    n_samples = 0;
    operating_mode = OM_AFTERTRIM;

    /* Estimate the offset in case writertc is called or chronyd
       is terminated during rapid sampling */
    coef_seconds_fast = -now.tv_usec / 1e6 + 0.5;
    coef_ref_time = now.tv_sec;

    /* And start rapid sampling, interrupts on now */
    if (timeout_running) {
      SCH_RemoveTimeout(timeout_id);
      timeout_running = 0;
    }
    switch_interrupts(1);
  }

  return 1;
  
}
Example #4
0
static void
fallback_time_init(void)
{
  struct timeval now;
  struct stat buf;
  char *drift_file;

  drift_file = CNF_GetDriftFile();
  if (!drift_file)
    return;

  if (stat(drift_file, &buf))
    return;

  LCL_ReadCookedTime(&now, NULL);

  if (now.tv_sec < buf.st_mtime) {
    LCL_ApplyStepOffset(now.tv_sec - buf.st_mtime);
    LOG(LOGS_INFO, LOGF_Rtc,
        "System clock set from driftfile %s", drift_file);
  }
}
Example #5
0
int
MNL_AcceptTimestamp(struct timeval *ts, long *offset_cs, double *dfreq_ppm, double *new_afreq_ppm)
{
  struct timeval now;
  double offset;
  int i;

  if (enabled) {

    /* Check whether timestamp is within margin of old one */
    LCL_ReadCookedTime(&now, NULL);

    UTI_DiffTimevalsToDouble(&offset, &now, ts);

    /* Check if buffer full up */
    if (n_samples == MAX_SAMPLES) {
      /* Shift samples down */
      for (i=1; i<n_samples; i++) {
        samples[i-1] = samples[i];
      }
      --n_samples;
    }
    
    samples[n_samples].when = now;
    samples[n_samples].offset = offset;
    samples[n_samples].orig_offset = offset;
    ++n_samples;

    estimate_and_set_system(&now, 1, offset, offset_cs, dfreq_ppm, new_afreq_ppm);

    return 1;

  } else {
  
    return 0;

  }
}
Example #6
0
int
RTC_Linux_TimePreInit(time_t driftfile_time)
{
  int fd, status;
  struct rtc_time rtc_raw, rtc_raw_retry;
  struct tm rtc_tm;
  time_t rtc_t;
  double accumulated_error, sys_offset;
  struct timeval new_sys_time, old_sys_time;

  coefs_file_name = CNF_GetRtcFile();

  setup_config();
  read_coefs_from_file();

  fd = open(CNF_GetRtcDevice(), O_RDONLY);

  if (fd < 0) {
    return 0; /* Can't open it, and won't be able to later */
  }

  /* Retry reading the rtc until both read attempts give the same sec value.
     This way the race condition is prevented that the RTC has updated itself
     during the first read operation. */
  do {
    status = ioctl(fd, RTC_RD_TIME, &rtc_raw);
    if (status >= 0) {
      status = ioctl(fd, RTC_RD_TIME, &rtc_raw_retry);
    }
  } while (status >= 0 && rtc_raw.tm_sec != rtc_raw_retry.tm_sec);

  /* Read system clock */
  LCL_ReadCookedTime(&old_sys_time, NULL);

  close(fd);

  if (status >= 0) {
    /* Convert to seconds since 1970 */
    rtc_tm.tm_sec = rtc_raw.tm_sec;
    rtc_tm.tm_min = rtc_raw.tm_min;
    rtc_tm.tm_hour = rtc_raw.tm_hour;
    rtc_tm.tm_mday = rtc_raw.tm_mday;
    rtc_tm.tm_mon = rtc_raw.tm_mon;
    rtc_tm.tm_year = rtc_raw.tm_year;
    
    rtc_t = t_from_rtc(&rtc_tm);

    if (rtc_t != (time_t)(-1)) {

      /* Work out approximatation to correct time (to about the
         nearest second) */
      if (valid_coefs_from_file) {
        accumulated_error = file_ref_offset +
          (rtc_t - file_ref_time) * 1.0e-6 * file_rate_ppm;
      } else {
        accumulated_error = 0.0;
      }

      /* Correct time */

      new_sys_time.tv_sec = rtc_t;
      /* Average error in the RTC reading */
      new_sys_time.tv_usec = 500000;

      UTI_AddDoubleToTimeval(&new_sys_time, -accumulated_error, &new_sys_time);

      if (new_sys_time.tv_sec < driftfile_time) {
        LOG(LOGS_WARN, LOGF_RtcLinux, "RTC time before last driftfile modification (ignored)");
        return 0;
      }

      UTI_DiffTimevalsToDouble(&sys_offset, &old_sys_time, &new_sys_time);

      /* Set system time only if the step is larger than 1 second */
      if (fabs(sys_offset) >= 1.0) {
        if (LCL_ApplyStepOffset(sys_offset))
          LOG(LOGS_INFO, LOGF_RtcLinux, "System time set from RTC");
      }
    } else {
      return 0;
    }
  } else {
    return 0;
  }

  return 1;
}