summaryrefslogtreecommitdiffstats
path: root/unix/tclUnixTime.c
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2017-07-10 08:53:28 (GMT)
committersebres <sebres@users.sourceforge.net>2017-07-10 08:53:28 (GMT)
commit0682a9d1c29428c039fde55c05a2d45eca36a1a1 (patch)
tree61f9b018146fc5d79c283977a3ac2863abefd951 /unix/tclUnixTime.c
parent4a5d28ee4e72a4e58dc65546f814c1cd71f3accc (diff)
parent3e7f9a47b4949a000fe065bb42a55163056cc1b7 (diff)
downloadtcl-0682a9d1c29428c039fde55c05a2d45eca36a1a1.zip
tcl-0682a9d1c29428c039fde55c05a2d45eca36a1a1.tar.gz
tcl-0682a9d1c29428c039fde55c05a2d45eca36a1a1.tar.bz2
merge resp. reintegrate sebres-8-5-event-perf-branch to 8.6
Diffstat (limited to 'unix/tclUnixTime.c')
-rw-r--r--unix/tclUnixTime.c154
1 files changed, 108 insertions, 46 deletions
diff --git a/unix/tclUnixTime.c b/unix/tclUnixTime.c
index 375e366..2bc1fd4 100644
--- a/unix/tclUnixTime.c
+++ b/unix/tclUnixTime.c
@@ -101,10 +101,54 @@ TclpGetSeconds(void)
Tcl_WideInt
TclpGetMicroseconds(void)
{
- Tcl_Time time;
+ if (tclGetTimeProcPtr == NativeGetTime) {
+ struct timeval tv;
- tclGetTimeProcPtr(&time, tclTimeClientData);
- return ((Tcl_WideInt)time.sec)*1000000 + time.usec;
+ (void) gettimeofday(&tv, NULL);
+ return ((Tcl_WideInt)tv.tv_sec)*1000000 + tv.tv_usec;
+ } else {
+ Tcl_Time time;
+
+ tclGetTimeProcPtr(&time, tclTimeClientData);
+ return ((Tcl_WideInt)time.sec)*1000000 + time.usec;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpGetUTimeMonotonic --
+ *
+ * This procedure returns the number of microseconds from some unspecified
+ * starting point.
+ * This time is monotonic (not affected by the time-jumps), so can be used
+ * for relative wait purposes and relative time calculation.
+ *
+ * Results:
+ * Monotonic time in microseconds.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_WideInt
+TclpGetUTimeMonotonic(void)
+{
+ struct timespec mntv;
+ if ( tclGetTimeProcPtr == NativeGetTime
+ && clock_gettime(CLOCK_MONOTONIC, &mntv) == 0
+ ) {
+ /* monotonic time since some starting point in microseconds */
+ return ((Tcl_WideInt)mntv.tv_sec)*1000000 + mntv.tv_nsec / 1000;
+ } else {
+ /* fallback via tclGetTimeProcPtr */
+ Tcl_Time time;
+
+ tclGetTimeProcPtr(&time, tclTimeClientData);
+ return ((Tcl_WideInt)time.sec)*1000000 + time.usec;
+ }
}
/*
@@ -129,30 +173,8 @@ TclpGetMicroseconds(void)
unsigned long
TclpGetClicks(void)
{
- unsigned long now;
-
-#ifdef NO_GETTOD
- if (tclGetTimeProcPtr != NativeGetTime) {
- Tcl_Time time;
-
- tclGetTimeProcPtr(&time, tclTimeClientData);
- now = time.sec*1000000 + time.usec;
- } else {
- /*
- * A semi-NativeGetTime, specialized to clicks.
- */
- struct tms dummy;
-
- now = (unsigned long) times(&dummy);
- }
-#else
- Tcl_Time time;
-
- tclGetTimeProcPtr(&time, tclTimeClientData);
- now = time.sec*1000000 + time.usec;
-#endif
-
- return now;
+ /* clicks should provide monotonic intervals */
+ return (unsigned long) TclpGetUTimeMonotonic();
}
#ifdef TCL_WIDE_CLICKS
@@ -180,17 +202,23 @@ TclpGetWideClicks(void)
{
Tcl_WideInt now;
- if (tclGetTimeProcPtr != NativeGetTime) {
+ if (tclGetTimeProcPtr == NativeGetTime) {
+#ifndef MAC_OSX_TCL
+ /* 1 wide click == 0.001 microseconds (1 nanosecond) */
+ struct timespec mntv;
+
+ (void)clock_gettime(CLOCK_MONOTONIC, &mntv);
+ return ((Tcl_WideInt)mntv.tv_sec)*1000000*1000 + mntv.tv_nsec;
+#else /* MAC_OSX_TCL: */
+ /* 1 wide click == (tb.numer / tb.denom / 1000) microseconds */
+ return (Tcl_WideInt) (mach_absolute_time() & INT64_MAX);
+#endif
+ } else {
+ /* 1 wide click == 1 microsecond (1000 nanoseconds) */
Tcl_Time time;
tclGetTimeProcPtr(&time, tclTimeClientData);
now = ((Tcl_WideInt)time.sec)*1000000 + time.usec;
- } else {
-#ifdef MAC_OSX_TCL
- now = (Tcl_WideInt) (mach_absolute_time() & INT64_MAX);
-#else
-#error Wide high-resolution clicks not implemented on this platform
-#endif
}
return now;
@@ -219,10 +247,12 @@ TclpWideClicksToNanoseconds(
{
double nsec;
- if (tclGetTimeProcPtr != NativeGetTime) {
- nsec = clicks * 1000;
- } else {
-#ifdef MAC_OSX_TCL
+ if (tclGetTimeProcPtr == NativeGetTime) {
+#ifndef MAC_OSX_TCL
+ /* 1 wide click == 0.001 microseconds (1 nanosecond) */
+ return clicks;
+#else /* MAC_OSX_TCL: */
+ /* 1 wide click == (tb.numer / tb.denom) nanoseconds */
static mach_timebase_info_data_t tb;
static uint64_t maxClicksForUInt64;
@@ -235,9 +265,10 @@ TclpWideClicksToNanoseconds(
} else {
nsec = ((long double) (uint64_t) clicks) * tb.numer / tb.denom;
}
-#else
-#error Wide high-resolution clicks not implemented on this platform
#endif
+ } else {
+ /* 1 wide click == 1 microsecond (1000 nanoseconds) */
+ nsec = clicks * 1000;
}
return nsec;
@@ -264,10 +295,12 @@ TclpWideClicksToNanoseconds(
double
TclpWideClickInMicrosec(void)
{
- if (tclGetTimeProcPtr != NativeGetTime) {
- return 1.0;
- } else {
-#ifdef MAC_OSX_TCL
+ if (tclGetTimeProcPtr == NativeGetTime) {
+#ifndef MAC_OSX_TCL
+ /* 1 wide click == 0.001 microseconds (1 nanosecond) */
+ return 0.001;
+#else /* MAC_OSX_TCL: */
+ /* 1 wide click == (tb.numer / tb.denom / 1000) microseconds */
static int initialized = 0;
static double scale = 0.0;
@@ -282,9 +315,10 @@ TclpWideClickInMicrosec(void)
initialized = 1;
return scale;
}
-#else
-#error Wide high-resolution clicks not implemented on this platform
#endif
+ } else {
+ /* 1 wide click == 1 microsecond (1000 nanoseconds) */
+ return 1.0;
}
}
#endif /* TCL_WIDE_CLICKS */
@@ -513,6 +547,34 @@ NativeScaleTime(
/*
*----------------------------------------------------------------------
*
+ * TclpScaleUTime --
+ *
+ * This procedure scales number of microseconds if expected.
+ *
+ * Results:
+ * Number of microseconds scaled using tclScaleTimeProcPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+void
+TclpScaleUTime(
+ Tcl_WideInt *usec)
+{
+ /* Native scale is 1:1. */
+ if (tclScaleTimeProcPtr != NativeScaleTime) {
+ return;
+ } else {
+ Tcl_Time scTime;
+ scTime.sec = *usec / 1000000;
+ scTime.usec = *usec % 1000000;
+ tclScaleTimeProcPtr(&scTime, tclTimeClientData);
+ *usec = ((Tcl_WideInt)scTime.sec) * 1000000 + scTime.usec;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* NativeGetTime --
*
* TIP #233: Gets the current system time in seconds and microseconds