Message ID | 20230320230507.3932018-1-gitster@pobox.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] git-compat-util: use gettimeofday(2) for time(2) | expand |
Thanks, this looks good. As a matter of fact it almost precisely matches what I was about to email you. The only significant difference is that yours has "#define time(x) git_time(x)" whereas mine had "#define time git_time". Since Git never takes the address of 'time' the two macro definitions should have equivalent effects when used in Git.
Paul Eggert <eggert@cs.ucla.edu> writes: > Thanks, this looks good. As a matter of fact it almost precisely > matches what I was about to email you. The only significant difference > is that yours has "#define time(x) git_time(x)" whereas mine had > "#define time git_time". Since Git never takes the address of 'time' > the two macro definitions should have equivalent effects when used in > Git. That is a valid concern. Writing &time would not be caught by compilers, and you would not notice such a mistake until you run "nm -ug" on the result. On the other hand, straight token replacement will risk renaming variables and structure members, and I was not sure if we have such use of the identifier "time". As long as people do not use "time" and "git_time" at the same time as such identifiers, that would not be an issue (except for perhaps expecting to see them in debuggers). Writing "git_time" and "time" at the same time for identifiers not related to the time(2) function would not be caught by compilers, either, but it feels much less likely mistake we would make in the future, so let me drop (x) from the macro. Thanks.
On Mon, Mar 20, 2023 at 04:05:07PM -0700, Junio C Hamano wrote: [...] > higher-res methods like gettimeofday. Although strictly > speaking users should tolerate this behavuior because a A small typo: it should probably read "behavior" or "behaviour". [...]
Konstantin Khomoutov <kostix@bswap.ru> writes: > On Mon, Mar 20, 2023 at 04:05:07PM -0700, Junio C Hamano wrote: > > [...] >> higher-res methods like gettimeofday. Although strictly >> speaking users should tolerate this behavuior because a > > A small typo: it should probably read "behavior" or "behaviour". > > [...] Thanks.
On Mon, Mar 20, 2023 at 04:05:07PM -0700, Junio C Hamano wrote: > +#ifdef time > +#undef time > +#endif > +static inline time_t git_time(time_t *tloc) > +{ > + struct timeval tv; > + > + /* > + * Avoid time(NULL), which can disagree with gettimeofday(2) > + * and filesystem timestamps. > + */ > + gettimeofday(&tv, NULL); > + > + if (tloc) > + *tloc = tv.tv_sec; > + return tv.tv_sec; > +} > +#define time(x) git_time(x) This looks good to me, but I wanted to mention one alternative. If we are declaring that time() sucks and gettimeofday() is how to do it, then we could just use gettimeofday() everywhere, and add time() to banned.h to catch stragglers. It has two mild advantages: 1. gettimeofday() gives the callers extra resolution if they want it (though in practice I guess none of them really do) 2. It more directly describes what's going on, and we'd play fewer games with macros (though we may end up with a git_gettimeofday() wrapper if somebody doesn't support it; I really wonder about Windows here). The disadvantage is that it's longer to type, and that you have to declare a timeval in the caller. So maybe it's a dumb idea. -Peff
On Tue, Mar 21, 2023 at 02:22:52PM -0400, Jeff King wrote: > The disadvantage is that it's longer to type, and that you have to > declare a timeval in the caller. So maybe it's a dumb idea. I don't think it's a dumb idea per-se, but I think that being able to pass `time(NULL)` around without having to create a timeval and pass a pointer to *it* before then giving that timeval to some other function is a nice advantage. So, yeah, we probably should just avoid calling time() altogether, but in practice I like the solution of redefining time() to do the right thing and implement it by calling gettimeofday(). ...Which is a long way of saying that I agree with you that this approach looks good, and that I'd like to avoid putting time() in the list of banned functions. Thanks, Taylor
Jeff King <peff@peff.net> writes: > This looks good to me, but I wanted to mention one alternative. If we > are declaring that time() sucks and gettimeofday() is how to do it, then > we could just use gettimeofday() everywhere, and add time() to banned.h > to catch stragglers. > > It has two mild advantages: > > 1. gettimeofday() gives the callers extra resolution if they want it > (though in practice I guess none of them really do) True. Many of our data structures do not have room to store the extra resolution right now. > 2. It more directly describes what's going on, and we'd play fewer > games with macros (though we may end up with a git_gettimeofday() > wrapper if somebody doesn't support it; I really wonder about > Windows here). I think they already have a compat/ function for their use in compat/mingw.c so that may not be an issue. > The disadvantage is that it's longer to type, and that you have to > declare a timeval in the caller. So maybe it's a dumb idea. Yes, you have to declare and use a timeval, but you are already declaring and using time_t in today's code, so if we were writing like so from scratch, the result wouldn't have been so bad. We just do nto use time_t and use timeval instead consistently. The patch noise to go from here to there may not be worth it, though. Also, unless we are going to actively take advantage of extra resolution, I am not sure if it is wise to ask for extra resolution in the first place. If time(2), at least on some platforms whose maintainers care, gets corrected to avoid going backwards or being inconsistent with filesystem timestamp in the future, converting everything that calls time(2) to call gettimeofday(2) would lose information---we will want to know which ones need only seconds resolution and convert them back when the world advances. So, I am not quite sure I am sold on the idea of rewriting everything to use gettimeofday(2). Thanks.
On Tue, Mar 21, 2023 at 01:04:49PM -0700, Junio C Hamano wrote: > So, I am not quite sure I am sold on the idea of rewriting > everything to use gettimeofday(2). I'm not sure I am either. :) All your points are fair. Let's forget about my suggestion. -Peff
diff --git a/git-compat-util.h b/git-compat-util.h index 4f0028ce60..d6fbe9311d 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -339,6 +339,25 @@ static inline const char *precompose_string_if_needed(const char *in) int compat_mkdir_wo_trailing_slash(const char*, mode_t); #endif +#ifdef time +#undef time +#endif +static inline time_t git_time(time_t *tloc) +{ + struct timeval tv; + + /* + * Avoid time(NULL), which can disagree with gettimeofday(2) + * and filesystem timestamps. + */ + gettimeofday(&tv, NULL); + + if (tloc) + *tloc = tv.tv_sec; + return tv.tv_sec; +} +#define time(x) git_time(x) + #ifdef NO_STRUCT_ITIMERVAL struct itimerval { struct timeval it_interval;