Example #1
0
int timerfd_settime(int fd, int flags,
                    const struct itimerspec *new_value,
                    struct itimerspec *old_value)
{
	int timerfd, periodfd;
	int ret;
	uint64_t period;
	struct timespec now_timespec = {0};
	struct timespec rel_timespec;

	timerfd = get_sibling_fd(fd, "timer");
	if (timerfd < 0)
		return -1;
	periodfd = get_sibling_fd(fd, "period");
	if (periodfd < 0) {
		close(timerfd);
		return -1;
	}
	if (old_value) {
		if (__timerfd_gettime(timerfd, periodfd, old_value)) {
			ret = -1;
			goto out;
		}
	}
	if (!new_value->it_value.tv_sec && !new_value->it_value.tv_nsec) {
		ret = set_timer(timerfd, 0);
		goto out;
	}
	period = timespec2tsc(&new_value->it_interval);
	ret = set_period(periodfd, period);
	if (ret < 0)
		goto out;
	/* So the caller is asking for timespecs in wall-clock time (depending
	 * on the clock, actually, (TODO)), and the kernel expects TSC ticks
	 * from boot.  If !ABSTIME, then it's just relative to now.  If it is
	 * ABSTIME, then they are asking in terms of real-world time, which
	 * means ABS - NOW to get the rel time, then convert to tsc ticks. */
	if (flags & TFD_TIMER_ABSTIME) {
		ret = clock_gettime(CLOCK_MONOTONIC, &now_timespec);
		if (ret < 0)
			goto out;
		subtract_timespecs(&rel_timespec, &new_value->it_value,
				   &now_timespec);
	} else {
		rel_timespec = new_value->it_value;
	}
	ret = set_timer(timerfd, timespec2tsc(&rel_timespec) + read_tsc());
	/* fall-through */
out:
	close(timerfd);
	close(periodfd);
	return ret;
}
Example #2
0
int timerfd_gettime(int fd, struct itimerspec *curr_value)
{
	int timerfd, periodfd;
	int ret;

	timerfd = get_sibling_fd(fd, "timer");
	if (timerfd < 0)
		return -1;
	periodfd = get_sibling_fd(fd, "period");
	if (periodfd < 0) {
		close(timerfd);
		return -1;
	}
	ret = __timerfd_gettime(timerfd, periodfd, curr_value);
	close(timerfd);
	close(periodfd);
	return ret;
}