summaryrefslogtreecommitdiffstats
path: root/generic/tclExecute.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2016-04-04 15:43:49 (GMT)
committerdgp <dgp@users.sourceforge.net>2016-04-04 15:43:49 (GMT)
commit5b2c3db492538b64ee77ef4873492a9a101f55bc (patch)
treec7e63083e02b4df9d805a9fbcf1896954b2b9840 /generic/tclExecute.c
parentf34e441fc16a51536c68eead8a87da4aa9306309 (diff)
downloadtcl-5b2c3db492538b64ee77ef4873492a9a101f55bc.zip
tcl-5b2c3db492538b64ee77ef4873492a9a101f55bc.tar.gz
tcl-5b2c3db492538b64ee77ef4873492a9a101f55bc.tar.bz2
Merge *both* commits to get the TclAsyncReady optimization. Without
both parts, the test interp-34.3.1 hangs.
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r--generic/tclExecute.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index d4077f5..823f619 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -35,14 +35,14 @@
#endif
/*
- * A mask (should be 2**n-1) that is used to work out when the bytecode engine
- * should call Tcl_AsyncReady() to see whether there is a signal that needs
- * handling.
+ * A counter that is used to work out when the bytecode engine should call
+ * Tcl_AsyncReady() to see whether there is a signal that needs handling, and
+ * other expensive periodic operations.
*/
-#ifndef ASYNC_CHECK_COUNT_MASK
-# define ASYNC_CHECK_COUNT_MASK 63
-#endif /* !ASYNC_CHECK_COUNT_MASK */
+#ifndef ASYNC_CHECK_COUNT
+# define ASYNC_CHECK_COUNT 64
+#endif /* !ASYNC_CHECK_COUNT */
/*
* Boolean flag indicating whether the Tcl bytecode interpreter has been
@@ -2115,8 +2115,14 @@ TEBCresume(
* sporadically: no special need for speed.
*/
- int instructionCount = 0; /* Counter that is used to work out when to
- * call Tcl_AsyncReady() */
+ unsigned interruptCounter = 1;
+ /* Counter that is used to work out when to
+ * call Tcl_AsyncReady(). This must be 1
+ * initially so that we call the async-check
+ * stanza early, otherwise there are command
+ * sequences that can make the interpreter
+ * busy-loop without an opportunity to
+ * recognise an interrupt. */
const char *curInstName;
#ifdef TCL_COMPILE_DEBUG
int traceInstructions; /* Whether we are doing instruction-level
@@ -2314,10 +2320,11 @@ TEBCresume(
/*
* Check for asynchronous handlers [Bug 746722]; we do the check every
- * ASYNC_CHECK_COUNT_MASK instruction, of the form (2**n-1).
+ * ASYNC_CHECK_COUNT instructions.
*/
- if ((instructionCount++ & ASYNC_CHECK_COUNT_MASK) == 0) {
+ if ((--interruptCounter) == 0) {
+ interruptCounter = ASYNC_CHECK_COUNT;
DECACHE_STACK_INFO();
if (TclAsyncReady(iPtr)) {
result = Tcl_AsyncInvoke(interp, result);