From: Karsten Blees <karsten.blees@gmail.com>
To: Git List <git@vger.kernel.org>, msysGit <msysgit@googlegroups.com>
Subject: [RFC/PATCH v4 1/3] add high resolution timer function to debug performance issues
Date: Tue, 20 May 2014 21:11:13 +0200 [thread overview]
Message-ID: <537BA8D1.1090503@gmail.com> (raw)
In-Reply-To: <537BA806.50600@gmail.com>
Add a getnanotime() function that returns nanoseconds since 01/01/1970 as
unsigned 64-bit integer (i.e. overflows in july 2554). This is easier to
work with than e.g. struct timeval or struct timespec.
The implementation uses gettimeofday() by default; supports high precision
time sources on the following platforms:
* Linux: using clock_gettime(CLOCK_MONOTONIC)
* Windows: using QueryPerformanceCounter()
Todo:
* enable clock_gettime() on more platforms
* implement Mac OSX version using mach_absolute_time
Signed-off-by: Karsten Blees <blees@dcon.de>
---
Makefile | 7 +++++
cache.h | 1 +
config.mak.uname | 1 +
trace.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 91 insertions(+)
diff --git a/Makefile b/Makefile
index a53f3a8..3c05f8c 100644
--- a/Makefile
+++ b/Makefile
@@ -341,6 +341,8 @@ all::
#
# Define GMTIME_UNRELIABLE_ERRORS if your gmtime() function does not
# return NULL when it receives a bogus time_t.
+#
+# Define HAVE_CLOCK_GETTIME if your platform has clock_gettime in librt.
GIT-VERSION-FILE: FORCE
@$(SHELL_PATH) ./GIT-VERSION-GEN
@@ -1497,6 +1499,11 @@ ifdef GMTIME_UNRELIABLE_ERRORS
BASIC_CFLAGS += -DGMTIME_UNRELIABLE_ERRORS
endif
+ifdef HAVE_CLOCK_GETTIME
+ BASIC_CFLAGS += -DHAVE_CLOCK_GETTIME
+ EXTLIBS += -lrt
+endif
+
ifeq ($(TCLTK_PATH),)
NO_TCLTK = NoThanks
endif
diff --git a/cache.h b/cache.h
index 107ac61..48fc616 100644
--- a/cache.h
+++ b/cache.h
@@ -1362,6 +1362,7 @@ extern int trace_want(const char *key);
__attribute__((format (printf, 2, 3)))
extern void trace_printf_key(const char *key, const char *fmt, ...);
extern void trace_strbuf(const char *key, const struct strbuf *buf);
+extern uint64_t getnanotime(void);
void packet_trace_identity(const char *prog);
diff --git a/config.mak.uname b/config.mak.uname
index 23a8803..5e3b1dd 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -33,6 +33,7 @@ ifeq ($(uname_S),Linux)
HAVE_PATHS_H = YesPlease
LIBC_CONTAINS_LIBINTL = YesPlease
HAVE_DEV_TTY = YesPlease
+ HAVE_CLOCK_GETTIME = YesPlease
endif
ifeq ($(uname_S),GNU/kFreeBSD)
NO_STRLCPY = YesPlease
diff --git a/trace.c b/trace.c
index 08180a9..3d72084 100644
--- a/trace.c
+++ b/trace.c
@@ -187,3 +187,85 @@ int trace_want(const char *key)
return 0;
return 1;
}
+
+#ifdef HAVE_CLOCK_GETTIME
+
+static inline uint64_t highres_nanos(void)
+{
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts))
+ return 0;
+ return (uint64_t) ts.tv_sec * 1000000000 + ts.tv_nsec;
+}
+
+#elif defined (GIT_WINDOWS_NATIVE)
+
+static inline uint64_t highres_nanos(void)
+{
+ static uint64_t high_ns, scaled_low_ns;
+ static int scale;
+ LARGE_INTEGER cnt;
+
+ if (!scale) {
+ if (!QueryPerformanceFrequency(&cnt))
+ return 0;
+
+ /* high_ns = number of ns per cnt.HighPart */
+ high_ns = (1000000000LL << 32) / (uint64_t) cnt.QuadPart;
+
+ /*
+ * Number of ns per cnt.LowPart is 10^9 / frequency (or
+ * high_ns >> 32). For maximum precision, we scale this factor
+ * so that it just fits within 32 bit (i.e. won't overflow if
+ * multiplied with cnt.LowPart).
+ */
+ scaled_low_ns = high_ns;
+ scale = 32;
+ while (scaled_low_ns >= 0x100000000LL) {
+ scaled_low_ns >>= 1;
+ scale--;
+ }
+ }
+
+ /* if QPF worked on initialization, we expect QPC to work as well */
+ QueryPerformanceCounter(&cnt);
+
+ return (high_ns * cnt.HighPart) +
+ ((scaled_low_ns * cnt.LowPart) >> scale);
+}
+
+#else
+# define highres_nanos() 0
+#endif
+
+static inline uint64_t gettimeofday_nanos(void)
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return (uint64_t) tv.tv_sec * 1000000000 + tv.tv_usec * 1000;
+}
+
+/*
+ * Returns nanoseconds since the epoch (01/01/1970), for performance tracing
+ * (i.e. favoring high precision over wall clock time accuracy).
+ */
+inline uint64_t getnanotime(void)
+{
+ static uint64_t offset;
+ if (offset > 1) {
+ /* initialization succeeded, return offset + high res time */
+ return offset + highres_nanos();
+ } else if (offset == 1) {
+ /* initialization failed, fall back to gettimeofday */
+ return gettimeofday_nanos();
+ } else {
+ /* initialize offset if high resolution timer works */
+ uint64_t now = gettimeofday_nanos();
+ uint64_t highres = highres_nanos();
+ if (highres)
+ offset = now - highres;
+ else
+ offset = 1;
+ return now;
+ }
+}
--
1.9.2.msysgit.0.493.g47a82c3
--
--
*** Please reply-to-all at all times ***
*** (do not pretend to know who is subscribed and who is not) ***
*** Please avoid top-posting. ***
The msysGit Wiki is here: https://github.com/msysgit/msysgit/wiki - Github accounts are free.
You received this message because you are subscribed to the Google
Groups "msysGit" group.
To post to this group, send email to msysgit@googlegroups.com
To unsubscribe from this group, send email to
msysgit+unsubscribe@googlegroups.com
For more options, and view previous threads, visit this group at
http://groups.google.com/group/msysgit?hl=en_US?hl=en
---
You received this message because you are subscribed to the Google Groups "msysGit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to msysgit+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
next parent reply other threads:[~2014-05-20 19:11 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <537BA806.50600@gmail.com>
2014-05-20 19:11 ` Karsten Blees [this message]
2014-05-21 7:31 ` [RFC/PATCH v4 1/3] add high resolution timer function to debug performance issues Noel Grandin
2014-05-21 9:14 ` Karsten Blees
2014-05-21 22:14 ` Richard Hansen
2014-05-21 22:17 ` Richard Hansen
2014-05-22 1:33 ` Karsten Blees
2014-05-20 19:11 ` [RFC/PATCH v4 2/3] add trace_performance facility " Karsten Blees
2014-05-21 16:58 ` Jeff King
2014-05-21 18:34 ` Karsten Blees
2014-05-21 20:55 ` Jeff King
2014-05-20 19:11 ` [RFC/PATCH v4 3/3] add command performance tracing to debug scripted commands Karsten Blees
2014-05-21 16:55 ` Jeff King
2014-05-21 17:38 ` Junio C Hamano
2014-05-22 0:40 ` Karsten Blees
2014-05-22 9:59 ` Jeff King
2014-05-23 14:43 ` Karsten Blees
2014-05-23 20:21 ` Jeff King
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=537BA8D1.1090503@gmail.com \
--to=karsten.blees@gmail.com \
--cc=git@vger.kernel.org \
--cc=msysgit@googlegroups.com \
/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).