Beispiel #1
0
unsigned long hwtimer_arch_now(void)
{
    struct timespec t;

    DEBUG("hwtimer_arch_now()\n");

    _native_syscall_enter();
#ifdef __MACH__
    clock_serv_t cclock;
    mach_timespec_t mts;
    host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
    clock_get_time(cclock, &mts);
    mach_port_deallocate(mach_task_self(), cclock);
    t.tv_sec = mts.tv_sec;
    t.tv_nsec = mts.tv_nsec;
#else

    if (real_clock_gettime(CLOCK_MONOTONIC, &t) == -1) {
        err(EXIT_FAILURE, "hwtimer_arch_now: clock_gettime");
    }

#endif
    _native_syscall_leave();

    native_hwtimer_now = ts2ticks(&t) - time_null;

    struct timeval tv;
    ticks2tv(native_hwtimer_now, &tv);
    DEBUG("hwtimer_arch_now(): it is now %lu s %lu us\n",
            (unsigned long)tv.tv_sec, (unsigned long)tv.tv_usec);
    DEBUG("hwtimer_arch_now(): returning %lu\n", native_hwtimer_now);
    return native_hwtimer_now;
}
Beispiel #2
0
/// Replacement pthread_cond_timedwait()
///
/// WARNING: This replacement calls through to the 2.3.2 version of the 
/// real pthread_cond_timedwait, regardless of the version the calling code
/// assumed it would be calling.  This will need updating to support other
/// libc versions.
///
/// WARNING THE SECOND: This assumes that the condition variable was created
/// with a condattr that specifies CLOCK_MONOTONIC.
///
/// http://blog.fesnel.com/blog/2009/08/25/preloading-with-multiple-symbol-versions/
int pthread_cond_timedwait(pthread_cond_t* cond,
                           pthread_mutex_t* mutex,
                           const struct timespec* abstime)
{
  struct timespec fixed_time;

  if (!real_pthread_cond_timedwait)
  {
    real_pthread_cond_timedwait = (pthread_cond_timedwait_func_t)(intptr_t)dlvsym(RTLD_NEXT, "pthread_cond_timedwait", "GLIBC_2.3.2");
  }

  // Subtract our fake time and add the real time, this means the
  // relative delay is correct while allowing the calling code to think
  // it's woking with absolute time.
  //
  // Note we call the fake clock_gettime first, meaning that real_clock_gettime
  // will be set before the call to it in the next line.
  struct timespec fake_time;
  struct timespec real_time;
  struct timespec delta_time;
  clock_gettime(CLOCK_MONOTONIC, &fake_time);
  real_clock_gettime(CLOCK_MONOTONIC, &real_time);
  ts_sub(*abstime, fake_time, delta_time);
  ts_add(real_time, delta_time, fixed_time);

  return real_pthread_cond_timedwait(cond, mutex, &fixed_time);
}
Beispiel #3
0
void cwtest_completely_control_time()
{
  if (!real_clock_gettime)
  {
    real_clock_gettime = (int (*)(clockid_t, struct timespec *))(intptr_t)dlsym(RTLD_NEXT, "clock_gettime");
  }

  if (!real_time)
  {
    real_time = (time_t (*)(time_t*))(intptr_t)dlsym(RTLD_NEXT, "time");
  }

  pthread_mutex_lock(&time_lock);
  completely_control_time = true;

  // Store the time at which the test scripts took control.  Do this for both
  // clock_gettime() and time().
  struct timespec ts;
  for (unsigned int i = 0;
       i < (sizeof(supported_clock_ids) / sizeof(supported_clock_ids[0]));
       ++i)
  {
    clockid_t clock_id = supported_clock_ids[i];
    real_clock_gettime(clock_id, &ts);
    abs_timespecs[clock_id] = ts;
  }

  abs_time = real_time(NULL);

  pthread_mutex_unlock(&time_lock);
}
Beispiel #4
0
unsigned int timer_read(tim_t dev)
{
    if (dev >= TIMER_NUMOF) {
        return 0;
    }

    struct timespec t;

    DEBUG("timer_read()\n");

    _native_syscall_enter();
#ifdef __MACH__
    clock_serv_t cclock;
    mach_timespec_t mts;
    host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
    clock_get_time(cclock, &mts);
    mach_port_deallocate(mach_task_self(), cclock);
    t.tv_sec = mts.tv_sec;
    t.tv_nsec = mts.tv_nsec;
#else

    if (real_clock_gettime(CLOCK_MONOTONIC, &t) == -1) {
        err(EXIT_FAILURE, "timer_read: clock_gettime");
    }

#endif
    _native_syscall_leave();

    return ts2ticks(&t) - time_null;
}
Beispiel #5
0
/// Replacement clock_gettime.
int clock_gettime(clockid_t clk_id, struct timespec *tp) throw ()
{
  int rc;

  if (!real_clock_gettime)
  {
    real_clock_gettime = (int (*)(clockid_t, struct timespec *))(intptr_t)dlsym(RTLD_NEXT, "clock_gettime");
  }

  pthread_mutex_lock(&time_lock);

  if (completely_control_time)
  {
    if (abs_timespecs.find(clk_id) != abs_timespecs.end())
    {
      *tp = abs_timespecs[clk_id];
      rc = 0;
    }
    else
    {
      // We don't support this clock ID. Print a warning, and act like an
      // invalid clock ID has been requested.
      fprintf(stderr, "WARNING: Clock ID %d is not supported (%s:%d)\n",
              clk_id, __FILE__, __LINE__);
      rc = -1;
      errno = EINVAL;
    }
  }
  else
  {
    rc = real_clock_gettime(clk_id, tp);
  }

  if (!rc)
  {
    ts_add(*tp, time_offset, *tp);
  }

  pthread_mutex_unlock(&time_lock);

  return rc;
}