RE: [PATCH 1/2] Support for setitimer() on platforms lacking it

2012-09-05 Thread Joachim Schmitz
 From: Junio C Hamano [mailto:gits...@pobox.com]
 Sent: Wednesday, September 05, 2012 12:45 AM
 To: Joachim Schmitz
 Cc: git@vger.kernel.org; 'Johannes Sixt'
 Subject: Re: [PATCH 1/2] Support for setitimer() on platforms lacking it
 
 Joachim Schmitz j...@schmitz-digital.de writes:
 
  From: Junio C Hamano [mailto:gits...@pobox.com]
  Sent: Tuesday, September 04, 2012 8:47 PM
  To: Joachim Schmitz
  Cc: git@vger.kernel.org; 'Johannes Sixt'
  Subject: Re: [PATCH 1/2] Support for setitimer() on platforms lacking it
 
  Junio C Hamano gits...@pobox.com writes:
 
   Joachim Schmitz j...@schmitz-digital.de writes:
  
   Only with the observation of clone, I cannot tell if your timer is
   working.  You can try repacking the test repository you created by
   your earlier git clone with git repack -a -d -f and see what
   happens.
  
   It does update the counter too.
  
   Yeah, that was not a very good way to diagnose it.
  
   You see the progress from pack-objects (which is the underlying
   machinery git repack uses) only because it knows how many objects
   it is going to pack, and it updates the progress meter for every
   per-cent progress it makes, without any help from the timer
   interrupt.
 
  I think the Counting objects: $number phase is purely driven by
  the timer, as there is no way to say we are done X per-cent so
  far.
 
  Doesn't your repack show Counting objects:  with a number once,
  pause forever and then show Counting objects: $number, done.?
 
  Yes, only once, when it is done
  $ ./git repack -a -d -f
  warning: no threads support, ignoring --threads
  Counting objects: 140302, done.
  Compressing objects:   1% (1385/138407)
 
 So this strongly suggests that (1) your poor-man's is not a real
 substitute for recurring itimer, and (2) users could live with the
 progress.c code without any itimer firing.

OK

 Perhaps a no-op macro would work equally well?

Like the following:

diff --git a/git-compat-util.h b/git-compat-util.h
index 18089f0..55b9421 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h@@ -163,6 +163,10 @@
 #define probe_utf8_pathname_composition(a,b)
 #endif

+#ifdef NO_SETITIMER
+#define setitimer(w,v,o) /* NOP */
+#endif
+
 #ifdef MKDIR_WO_TRAILING_SLASH
 #define mkdir(a,b) compat_mkdir_wo_trailing_slash((a),(b))
 extern int compat_mkdir_wo_trailing_slash(const char*, mode_t);

Does work for me and does not seem to make any difference, not in those test 
cases at least

Does the inability to re-arm the timer depend on SA_RESTART, possibly?
If so we may instead want 
#if SA_RSTART == 0   defined(NO_SETITIMER)

Bye, Jojo

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] Support for setitimer() on platforms lacking it

2012-09-04 Thread Junio C Hamano
Joachim Schmitz j...@schmitz-digital.de writes:

 Only with the observation of clone, I cannot tell if your timer is
 working.  You can try repacking the test repository you created by
 your earlier git clone with git repack -a -d -f and see what
 happens.

 It does update the counter too.

Yeah, that was not a very good way to diagnose it.

You see the progress from pack-objects (which is the underlying
machinery git repack uses) only because it knows how many objects
it is going to pack, and it updates the progress meter for every
per-cent progress it makes, without any help from the timer
interrupt.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] Support for setitimer() on platforms lacking it

2012-09-04 Thread Junio C Hamano
Junio C Hamano gits...@pobox.com writes:

 Joachim Schmitz j...@schmitz-digital.de writes:

 Only with the observation of clone, I cannot tell if your timer is
 working.  You can try repacking the test repository you created by
 your earlier git clone with git repack -a -d -f and see what
 happens.

 It does update the counter too.

 Yeah, that was not a very good way to diagnose it.

 You see the progress from pack-objects (which is the underlying
 machinery git repack uses) only because it knows how many objects
 it is going to pack, and it updates the progress meter for every
 per-cent progress it makes, without any help from the timer
 interrupt.

I think the Counting objects: $number phase is purely driven by
the timer, as there is no way to say we are done X per-cent so
far.

Doesn't your repack show Counting objects:  with a number once,
pause forever and then show Counting objects: $number, done.?


--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] Support for setitimer() on platforms lacking it

2012-09-04 Thread Johannes Sixt
Am 04.09.2012 19:23, schrieb Joachim Schmitz:
 From: Junio C Hamano [mailto:gits...@pobox.com]
 Only with the observation of clone, I cannot tell if your timer is
 working.  You can try repacking the test repository you created by
 your earlier git clone with git repack -a -d -f and see what
 happens.
 
 It does update the counter too.

Last time I looked at the progress code, it updated the progress text
also every time the percent value changed. If you have a large count or
large objects such that it takes more than a second to increase the
percentage, than you don't get a smooth progress. Nor do you for phases
that do not have a percentage, like the counting objects phase of
pack-objects.

-- Hannes

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 1/2] Support for setitimer() on platforms lacking it

2012-09-04 Thread Joachim Schmitz
 From: Junio C Hamano [mailto:gits...@pobox.com]
 Sent: Tuesday, September 04, 2012 8:47 PM
 To: Joachim Schmitz
 Cc: git@vger.kernel.org; 'Johannes Sixt'
 Subject: Re: [PATCH 1/2] Support for setitimer() on platforms lacking it
 
 Junio C Hamano gits...@pobox.com writes:
 
  Joachim Schmitz j...@schmitz-digital.de writes:
 
  Only with the observation of clone, I cannot tell if your timer is
  working.  You can try repacking the test repository you created by
  your earlier git clone with git repack -a -d -f and see what
  happens.
 
  It does update the counter too.
 
  Yeah, that was not a very good way to diagnose it.
 
  You see the progress from pack-objects (which is the underlying
  machinery git repack uses) only because it knows how many objects
  it is going to pack, and it updates the progress meter for every
  per-cent progress it makes, without any help from the timer
  interrupt.
 
 I think the Counting objects: $number phase is purely driven by
 the timer, as there is no way to say we are done X per-cent so
 far.
 
 Doesn't your repack show Counting objects:  with a number once,
 pause forever and then show Counting objects: $number, done.?

Yes, only once, when it is done
$ ./git repack -a -d -f
warning: no threads support, ignoring --threads
Counting objects: 140302, done.
Compressing objects:   1% (1385/138407)

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] Support for setitimer() on platforms lacking it

2012-09-04 Thread Junio C Hamano
Joachim Schmitz j...@schmitz-digital.de writes:

 From: Junio C Hamano [mailto:gits...@pobox.com]
 Sent: Tuesday, September 04, 2012 8:47 PM
 To: Joachim Schmitz
 Cc: git@vger.kernel.org; 'Johannes Sixt'
 Subject: Re: [PATCH 1/2] Support for setitimer() on platforms lacking it
 
 Junio C Hamano gits...@pobox.com writes:
 
  Joachim Schmitz j...@schmitz-digital.de writes:
 
  Only with the observation of clone, I cannot tell if your timer is
  working.  You can try repacking the test repository you created by
  your earlier git clone with git repack -a -d -f and see what
  happens.
 
  It does update the counter too.
 
  Yeah, that was not a very good way to diagnose it.
 
  You see the progress from pack-objects (which is the underlying
  machinery git repack uses) only because it knows how many objects
  it is going to pack, and it updates the progress meter for every
  per-cent progress it makes, without any help from the timer
  interrupt.
 
 I think the Counting objects: $number phase is purely driven by
 the timer, as there is no way to say we are done X per-cent so
 far.
 
 Doesn't your repack show Counting objects:  with a number once,
 pause forever and then show Counting objects: $number, done.?

 Yes, only once, when it is done
 $ ./git repack -a -d -f
 warning: no threads support, ignoring --threads
 Counting objects: 140302, done.
 Compressing objects:   1% (1385/138407)

So this strongly suggests that (1) your poor-man's is not a real
substitute for recurring itimer, and (2) users could live with the
progress.c code without any itimer firing.

Perhaps a no-op macro would work equally well?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 1/2] Support for setitimer() on platforms lacking it

2012-09-03 Thread Joachim Schmitz
 From: Junio C Hamano [mailto:gits...@pobox.com]
 Sent: Sunday, September 02, 2012 10:44 PM
 To: Joachim Schmitz
 Cc: git@vger.kernel.org; Johannes Sixt
 Subject: Re: [PATCH 1/2] Support for setitimer() on platforms lacking it
 
 Joachim Schmitz j...@schmitz-digital.de writes:
 
Should we leave tv_usec untouched then? That was we round up on
the next (and subsequent?) round(s). Or just set to ENOTSUP in
setitimer if ovalue is !NULL?
  
   I was alluding to the latter.
 
  OK, will do that then.
 
 Thanks.
 
  Unless I screwed up the operator precedence?
 
 I think you did, but not in the version we see below.
 
  int git_setitimer(int which, const struct itimerval *value,
  struct itimerval *ovalue)
  {
  int ret = 0;
 
  if (!value ) {
 
 Style: space before ')'?

Will fix.
 
  errno = EFAULT;
  return -1;
 
 EFAULT is good ;-)

That's what 'man setitimer()' on Linux says to happen if invalid value is found.
 
 The emulation in mingw.c 6072fc3 (Windows: Implement setitimer() and
 sigaction()., 2007-11-13) may want to be tightened in a similar way.


Hmm, I see that there the errors are handled differently, like this:

if (ovalue != NULL)
return errno = EINVAL,
error(setitimer param 3 != NULL not implemented);

Should this be done in my setitimer() too? Or rather be left to the caller?
I tend to the later.

  }
 
  if ( value-it_value.tv_sec  0
 
 Style: space after ')'?

After '(', I guess? Will fix.
 
  || value-it_value.tv_usec  100
  || value-it_value.tv_usec  0) {
  errno = EINVAL;
  return -1;
  }
 
  if ((ovalue)  (git_getitimer(which, ovalue) == -1))
  return -1; /* errno set in git_getitimer() */
 
 As nobody passes non-NULL ovalue to setitimer(), I think we should
 instead get rid of git_getitmier() implemenation, and change this to

True.
 
   if (ovalue) {
   errno = ENOTSUP;
 return -1;
   }

 which is how I understood what the latter in the paragraph I
 quoted from you above meant.

OK, will do this and then I'll rename the entire file into getitimer.c.
 
  switch (which) {
  case ITIMER_REAL:
   /* If tv_usec is  0, round up to next full sec */
  alarm(value-it_value.tv_sec + (value-it_value.tv_usec  0));
 
 OK.
 
  ret = 0; /* if alarm() fails, we get a SIGLIMIT */
  break;
  case ITIMER_VIRTUAL:
  case ITIMER_PROF:
  errno = ENOTSUP;
  ret = -1;
  break;
  default:
  errno = EINVAL;
  ret = -1;
  break;
  }
 
  return ret;
  }
 
 Other than that, looks good.
 
 Thanks.

I had a closer look at the places in git where setitimer() is used. It is in 2 
files, progress.c and builtin/log.c.
In progress.c :
static void set_progress_signal(void)
{
struct sigaction sa;
struct itimerval v;

progress_update = 0;

memset(sa, 0, sizeof(sa));
sa.sa_handler = progress_interval;
sigemptyset(sa.sa_mask);
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);
}

static void clear_progress_signal(void)
{
struct itimerval v = {{0,},};
setitimer(ITIMER_REAL, v, NULL);
signal(SIGALRM, SIG_IGN);
progress_update = 0;
}

So it uses a 1 sec timeout, which is a good match to my implementation, but 
also uses it_interval, meant to 're-arm' the timer after
it expired.
My implementation doesn't do that at all, and I also don't see how it possibly 
could (short of installing a signal handler, which
then conflicts with the one use in progress.c).
On top here SA_RESTART is used, which is not available in HP NonStop (so I have 
a -DSA_RESTART=0 in COMPAT_CFLAGS).

In builtin/log.c it doesn't use it_interval, which is a good match to my 
implementation, but uses 1/2 a sec and 1/10 sec, so here
would be a victim of a 1 sec upgrade. This is probably acceptable.
...
 * NOTE! We don't use it_interval, because if the
 * reader isn't listening, we want our output to be
 * throttled by the writing, and not have the timer
 * 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 = 50;
setitimer(ITIMER_REAL, early_output_timer, NULL);
...
static void setup_early_output(struct rev_info *rev)
{
struct sigaction sa;

/*
 * Set up the signal handler, minimally intrusively:
 * we only set a single volatile integer word (not
 * using sigatomic_t - trying to avoid unnecessary
 * system dependencies and headers

Re: [PATCH 1/2] Support for setitimer() on platforms lacking it

2012-09-03 Thread Junio C Hamano
Johannes Sixt j...@kdbg.org writes:

 Am 03.09.2012 11:31, schrieb Joachim Schmitz:
 
 Hmm, I see that there the errors are handled differently, like this:
 
 if (ovalue != NULL)
 return errno = EINVAL,
 error(setitimer param 3 != NULL not implemented);
 
 Should this be done in my setitimer() too? Or rather be left to the caller?
 I tend to the later.

 The error message is really just a reminder that the implementation is
 not complete. Writing it here has the advantage that it is much more
 accurate than a generic invalid argument or operation not supported
 error that the caller would be able to write.

Joachim quoted irrelevant (to you) part and made comments on it, but
the issue I raised by Ccing you was about diagnosing NULL passed in
newvalue parameter, which Joachim's code did like this:

 int git_setitimer(int which, const struct itimerval *value,
   struct itimerval *ovalue)
 {
   int ret = 0;

   if (!value ) {
   errno = EFAULT;
   return -1;

EFAULT is good ;-)

The emulation in mingw.c 6072fc3 (Windows: Implement setitimer() and
sigaction()., 2007-11-13) may want to be tightened in a similar way.

but mingw.c doesn't seem to.

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] Support for setitimer() on platforms lacking it

2012-09-03 Thread Junio C Hamano
Joachim Schmitz j...@schmitz-digital.de writes:

 if (!value ) {
 
 Style: space before ')'?

 Will fix.
  
 errno = EFAULT;
 return -1;
 
 EFAULT is good ;-)

 That's what 'man setitimer()' on Linux says to happen if invalid value is 
 found.
  
 The emulation in mingw.c 6072fc3 (Windows: Implement setitimer() and
 sigaction()., 2007-11-13) may want to be tightened in a similar way.


 Hmm, I see that there the errors are handled differently, like this:

 if (ovalue != NULL)
 return errno = EINVAL,
 error(setitimer param 3 != NULL not implemented);

 Should this be done in my setitimer() too? Or rather be left to the caller?
 I tend to the later.

I don't care too deeply either way.  The above was not a comment
meant for you, but was to point out the error checking when the
newvalue is NULL---it is missing in mingw.c and I think the
condition should be checked.

 On top here SA_RESTART is used, which is not available in HP
 NonStop (so I have a -DSA_RESTART=0 in COMPAT_CFLAGS).

If you cannot re-trigger the timer, then you will see 20% shown
after one second, silence for 4 seconds and then done, for an
operation that takes 5 seconds.  Which is not the end of the world,
though.  It does not affect correctness.

The other use of itimer in our codebase is the early-output timer,
but that also is about perceived latency, and not about correctness,
so it is possible that you do not have to support anything (i.e. not
even setting an alarm) at all.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 1/2] Support for setitimer() on platforms lacking it

2012-09-03 Thread Joachim Schmitz
 From: Junio C Hamano [mailto:gits...@pobox.com]
 Sent: Monday, September 03, 2012 9:03 PM
 To: Joachim Schmitz
 Cc: git@vger.kernel.org; 'Johannes Sixt'
 Subject: Re: [PATCH 1/2] Support for setitimer() on platforms lacking it
 
 Joachim Schmitz j...@schmitz-digital.de writes:
 
if (!value ) {
 
  Style: space before ')'?
 
  Will fix.
 
errno = EFAULT;
return -1;
 
  EFAULT is good ;-)
 
  That's what 'man setitimer()' on Linux says to happen if invalid value is 
  found.
 
  The emulation in mingw.c 6072fc3 (Windows: Implement setitimer() and
  sigaction()., 2007-11-13) may want to be tightened in a similar way.
 
 
  Hmm, I see that there the errors are handled differently, like this:
 
  if (ovalue != NULL)
  return errno = EINVAL,
  error(setitimer param 3 != NULL not implemented);
 
  Should this be done in my setitimer() too? Or rather be left to the caller?
  I tend to the later.
 
 I don't care too deeply either way.  The above was not a comment
 meant for you, but was to point out the error checking when the
 newvalue is NULL---it is missing in mingw.c and I think the
 condition should be checked.

 Ah, OK. Guess Johannes and I misunderstood ;-)

  On top here SA_RESTART is used, which is not available in HP
  NonStop (so I have a -DSA_RESTART=0 in COMPAT_CFLAGS).
 
 If you cannot re-trigger the timer, then you will see 20% shown
 after one second, silence for 4 seconds and then done, for an
 operation that takes 5 seconds.  Which is not the end of the world,
 though.  It does not affect correctness.

That does seem to work, if I do e.g. a git clone on git itself (being a 
fairly large repository), I see it updating the % values
about once per second.

 The other use of itimer in our codebase is the early-output timer,
 but that also is about perceived latency, and not about correctness,
 so it is possible that you do not have to support anything (i.e. not
 even setting an alarm) at all.

OK, I'll go for that one-liner in git-compat-utils.h then

#ifdef NO_SETITIMER /* poor man's setitimer() */
#define setitimer(w,v,o) alarm((v)-it_value.tv_sec+((v)-it_value.tv_usec0))
#endif

It certainly seems to work just fine for me.
Could as well be #ifdef __TANDEM, I won't mind.

Bye, Jojo

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 1/2] Support for setitimer() on platforms lacking it

2012-09-01 Thread Joachim Schmitz
 From: Joachim Schmitz [mailto:j...@schmitz-digital.de]
 Sent: Thursday, August 30, 2012 7:23 PM
 To: 'Junio C Hamano'
 Cc: 'git@vger.kernel.org'
 Subject: RE: [PATCH 1/2] Support for setitimer() on platforms lacking it
 
  From: Junio C Hamano [mailto:gits...@pobox.com]
  Sent: Thursday, August 30, 2012 7:14 PM
  To: Joachim Schmitz
  Cc: git@vger.kernel.org
  Subject: Re: [PATCH 1/2] Support for setitimer() on platforms lacking it
 
  Joachim Schmitz j...@schmitz-digital.de writes:
 
   I see no existing code calls setitimer() with non-NULL ovalue, and I
   do not think we would add a new caller that would do so in any time
   soon, so it may not be a bad idea to drop support of returning the
   remaining timer altogether from this emulation layer (just like
   giving anything other than ITIMER_REAL gives us ENOTSUP).  That
   would sidestep the whole we cannot answer how many milliseconds are
   still remaining on the timer when using emulation based on alarm().
  
   Should we leave tv_usec untouched then? That was we round up on
   the next (and subsequent?) round(s). Or just set to ENOTSUP in
   setitimer if ovalue is !NULL?
 
  I was alluding to the latter.
 
 OK, will do that then.
 
+  switch (which) {
+  case ITIMER_REAL:
+  alarm(value-it_value.tv_sec +
+  (value-it_value.tv_usec  0) ? 1 : 0);
  
   Why is this capped to 1 second?  Is this because no existing code
   uses the timer for anything other than 1 second or shorter?  If that
   is the case, that needs at least some documenting (or a possibly
   support for longer expiration, if it is not too cumbersome to add).
  
   As you mention alarm() has only seconds resolution. It is tv_sec
   plus 1 if there are tv_usecs  0, it is rounding up, so we don't
   cancel the alarm() if tv_sec is 0 but tv_usec is not. Looks OK to
   me?
 
  Can a caller use setitimer to be notified in 5 seconds?
 
 Yes, by setting tv_sec to 5 and tv_usec to 0, or be setting tv_sec to 4 and 
 tv_usec to something  0.
 
 Unless I screwed up the operator precedence?
 To make it clearer (any possibly correct?):
 
   switch (which) {
   case ITIMER_REAL:
   alarm(value-it_value.tv_sec +
   ((value-it_value.tv_usec  0) ? 1 : 0));
 
 Or even just
   switch (which) {
   case ITIMER_REAL:
   alarm(value-it_value.tv_sec + (value-it_value.tv_usec 
  0));

OK, here it goes again, not yet as a patch, just plain code for comment:

$ cat itimer.c
/* 
 * Rely on system headers (sys/time.h) to contain struct itimerval
 * and git-compat-util.h to have the prototype for git_getitimer().
 * As soon as there's a platform where that is not the case, we'd need
 * an itimer .h.
 */
#include ../git-compat-util.h

#ifndef NO_GETITIMER /* not yet needed anywhere else in git */
static
#endif
int git_getitimer(int which, struct itimerval *value)
{
int ret = 0;

if (!value) {
errno = EFAULT;
return -1;
}

switch (which) {
case ITIMER_REAL:
#if 0
value-it_value.tv_usec = 0;
value-it_value.tv_sec = alarm(0);
ret = 0; /* if alarm() fails, we get a SIGLIMIT */
break;
#else
/*
 * As an emulation via alarm(0) won't tell us how many
 * usecs are left, we don't support it altogether.
 */
#endif
case ITIMER_VIRTUAL:
case ITIMER_PROF:
errno = ENOTSUP;
ret = -1;
break;
default:
errno = EINVAL;
ret = -1;
break;
}
return ret;
}

int git_setitimer(int which, const struct itimerval *value,
struct itimerval *ovalue)
{
int ret = 0;

if (!value ) {
errno = EFAULT;
return -1;
}

if ( value-it_value.tv_sec  0
|| value-it_value.tv_usec  100
|| value-it_value.tv_usec  0) {
errno = EINVAL;
return -1;
}

if ((ovalue)  (git_getitimer(which, ovalue) == -1))
return -1; /* errno set in git_getitimer() */

switch (which) {
case ITIMER_REAL:
 /* If tv_usec is  0, round up to next full sec */
alarm(value-it_value.tv_sec + (value-it_value.tv_usec  0));
ret = 0; /* if alarm() fails, we get a SIGLIMIT */
break;
case ITIMER_VIRTUAL:
case ITIMER_PROF:
errno = ENOTSUP;
ret = -1;
break;
default:
errno = EINVAL;
ret = -1;
break;
}

return ret;
}

Would this pass muster? The previous version had a bug too, of ovalue was !NULL

RE: [PATCH 1/2] Support for setitimer() on platforms lacking it

2012-08-30 Thread Joachim Schmitz
 From: Junio C Hamano [mailto:gits...@pobox.com]
 Sent: Tuesday, August 28, 2012 10:16 PM
 To: Joachim Schmitz
 Cc: git@vger.kernel.org
 Subject: Re: [PATCH 1/2] Support for setitimer() on platforms lacking it
 
 Joachim Schmitz j...@schmitz-digital.de writes:
 
  Implementation includes getitimer(), but for now it is static.
  Supports ITIMER_REAL only.
 
  Signed-off-by: Joachim Schmitz j...@schmitz-digital.de
  ---
  May need a header file for ITIMER_*, struct itimerval and the prototypes,
  But for now, and the HP NonStop platform this isn't needed, here
  sys/time has ITIMER_* and struct timeval, and the prototypes can
  vo into git-compat-util.h for now (Patch 2/2)
 
   compat/itimer.c | 50 ++
   1 file changed, 50 insertions(+)
   create mode 100644 compat/itimer.c
 
  diff --git a/compat/itimer.c b/compat/itimer.c
  new file mode 100644
  index 000..713f1ff
  --- /dev/null
  +++ b/compat/itimer.c
  @@ -0,0 +1,50 @@
  +#include ../git-compat-util.h
  +
  +static int git_getitimer(int which, struct itimerval *value)
  +{
  +   int ret = 0;
  +
  +   switch (which) {
  +   case ITIMER_REAL:
  +   value-it_value.tv_usec = 0;
  +   value-it_value.tv_sec = alarm(0);
  +   ret = 0; /* if alarm() fails, we get a SIGLIMIT */
  +   break;
  +   case ITIMER_VIRTUAL: /* FALLTHRU */
  +   case ITIMER_PROF: errno = ENOTSUP; ret = -1; break;
  +   default: errno = EINVAL; ret = -1;
  +   }
 
 Just a style thing, but we align case arms and switch statements,
 like this:
 
   switch (which) {
 case ...:
   stmt;
 break;
   default:
   stmt;
 break;
   }

OK, I'll fix the syle

 Because alarm() runs in integral seconds granularity, this could
 return 0.0 sec (i.e. do not re-trigger this alarm any more) in
 ovalue after setting alarm(1) (via git_setitimer()) and calling this
 function (via git_setitimer() again) before the timer expires, no?
 Is it a desired behaviour?

Unintentional, never really thought about this.
 
 What I am most worried about is that callers _might_ take this
 emulation too seriously, grab the remainder from getitimer(), and
 drives a future call to getitimer() with the returned value, and
 accidentally cause the recurring nature of the request to be
 disabled.
 
 I see no existing code calls setitimer() with non-NULL ovalue, and I
 do not think we would add a new caller that would do so in any time
 soon, so it may not be a bad idea to drop support of returning the
 remaining timer altogether from this emulation layer (just like
 giving anything other than ITIMER_REAL gives us ENOTSUP).  That
 would sidestep the whole we cannot answer how many milliseconds are
 still remaining on the timer when using emulation based on alarm().

Should we leave tv_usec untouched then? That was we round up on the next (and 
subsequent?) round(s). Or just set to ENOTSUP in
setitimer if ovalue is !NULL?

  +int git_setitimer(int which, const struct itimerval *value,
  +   struct itimerval *ovalue)
  +{
  +   int ret = 0;
  +
  +   if (!value
  +   || value-it_value.tv_usec  0
  +   || value-it_value.tv_usec  100
  +   || value-it_value.tv_sec  0) {
  +   errno = EINVAL;
  +   return -1;
  +   }
  +
  +   else if (ovalue)
  +   if (!git_getitimer(which, ovalue))
  +   return -1; /* errno set in git_getitimer() */
  +
  +   else
  +   switch (which) {
  +   case ITIMER_REAL:
  +   alarm(value-it_value.tv_sec +
  +   (value-it_value.tv_usec  0) ? 1 : 0);
 
 Why is this capped to 1 second?  Is this because no existing code
 uses the timer for anything other than 1 second or shorter?  If that
 is the case, that needs at least some documenting (or a possibly
 support for longer expiration, if it is not too cumbersome to add).

As you mention alarm() has only seconds resolution. It is tv_sec plus 1 if 
there are tv_usecs  0, it is rounding up, so we don't
cancel the alarm() if tv_sec is 0 but tv_usec is not. Looks OK to me?
 
  +   ret = 0; /* if alarm() fails, we get a SIGLIMIT */
  +   break;
  +   case ITIMER_VIRTUAL: /* FALLTHRU */
  +   case ITIMER_PROF: errno = ENOTSUP; ret = -1; break;
 
 Please don't add a misleading fallthru label here.  We do not say
 fallthru when two case arms do _exactly_ the same thing.  Only
 when the one arm does some pre-action before the common action, i.e.
 
   switch (which) {
 case one:
   do some thing specific to one;
 /* fallthru */
   case two:
   do some thing common between one and two;
   break;
   }
 
 we label it fallthru to make it clear to the readers that it is
 not missing a break

Re: [PATCH 1/2] Support for setitimer() on platforms lacking it

2012-08-30 Thread Junio C Hamano
Joachim Schmitz j...@schmitz-digital.de writes:

 I see no existing code calls setitimer() with non-NULL ovalue, and I
 do not think we would add a new caller that would do so in any time
 soon, so it may not be a bad idea to drop support of returning the
 remaining timer altogether from this emulation layer (just like
 giving anything other than ITIMER_REAL gives us ENOTSUP).  That
 would sidestep the whole we cannot answer how many milliseconds are
 still remaining on the timer when using emulation based on alarm().

 Should we leave tv_usec untouched then? That was we round up on
 the next (and subsequent?) round(s). Or just set to ENOTSUP in
 setitimer if ovalue is !NULL?

I was alluding to the latter.

  +  switch (which) {
  +  case ITIMER_REAL:
  +  alarm(value-it_value.tv_sec +
  +  (value-it_value.tv_usec  0) ? 1 : 0);
 
 Why is this capped to 1 second?  Is this because no existing code
 uses the timer for anything other than 1 second or shorter?  If that
 is the case, that needs at least some documenting (or a possibly
 support for longer expiration, if it is not too cumbersome to add).

 As you mention alarm() has only seconds resolution. It is tv_sec
 plus 1 if there are tv_usecs  0, it is rounding up, so we don't
 cancel the alarm() if tv_sec is 0 but tv_usec is not. Looks OK to
 me?

Can a caller use setitimer to be notified in 5 seconds?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] Support for setitimer() on platforms lacking it

2012-08-28 Thread Junio C Hamano
Joachim Schmitz j...@schmitz-digital.de writes:

 Implementation includes getitimer(), but for now it is static.
 Supports ITIMER_REAL only.

 Signed-off-by: Joachim Schmitz j...@schmitz-digital.de
 ---
 May need a header file for ITIMER_*, struct itimerval and the prototypes,
 But for now, and the HP NonStop platform this isn't needed, here
 sys/time has ITIMER_* and struct timeval, and the prototypes can 
 vo into git-compat-util.h for now (Patch 2/2) 

  compat/itimer.c | 50 ++
  1 file changed, 50 insertions(+)
  create mode 100644 compat/itimer.c

 diff --git a/compat/itimer.c b/compat/itimer.c
 new file mode 100644
 index 000..713f1ff
 --- /dev/null
 +++ b/compat/itimer.c
 @@ -0,0 +1,50 @@
 +#include ../git-compat-util.h
 +
 +static int git_getitimer(int which, struct itimerval *value)
 +{
 + int ret = 0;
 +
 + switch (which) {
 + case ITIMER_REAL:
 + value-it_value.tv_usec = 0;
 + value-it_value.tv_sec = alarm(0);
 + ret = 0; /* if alarm() fails, we get a SIGLIMIT */
 + break;
 + case ITIMER_VIRTUAL: /* FALLTHRU */
 + case ITIMER_PROF: errno = ENOTSUP; ret = -1; break;
 + default: errno = EINVAL; ret = -1;
 + }

Just a style thing, but we align case arms and switch statements,
like this:

switch (which) {
case ...:
stmt;
break;
default:
stmt;
break;
}

Because alarm() runs in integral seconds granularity, this could
return 0.0 sec (i.e. do not re-trigger this alarm any more) in
ovalue after setting alarm(1) (via git_setitimer()) and calling this
function (via git_setitimer() again) before the timer expires, no?
Is it a desired behaviour?

What I am most worried about is that callers _might_ take this
emulation too seriously, grab the remainder from getitimer(), and
drives a future call to getitimer() with the returned value, and
accidentally cause the recurring nature of the request to be
disabled.

I see no existing code calls setitimer() with non-NULL ovalue, and I
do not think we would add a new caller that would do so in any time
soon, so it may not be a bad idea to drop support of returning the
remaining timer altogether from this emulation layer (just like
giving anything other than ITIMER_REAL gives us ENOTSUP).  That
would sidestep the whole we cannot answer how many milliseconds are
still remaining on the timer when using emulation based on alarm().

 +int git_setitimer(int which, const struct itimerval *value,
 + struct itimerval *ovalue)
 +{
 + int ret = 0;
 +
 + if (!value
 + || value-it_value.tv_usec  0
 + || value-it_value.tv_usec  100
 + || value-it_value.tv_sec  0) {
 + errno = EINVAL;
 + return -1;
 + }
 +
 + else if (ovalue)
 + if (!git_getitimer(which, ovalue))
 + return -1; /* errno set in git_getitimer() */
 +
 + else
 + switch (which) {
 + case ITIMER_REAL:
 + alarm(value-it_value.tv_sec +
 + (value-it_value.tv_usec  0) ? 1 : 0);

Why is this capped to 1 second?  Is this because no existing code
uses the timer for anything other than 1 second or shorter?  If that
is the case, that needs at least some documenting (or a possibly
support for longer expiration, if it is not too cumbersome to add).

 + ret = 0; /* if alarm() fails, we get a SIGLIMIT */
 + break;
 + case ITIMER_VIRTUAL: /* FALLTHRU */
 + case ITIMER_PROF: errno = ENOTSUP; ret = -1; break;

Please don't add a misleading fallthru label here.  We do not say
fallthru when two case arms do _exactly_ the same thing.  Only
when the one arm does some pre-action before the common action, i.e.

switch (which) {
case one:
do some thing specific to one;
/* fallthru */
case two:
do some thing common between one and two;
break;
}

we label it fallthru to make it clear to the readers that it is
not missing a break but is deliberate.

 + default: errno = EINVAL; ret = -1;
 + }
 +
 + return ret;
 +}

Thanks.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] Support for setitimer() on platforms lacking it

2012-08-24 Thread Joachim Schmitz

Implementation includes getitimer(), but for now it is static.
Supports ITIMER_REAL only.

Signed-off-by: Joachim Schmitz j...@schmitz-digital.de
---
May need a header file for ITIMER_*, struct itimerval and the prototypes,
But for now, and the HP NonStop platform this isn't needed, here
sys/time has ITIMER_* and struct timeval, and the prototypes can 
vo into git-compat-util.h for now (Patch 2/2) 

 compat/itimer.c | 50 ++
 1 file changed, 50 insertions(+)
 create mode 100644 compat/itimer.c

diff --git a/compat/itimer.c b/compat/itimer.c
new file mode 100644
index 000..713f1ff
--- /dev/null
+++ b/compat/itimer.c
@@ -0,0 +1,50 @@
+#include ../git-compat-util.h
+
+static int git_getitimer(int which, struct itimerval *value)
+{
+   int ret = 0;
+
+   switch (which) {
+   case ITIMER_REAL:
+   value-it_value.tv_usec = 0;
+   value-it_value.tv_sec = alarm(0);
+   ret = 0; /* if alarm() fails, we get a SIGLIMIT */
+   break;
+   case ITIMER_VIRTUAL: /* FALLTHRU */
+   case ITIMER_PROF: errno = ENOTSUP; ret = -1; break;
+   default: errno = EINVAL; ret = -1;
+   }
+   return ret;
+}
+
+int git_setitimer(int which, const struct itimerval *value,
+   struct itimerval *ovalue)
+{
+   int ret = 0;
+
+   if (!value
+   || value-it_value.tv_usec  0
+   || value-it_value.tv_usec  100
+   || value-it_value.tv_sec  0) {
+   errno = EINVAL;
+   return -1;
+   }
+
+   else if (ovalue)
+   if (!git_getitimer(which, ovalue))
+   return -1; /* errno set in git_getitimer() */
+
+   else
+   switch (which) {
+   case ITIMER_REAL:
+   alarm(value-it_value.tv_sec +
+   (value-it_value.tv_usec  0) ? 1 : 0);
+   ret = 0; /* if alarm() fails, we get a SIGLIMIT */
+   break;
+   case ITIMER_VIRTUAL: /* FALLTHRU */
+   case ITIMER_PROF: errno = ENOTSUP; ret = -1; break;
+   default: errno = EINVAL; ret = -1;
+   }
+
+   return ret;
+}
-- 
1.7.12


--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html