/**
 * Wrapper around various monotone time sources.
 */
DECLINLINE(int) mono_clock(struct timespec *ts)
{
    static int iWorking = -1;
    switch (iWorking)
    {
#ifdef CLOCK_MONOTONIC
    /*
     * Standard clock_gettime()
     */
    case 0:
        return clock_gettime(CLOCK_MONOTONIC, ts);

    /*
     * Syscall clock_gettime().
     */
    case 1:
        return sys_clock_gettime(CLOCK_MONOTONIC, ts);

#endif /* CLOCK_MONOTONIC */


    /*
     * Figure out what's working.
     */
    case -1:
    {
        int rc;
#ifdef CLOCK_MONOTONIC
        /*
         * Real-Time API.
         */
        rc = clock_gettime(CLOCK_MONOTONIC, ts);
        if (!rc)
        {
            iWorking = 0;
            return 0;
        }

        rc = sys_clock_gettime(CLOCK_MONOTONIC, ts);
        if (!rc)
        {
            iWorking = 1;
            return 0;
        }
#endif /* CLOCK_MONOTONIC */

        /* give up */
        iWorking = -2;
        break;
    }
    }
    return -1;
}
示例#2
0
static void test_one_clock_gettime(int clock, const char *name)
{
	struct timespec start, vdso, end;
	int vdso_ret, end_ret;

	printf("[RUN]\tTesting clock_gettime for clock %s (%d)...\n", name, clock);

	if (sys_clock_gettime(clock, &start) < 0) {
		if (errno == EINVAL) {
			vdso_ret = vdso_clock_gettime(clock, &vdso);
			if (vdso_ret == -EINVAL) {
				printf("[OK]\tNo such clock.\n");
			} else {
				printf("[FAIL]\tNo such clock, but __vdso_clock_gettime returned %d\n", vdso_ret);
				nerrs++;
			}
		} else {
			printf("[WARN]\t clock_gettime(%d) syscall returned error %d\n", clock, errno);
		}
		return;
	}

	vdso_ret = vdso_clock_gettime(clock, &vdso);
	end_ret = sys_clock_gettime(clock, &end);

	if (vdso_ret != 0 || end_ret != 0) {
		printf("[FAIL]\tvDSO returned %d, syscall errno=%d\n",
		       vdso_ret, errno);
		nerrs++;
		return;
	}

	printf("\t%llu.%09ld %llu.%09ld %llu.%09ld\n",
	       (unsigned long long)start.tv_sec, start.tv_nsec,
	       (unsigned long long)vdso.tv_sec, vdso.tv_nsec,
	       (unsigned long long)end.tv_sec, end.tv_nsec);

	if (!ts_leq(&start, &vdso) || !ts_leq(&vdso, &end)) {
		printf("[FAIL]\tTimes are out of sequence\n");
		nerrs++;
	}
}
示例#3
0
文件: restorer.c 项目: rmoorman/criu
static int timerfd_arm(struct task_restore_args *args)
{
	int i;

	for (i = 0; i < args->timerfd_n; i++) {
		struct restore_timerfd *t = &args->timerfd[i];
		int ret;

		pr_debug("timerfd: arm for fd %d (%d)\n", t->fd, i);

		if (t->settime_flags & TFD_TIMER_ABSTIME) {
			struct timespec ts = { };

			/*
			 * We might need to adjust value because the checkpoint
			 * and restore procedure takes some time itself. Note
			 * we don't adjust nanoseconds, since the result may
			 * overflow the limit NSEC_PER_SEC FIXME
			 */
			if (sys_clock_gettime(t->clockid, &ts)) {
				pr_err("Can't get current time");
				return -1;
			}

			t->val.it_value.tv_sec += (time_t)ts.tv_sec;

			pr_debug("Ajust id %#x it_value(%llu, %llu) -> it_value(%llu, %llu)\n",
				 t->id, (unsigned long long)ts.tv_sec,
				 (unsigned long long)ts.tv_nsec,
				 (unsigned long long)t->val.it_value.tv_sec,
				 (unsigned long long)t->val.it_value.tv_nsec);
		}

		ret  = sys_timerfd_settime(t->fd, t->settime_flags, &t->val, NULL);
		if (t->ticks)
			ret |= sys_ioctl(t->fd, TFD_IOC_SET_TICKS, (unsigned long)&t->ticks);
		if (ret) {
			pr_err("Can't restore ticks/time for timerfd - %d\n", i);
			return ret;
		}
	}
	return 0;
}