summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2021-02-18 07:55:08 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2021-02-18 07:55:08 (GMT)
commitf2c4a32d7fbff5e3b59d4d1594a55ea3dbf52837 (patch)
treed93f9cf3071d00faacdd74958733879ebc6b28d6 /generic
parentcf0af45b5ac5705ecec34ff416e57f64db10a03d (diff)
downloadtcl-f2c4a32d7fbff5e3b59d4d1594a55ea3dbf52837.zip
tcl-f2c4a32d7fbff5e3b59d4d1594a55ea3dbf52837.tar.gz
tcl-f2c4a32d7fbff5e3b59d4d1594a55ea3dbf52837.tar.bz2
Performance optimization in TzsetIfNecessary() function. Cherry-picked from sebres-8-6-clock-speedup-cr2 branch
Diffstat (limited to 'generic')
-rw-r--r--generic/tclClock.c19
-rw-r--r--generic/tclEnv.c9
-rw-r--r--generic/tclInt.h7
3 files changed, 34 insertions, 1 deletions
diff --git a/generic/tclClock.c b/generic/tclClock.c
index 37883bb..2c5173a 100644
--- a/generic/tclClock.c
+++ b/generic/tclClock.c
@@ -2029,10 +2029,27 @@ ClockSecondsObjCmd(
static void
TzsetIfNecessary(void)
{
- static char* tzWas = (char*)INT2PTR(-1); /* Previous value of TZ, protected by
+ static char *tzWas = (char *)INT2PTR(-1); /* Previous value of TZ, protected by
* clockMutex. */
+ static long tzLastRefresh = 0; /* Used for latency before next refresh */
+ static size_t tzEnvEpoch = 0; /* Last env epoch, for faster signaling,
+ that TZ changed via TCL */
const char *tzIsNow; /* Current value of TZ */
+ /*
+ * Prevent performance regression on some platforms by resolving of system time zone:
+ * small latency for check whether environment was changed (once per second)
+ * no latency if environment was changed with tcl-env (compare both epoch values)
+ */
+ Tcl_Time now;
+ Tcl_GetTime(&now);
+ if (now.sec == tzLastRefresh && tzEnvEpoch == TclEnvEpoch) {
+ return;
+ }
+
+ tzEnvEpoch = TclEnvEpoch;
+ tzLastRefresh = now.sec;
+
Tcl_MutexLock(&clockMutex);
tzIsNow = getenv("TZ");
if (tzIsNow != NULL && (tzWas == NULL || tzWas == (char*)INT2PTR(-1)
diff --git a/generic/tclEnv.c b/generic/tclEnv.c
index 15dd8b5..e4246a1 100644
--- a/generic/tclEnv.c
+++ b/generic/tclEnv.c
@@ -36,6 +36,11 @@ TCL_DECLARE_MUTEX(envMutex) /* To serialize access to environ. */
# define techar char
#endif
+
+/* MODULE_SCOPE */
+size_t TclEnvEpoch = 0; /* Epoch of the tcl environment
+ * (if changed with tcl-env). */
+
static struct {
int cacheSize; /* Number of env strings in cache. */
char **cache; /* Array containing all of the environment
@@ -417,6 +422,7 @@ Tcl_PutEnv(
value[0] = '\0';
TclSetEnv(name, value+1);
}
+ TclEnvEpoch++;
Tcl_DStringFree(&nameString);
return 0;
@@ -625,6 +631,7 @@ EnvTraceProc(
if (flags & TCL_TRACE_ARRAY) {
TclSetupEnv(interp);
+ TclEnvEpoch++;
return NULL;
}
@@ -645,6 +652,7 @@ EnvTraceProc(
value = Tcl_GetVar2(interp, "env", name2, TCL_GLOBAL_ONLY);
TclSetEnv(name2, value);
+ TclEnvEpoch++;
}
/*
@@ -668,6 +676,7 @@ EnvTraceProc(
if (flags & TCL_TRACE_UNSETS) {
TclUnsetEnv(name2);
+ TclEnvEpoch++;
}
return NULL;
}
diff --git a/generic/tclInt.h b/generic/tclInt.h
index df29da8..5da21b0 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -4977,6 +4977,13 @@ typedef struct NRE_callback {
#define Tcl_Free(ptr) TclpFree(ptr)
#endif
+/*
+ * Other externals.
+ */
+
+MODULE_SCOPE size_t TclEnvEpoch; /* Epoch of the tcl environment
+ * (if changed with tcl-env). */
+
#endif /* _TCLINT */
/*