NetBSD Problem Report #58917

From www@netbsd.org  Wed Dec 18 16:18:51 2024
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (2048 bits)
	 client-signature RSA-PSS (2048 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 3E2C91A9238
	for <gnats-bugs@gnats.NetBSD.org>; Wed, 18 Dec 2024 16:18:51 +0000 (UTC)
Message-Id: <20241218161850.079651A923A@mollari.NetBSD.org>
Date: Wed, 18 Dec 2024 16:18:49 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: timer_settime and timerfd_settime return absolute time of next event
X-Send-Pr-Version: www-1.0

>Number:         58917
>Category:       kern
>Synopsis:       timer_settime and timerfd_settime return absolute time of next event
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Dec 18 16:20:00 +0000 2024
>Last-Modified:  Thu Dec 19 23:55:01 +0000 2024
>Originator:     Taylor R Campbell
>Release:        current, 10, 9, ...
>Organization:
The TimerBSD Remaining
>Environment:
>Description:
timer_settime(2) and timerfd_settime(2) are supposed to return the
relative duration until the event, not the absolute time of the next
event.  But we've implemented them to return the absolute time of the
next event, and we failed to write any automatic tests for this.

POSIX says of timer_settime(2):

> If the argument ovalue is not NULL, the timer_settime() function
> shall store, in the location referenced by ovalue, a value
> representing the previous amount of time before the timer would have
> expired, or zero if the timer was disarmed, together with the
> previous timer reload value.
>
> https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/timer_settime.html

Linux man page says of timerfd_settime(2):

>        If the old_value argument is not NULL, then the itimerspec
>        structure that it points to is used to return the setting of the
>        timer that was current at the time of the call; see the
>        description of timerfd_gettime() following.
>
>    timerfd_gettime()
>        timerfd_gettime() returns, in curr_value, an itimerspec structure
>        that contains the current setting of the timer referred to by the
>        file descriptor fd.
>
>        The it_value field returns the amount of time until the timer
>        will next expire.  If both fields of this structure are zero,
>        then the timer is currently disarmed.  This field always contains
>        a relative value, regardless of whether the TFD_TIMER_ABSTIME
>        flag was specified when setting the timer.
>
> https://www.man7.org/linux/man-pages/man2/timerfd_create.2.html

>How-To-Repeat:
#include <err.h>
#include <stdio.h>
#include <time.h>

int
main(void)
{
	timer_t t;
	struct timespec t0, t1;
	struct itimerspec it, oit;
	int status = 0;

	if (timer_create(CLOCK_MONOTONIC, NULL, &t) == -1)
		err(1, "timer_create");
	if (clock_gettime(CLOCK_MONOTONIC, &t0) == -1)
		err(1, "clock_gettime");
	t1 = t0;
	t1.tv_sec += 1;
	it.it_value = t1;
	it.it_interval = (struct timespec){0,0};
	if (timer_settime(t, TIMER_ABSTIME, &it, NULL) == -1)
		err(1, "timer_settime 1");
	if (timer_settime(t, TIMER_ABSTIME, &it, &oit) == -1)
		err(1, "timer_settime 2");
	printf("timer_settime reports %llds %dns remaining\n",
	    (long long)oit.it_value.tv_sec, (int)oit.it_value.tv_nsec);
	status |= oit.it_value.tv_sec > 0; /* fail if remaining >1sec */
	if (timer_gettime(t, &oit) == -1)
		err(1, "timer_gettime");
	printf("timer_gettime reports %llds %dns remaining\n",
	    (long long)oit.it_value.tv_sec, (int)oit.it_value.tv_nsec);
	status |= oit.it_value.tv_sec > 0; /* fail if remaining >1sec */

	fflush(stdout);
	return ferror(stdout) | status;
}

Example output:

$ ./timer
timer_settime reports 4360366s 902110555ns remaining
timer_gettime reports 1s 95289ns remaining

(Also surprising: that timer_gettime reports a duration remaining greater than 1sec.)
>Fix:
Yes, please!

>Audit-Trail:
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/58917 CVS commit: src/tests/lib/libc/sys
Date: Wed, 18 Dec 2024 22:26:53 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Wed Dec 18 22:26:53 UTC 2024

 Modified Files:
 	src/tests/lib/libc/sys: t_timer_create.c

 Log Message:
 t_timer_create: Add some more test cases.

 PR kern/58917: timer_settime and timerfd_settime return absolute time
 of next event

 PR kern/58919: timer_settime fails to trigger for past times


 To generate a diff of this commit:
 cvs rdiff -u -r1.5 -r1.6 src/tests/lib/libc/sys/t_timer_create.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/58917 CVS commit: src/tests/lib/libc/sys
Date: Thu, 19 Dec 2024 20:11:03 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Thu Dec 19 20:11:03 UTC 2024

 Modified Files:
 	src/tests/lib/libc/sys: t_timerfd.c

 Log Message:
 t_timerfd: Test for timerfd_settime old_value.

 PR kern/58917: timer_settime and timerfd_settime return absolute time
 of next event


 To generate a diff of this commit:
 cvs rdiff -u -r1.8 -r1.9 src/tests/lib/libc/sys/t_timerfd.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/58917 CVS commit: src
Date: Thu, 19 Dec 2024 23:41:46 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Thu Dec 19 23:41:46 UTC 2024

 Modified Files:
 	src/sys/kern: kern_time.c
 	src/tests/lib/libc/sys: t_timer_create.c

 Log Message:
 timer_settime(2): Return relative duration remaining.

 Not absolute time of next event.

 PR kern/58917: timer_settime and timerfd_settime return absolute time
 of next event


 To generate a diff of this commit:
 cvs rdiff -u -r1.222 -r1.223 src/sys/kern/kern_time.c
 cvs rdiff -u -r1.8 -r1.9 src/tests/lib/libc/sys/t_timer_create.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/58917 CVS commit: src
Date: Thu, 19 Dec 2024 23:50:23 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Thu Dec 19 23:50:23 UTC 2024

 Modified Files:
 	src/sys/kern: sys_timerfd.c
 	src/tests/lib/libc/sys: t_timerfd.c

 Log Message:
 timerfd_settime(2): Return relative duration remaining.

 Not absolute time of next event.

 PR kern/58917: timer_settime and timerfd_settime return absolute time
 of next event


 To generate a diff of this commit:
 cvs rdiff -u -r1.10 -r1.11 src/sys/kern/sys_timerfd.c
 cvs rdiff -u -r1.10 -r1.11 src/tests/lib/libc/sys/t_timerfd.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2024 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.