git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jacob Keller <jacob.e.keller@intel.com>
To: git@vger.kernel.org
Cc: Jonas 'Sortie' Termansen <sortie@maxsi.org>,
	Jacob Keller <jacob.e.keller@intel.com>
Subject: [PATCH 9/9] Use timer_settime for new platforms
Date: Fri, 29 Aug 2014 09:42:41 -0700	[thread overview]
Message-ID: <1409330561-11806-9-git-send-email-jacob.e.keller@intel.com> (raw)
In-Reply-To: <1409330561-11806-1-git-send-email-jacob.e.keller@intel.com>

From: Jonas 'Sortie' Termansen <sortie@maxsi.org>

setitimer() is an obsolescent XSI interface and may be removed in a
future standard. Applications should use the core POSIX timer_settime()
instead.

It's important that code doesn't simply check if timer_settime is
available as it can give false positives. Some systems like contemporary
OpenBSD provides the function, but it unconditionally fails with ENOSYS
at runtime.

Clean up the progress reporting and change it to use timer_settime,
which will fall back to setitimer automatically if timer_settime is not
supported. (see git-compat-util.h for how it does this). If both
functions are not present, then git-compat-util.h provides replacements
which will always fail with ENOSYS.

The approach used here enables us to use a single API (timer_settime)
without having to worry about checking for #ifdefs or if blocks which
make it an unreadable nightmare. The major downside is for systems
without timer_settime support, they may fall back on a wrapped
implementation which could have subtle differences. This should be a
minor issue as almost all modern systems provide timer_settime support.

Note that this change means that git should never use setitimer on its
own now, as the fallback implementation of timer_settime assumes that it
is the sole user of ITIMER_REAL, and timer_delete will reset the
ITIMER_REAL.

Signed-off-by: Jonas 'Sortie' Termansen <sortie@maxsi.org>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
 builtin/log.c | 27 ++++++++++++++++++++-------
 progress.c    | 20 +++++++++++++-------
 2 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/builtin/log.c b/builtin/log.c
index 4389722b4b1e..a39e82d67eb3 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -229,7 +229,7 @@ static void show_early_header(struct rev_info *rev, const char *stage, int nr)
 	printf(_("Final output: %d %s\n"), nr, stage);
 }
 
-static struct itimerval early_output_timer;
+static timer_t early_output_timer;
 
 static void log_show_early(struct rev_info *revs, struct commit_list *list)
 {
@@ -271,9 +271,12 @@ static void log_show_early(struct rev_info *revs, struct commit_list *list)
 	 * trigger every second even if we're blocked on a
 	 * reader!
 	 */
-	early_output_timer.it_value.tv_sec = 0;
-	early_output_timer.it_value.tv_usec = 500000;
-	setitimer(ITIMER_REAL, &early_output_timer, NULL);
+	struct itimerspec value;
+	value.it_value.tv_sec = 0;
+	value.it_value.tv_nsec = 500000L * 1000L;
+	value.it_interval.tv_sec = 0;
+	value.it_interval.tv_nsec = 0;
+	timer_settime(early_output_timer, 0, &value, NULL);
 }
 
 static void early_output(int signal)
@@ -284,6 +287,7 @@ static void early_output(int signal)
 static void setup_early_output(struct rev_info *rev)
 {
 	struct sigaction sa;
+	struct sigevent sev;
 
 	/*
 	 * Set up the signal handler, minimally intrusively:
@@ -305,14 +309,23 @@ static void setup_early_output(struct rev_info *rev)
 	 *
 	 * This is a one-time-only trigger.
 	 */
-	early_output_timer.it_value.tv_sec = 0;
-	early_output_timer.it_value.tv_usec = 100000;
-	setitimer(ITIMER_REAL, &early_output_timer, NULL);
+	memset(&sev, 0, sizeof(sev));
+	sev.sigev_notify = SIGEV_SIGNAL;
+	sev.sigev_signo = SIGALRM;
+	timer_create(CLOCK_MONOTONIC, &sev, &early_output_timer);
+
+	struct itimerspec value;
+	value.it_value.tv_sec = 0;
+	value.it_value.tv_nsec = 100000L * 1000L;
+	value.it_interval.tv_sec = 0;
+	value.it_interval.tv_nsec = 0;
+	timer_settime(early_output_timer, 0, &value, NULL);
 }
 
 static void finish_early_output(struct rev_info *rev)
 {
 	int n = estimate_commit_count(rev, rev->commits);
+	timer_delete(early_output_timer);
 	signal(SIGALRM, SIG_IGN);
 	show_early_header(rev, "done", n);
 }
diff --git a/progress.c b/progress.c
index 412e6b1ecc36..7fe73df35625 100644
--- a/progress.c
+++ b/progress.c
@@ -38,6 +38,7 @@ struct progress {
 	struct throughput *throughput;
 };
 
+static timer_t progress_timer;
 static volatile sig_atomic_t progress_update;
 
 static void progress_interval(int signum)
@@ -48,7 +49,7 @@ static void progress_interval(int signum)
 static void set_progress_signal(void)
 {
 	struct sigaction sa;
-	struct itimerval v;
+	struct sigevent sev;
 
 	progress_update = 0;
 
@@ -58,16 +59,21 @@ static void set_progress_signal(void)
 	sa.sa_flags = SA_RESTART;
 	sigaction(SIGALRM, &sa, NULL);
 
-	v.it_interval.tv_sec = 1;
-	v.it_interval.tv_usec = 0;
-	v.it_value = v.it_interval;
-	setitimer(ITIMER_REAL, &v, NULL);
+	memset(&sev, 0, sizeof(sev));
+	sev.sigev_notify = SIGEV_SIGNAL;
+	sev.sigev_signo = SIGALRM;
+	timer_create(CLOCK_MONOTONIC, &sev, &progress_timer);
+
+	struct itimerspec value;
+	value.it_interval.tv_sec = 1;
+	value.it_interval.tv_nsec = 0;
+	value.it_value = value.it_interval;
+	timer_settime(progress_timer, 0, &value, NULL);
 }
 
 static void clear_progress_signal(void)
 {
-	struct itimerval v = {{0,},};
-	setitimer(ITIMER_REAL, &v, NULL);
+	timer_delete(progress_timer);
 	signal(SIGALRM, SIG_IGN);
 	progress_update = 0;
 }
-- 
2.0.1.475.g9b8d714

  parent reply	other threads:[~2014-08-29 16:43 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-29 16:42 [PATCH 1/9] git-compat-util.h: Add missing semicolon after struct itimerval Jacob Keller
2014-08-29 16:42 ` [PATCH 2/9] autoconf: Check for " Jacob Keller
2014-08-29 16:42 ` [PATCH 3/9] autoconf: Check for setitimer Jacob Keller
2014-08-29 16:42 ` [PATCH 4/9] autoconf: Check for timer_t Jacob Keller
2014-08-29 18:20   ` Jonas 'Sortie' Termansen
2014-08-29 16:42 ` [PATCH 5/9] autoconf: Check for struct timespec Jacob Keller
2014-08-29 16:42 ` [PATCH 6/9] autoconf: Check for struct sigevent Jacob Keller
2014-08-29 16:42 ` [PATCH 7/9] autoconf: Check for struct itimerspec Jacob Keller
2014-08-29 16:42 ` [PATCH 8/9] autoconf: Check for timer_settime Jacob Keller
2014-08-29 17:26   ` Johannes Sixt
2014-08-29 17:40     ` Keller, Jacob E
2014-09-10 15:33       ` Karsten Blees
2014-09-10 21:08         ` Junio C Hamano
2014-09-10 21:13           ` Keller, Jacob E
2014-08-29 16:42 ` Jacob Keller [this message]
2014-08-29 18:02   ` [PATCH 9/9] Use timer_settime for new platforms Junio C Hamano
2014-08-29 18:09     ` Keller, Jacob E
2014-08-29 18:12   ` Junio C Hamano
2014-08-29 16:48 ` [PATCH 1/9] git-compat-util.h: Add missing semicolon after struct itimerval Keller, Jacob E
2014-08-29 18:54   ` Jonas 'Sortie' Termansen
2014-08-29 19:07     ` Junio C Hamano
2014-08-29 19:43       ` Jonas 'Sortie' Termansen
2014-09-03  0:17         ` Keller, Jacob E
  -- strict thread matches above, loose matches on Subject: below --
2014-08-28  1:04 [PATCH 0/9] Use timer_settime for new platforms Jonas 'Sortie' Termansen
2014-08-28  1:04 ` [PATCH 9/9] " Jonas 'Sortie' Termansen
2014-08-28 19:43   ` Junio C Hamano
2014-08-29 16:11     ` Keller, Jacob E

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1409330561-11806-9-git-send-email-jacob.e.keller@intel.com \
    --to=jacob.e.keller@intel.com \
    --cc=git@vger.kernel.org \
    --cc=sortie@maxsi.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).