From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 555DD3856944; Fri, 16 Jun 2023 02:51:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 555DD3856944 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1686883914; bh=EMgwUx5ntus7nV+PFoGQqcep9W2Te/eW4zNMP4JoOdk=; h=From:To:Subject:Date:From; b=HXrxTPye24NhFXz51J5UVZEHm0sRvbB4TV9FB+Dmkli6RjbP/eY9sVacrFVKhESvI lVZ+BQUhYGdWie/G7Hi2mTha3WuhfpWrtek1uh3g5KJFrGSdLiw8+tsbBm7jZBZUfr eiJNqyAiCED+ZcSop8/RSUc+R0mWUcow0RbjSCoo= From: "vladimir.mezentsev at oracle dot com" To: glibc-bugs@sourceware.org Subject: [Bug time/30559] New: setitimer works incorrectly Date: Fri, 16 Jun 2023 02:51:53 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: glibc X-Bugzilla-Component: time X-Bugzilla-Version: unspecified X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: vladimir.mezentsev at oracle dot com X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at sourceware dot org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://sourceware.org/bugzilla/show_bug.cgi?id=3D30559 Bug ID: 30559 Summary: setitimer works incorrectly Product: glibc Version: unspecified Status: NEW Severity: normal Priority: P2 Component: time Assignee: unassigned at sourceware dot org Reporter: vladimir.mezentsev at oracle dot com Target Milestone: --- A small test below shows the problem with the itimer setting: % cat sig.c #include #include #include #include #include #include #ifndef MY_TIMER #define MY_TIMER 1000 #endif static time_t start; static int sigprof_cnt =3D 0; time_t gethrtime (void) { struct timespec tp; time_t rc =3D 0; int r =3D clock_gettime (CLOCK_MONOTONIC, &tp); if (r =3D=3D 0) rc =3D ((time_t) tp.tv_sec) * 1e9 + (time_t) tp.tv_nsec; return rc; } static void sigprof_handler(int signo, siginfo_t* info, void *context) { if (++sigprof_cnt >=3D 3) exit(0); static struct itimerval t; memset(&t, 0, sizeof(t)); if (getitimer(ITIMER_PROF, &t) !=3D 0) printf("getitimer failed\n"); printf("sigprof_handler: it_interval.tv_sec=3D%lld it_interval.tv_usec=3D= %lld\n" " it_value.tv_sec=3D%lld it_value.tv_usec=3D%ll= d\n", (long long) t.it_interval.tv_sec, (long long) t.it_interval.tv_usec, (long long) t.it_value.tv_sec, (long long) t.it_value.tv_usec); } volatile long x; /* temp variable for long calculation */ int main (int argc, char **argv) { long long count =3D 0; start =3D gethrtime (); struct sigaction sa; memset(&sa, 0, sizeof(struct sigaction)); sa.sa_sigaction =3D sigprof_handler; sa.sa_flags =3D SA_RESTART | SA_SIGINFO; sigemptyset(&sa.sa_mask); if (sigaction(SIGPROF, &sa, NULL) =3D=3D -1) { perror("sigaction"); return 1; } static struct itimerval timer; memset(&timer, 0, sizeof(timer)); timer.it_interval.tv_usec =3D MY_TIMER; timer.it_value.tv_usec =3D MY_TIMER; if (setitimer(ITIMER_PROF, &timer, NULL) !=3D 0) { printf("Timer could not be initialized \n"); return 1; } struct itimerval t; memset(&t, 0, sizeof(t)); if (getitimer(ITIMER_PROF, &t) !=3D 0) { printf("getitimer failed\n"); return 1; } printf("After setitimer: it_interval.tv_sec=3D%lld it_interval.tv_usec=3D= %lld\n" " it_value.tv_sec=3D%lld it_value.tv_usec=3D%ll= d\n", (long long) t.it_interval.tv_sec, (long long) t.it_interval.tv_usec, (long long) t.it_value.tv_sec, (long long) t.it_value.tv_usec); do { x =3D 0; for (int j =3D 0; j < 1000000; j++) x =3D x + 1; count++; } while (start + 1e9 / 4 > gethrtime ()); printf("count=3D%lld x=3D%lld\n", count, x); return 0; } It is from man page: % man setitimer ... setitimer() If either field in new_value.it_value is nonzero, then the timer is = arme to initially expire at the specified time. But this is not right on x86_64 and aarch64. I run this test on OL8. On x86_64 / OL8: % gcc -DMY_TIMER=3D1000 sig.c; ./a.out After setitimer: it_interval.tv_sec=3D0 it_interval.tv_usec=3D1000 it_value.tv_sec=3D0 it_value.tv_usec=3D2000 <<<<<<= this should be <=3D 1000 because I set it_value.tv_usec to 1000 in setitimer sigprof_handler: it_interval.tv_sec=3D0 it_interval.tv_usec=3D1000 it_value.tv_sec=3D0 it_value.tv_usec=3D23 sigprof_handler: it_interval.tv_sec=3D0 it_interval.tv_usec=3D1000 it_value.tv_sec=3D0 it_value.tv_usec=3D27 On aarch64 / OL8: % gcc -DMY_TIMER=3D1000 sig.c; ./a.out After setitimer: it_interval.tv_sec=3D0 it_interval.tv_usec=3D1000 it_value.tv_sec=3D0 it_value.tv_usec=3D5000 <<<<<< S= ame as on x86_64 sigprof_handler: it_interval.tv_sec=3D0 it_interval.tv_usec=3D1000 it_value.tv_sec=3D0 it_value.tv_usec=3D4000 <<<<<< this= must be <=3D 1000 because it_interval.tv_usec is 1000 sigprof_handler: it_interval.tv_sec=3D0 it_interval.tv_usec=3D1000 it_value.tv_sec=3D0 it_value.tv_usec=3D4000<<<<<< = this must be <=3D 1000 because it_interval.tv_usec is 1000 --=20 You are receiving this mail because: You are on the CC list for the bug.=