From f5d0aa6e2254e5bc7b53ad639b36ee06453c361a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 31 May 2017 08:31:10 +0000 Subject: Remove "timerate" functionality: this definitely needs a TIP. Also undo changes in library/reg/pkgIndex.tcl, which are unrelated to clock functionality --- generic/tclBasic.c | 1 - generic/tclCmdMZ.c | 348 +---------------------------------------------- generic/tclInt.h | 3 - library/reg/pkgIndex.tcl | 12 +- 4 files changed, 2 insertions(+), 362 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 4d392d0..0486383 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -285,7 +285,6 @@ static const CmdInfo builtInCmds[] = { {"source", Tcl_SourceObjCmd, NULL, TclNRSourceObjCmd, 0}, {"tell", Tcl_TellObjCmd, NULL, NULL, CMD_IS_SAFE}, {"time", Tcl_TimeObjCmd, NULL, NULL, CMD_IS_SAFE}, - {"timerate", Tcl_TimeRateObjCmd, NULL, NULL, CMD_IS_SAFE}, {"unload", Tcl_UnloadObjCmd, NULL, NULL, 0}, {"update", Tcl_UpdateObjCmd, NULL, NULL, CMD_IS_SAFE}, {"vwait", Tcl_VwaitObjCmd, NULL, NULL, CMD_IS_SAFE}, diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 8c2c026..885a0bc 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -17,7 +17,6 @@ */ #include "tclInt.h" -#include "tclCompile.h" #include "tclRegexp.h" #include "tclStringTrim.h" @@ -4147,7 +4146,7 @@ Tcl_TimeObjCmd( start = TclpGetWideClicks(); #endif while (i-- > 0) { - result = TclEvalObjEx(interp, objPtr, 0, NULL, 0); + result = Tcl_EvalObjEx(interp, objPtr, 0); if (result != TCL_OK) { return result; } @@ -4187,351 +4186,6 @@ Tcl_TimeObjCmd( /* *---------------------------------------------------------------------- * - * Tcl_TimeRateObjCmd -- - * - * This object-based procedure is invoked to process the "timerate" Tcl - * command. - * This is similar to command "time", except the execution limited by - * given time (in milliseconds) instead of repetition count. - * - * Example: - * timerate {after 5} 1000 ; # equivalent for `time {after 5} [expr 1000/5]` - * - * Results: - * A standard Tcl object result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_TimeRateObjCmd( - ClientData dummy, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - static - double measureOverhead = 0; /* global measure-overhead */ - double overhead = -1; /* given measure-overhead */ - register Tcl_Obj *objPtr; - register int result, i; - Tcl_Obj *calibrate = NULL, *direct = NULL; - Tcl_WideInt count = 0; /* Holds repetition count */ - Tcl_WideInt maxms = -0x7FFFFFFFFFFFFFFFL; - /* Maximal running time (in milliseconds) */ - Tcl_WideInt threshold = 1; /* Current threshold for check time (faster - * repeat count without time check) */ - Tcl_WideInt maxIterTm = 1; /* Max time of some iteration as max threshold - * additionally avoid divide to zero (never < 1) */ - register Tcl_WideInt start, middle, stop; -#ifndef TCL_WIDE_CLICKS - Tcl_Time now; -#endif - - static const char *const options[] = { - "-direct", "-overhead", "-calibrate", "--", NULL - }; - enum options { - TMRT_EV_DIRECT, TMRT_OVERHEAD, TMRT_CALIBRATE, TMRT_LAST - }; - - NRE_callback *rootPtr; - ByteCode *codePtr = NULL; - - for (i = 1; i < objc - 1; i++) { - int index; - if (Tcl_GetIndexFromObj(NULL, objv[i], options, "option", TCL_EXACT, - &index) != TCL_OK) { - break; - } - if (index == TMRT_LAST) { - i++; - break; - } - switch (index) { - case TMRT_EV_DIRECT: - direct = objv[i]; - break; - case TMRT_OVERHEAD: - if (++i >= objc - 1) { - goto usage; - } - if (Tcl_GetDoubleFromObj(interp, objv[i], &overhead) != TCL_OK) { - return TCL_ERROR; - } - break; - case TMRT_CALIBRATE: - calibrate = objv[i]; - break; - } - } - - if (i >= objc || i < objc-2) { -usage: - Tcl_WrongNumArgs(interp, 1, objv, "?-direct? ?-calibrate? ?-overhead double? command ?time?"); - return TCL_ERROR; - } - objPtr = objv[i++]; - if (i < objc) { - result = TclGetWideIntFromObj(interp, objv[i], &maxms); - if (result != TCL_OK) { - return result; - } - } - - /* if calibrate */ - if (calibrate) { - - /* if no time specified for the calibration */ - if (maxms == -0x7FFFFFFFFFFFFFFFL) { - Tcl_Obj *clobjv[6]; - Tcl_WideInt maxCalTime = 5000; - double lastMeasureOverhead = measureOverhead; - - clobjv[0] = objv[0]; - i = 1; - if (direct) { - clobjv[i++] = direct; - } - clobjv[i++] = objPtr; - - /* reset last measurement overhead */ - measureOverhead = (double)0; - - /* self-call with 100 milliseconds to warm-up, - * before entering the calibration cycle */ - TclNewLongObj(clobjv[i], 100); - Tcl_IncrRefCount(clobjv[i]); - result = Tcl_TimeRateObjCmd(dummy, interp, i+1, clobjv); - Tcl_DecrRefCount(clobjv[i]); - if (result != TCL_OK) { - return result; - } - - i--; - clobjv[i++] = calibrate; - clobjv[i++] = objPtr; - - /* set last measurement overhead to max */ - measureOverhead = (double)0x7FFFFFFFFFFFFFFFL; - - /* calibration cycle until it'll be preciser */ - maxms = -1000; - do { - lastMeasureOverhead = measureOverhead; - TclNewLongObj(clobjv[i], (int)maxms); - Tcl_IncrRefCount(clobjv[i]); - result = Tcl_TimeRateObjCmd(dummy, interp, i+1, clobjv); - Tcl_DecrRefCount(clobjv[i]); - if (result != TCL_OK) { - return result; - } - maxCalTime += maxms; - /* increase maxms for preciser calibration */ - maxms -= (-maxms / 4); - /* as long as new value more as 0.05% better */ - } while ( (measureOverhead >= lastMeasureOverhead - || measureOverhead / lastMeasureOverhead <= 0.9995) - && maxCalTime > 0 - ); - - return result; - } - if (maxms == 0) { - /* reset last measurement overhead */ - measureOverhead = 0; - Tcl_SetObjResult(interp, Tcl_NewLongObj(0)); - return TCL_OK; - } - - /* if time is negative - make current overhead more precise */ - if (maxms > 0) { - /* set last measurement overhead to max */ - measureOverhead = (double)0x7FFFFFFFFFFFFFFFL; - } else { - maxms = -maxms; - } - - } - - if (maxms == -0x7FFFFFFFFFFFFFFFL) { - maxms = 1000; - } - if (overhead == -1) { - overhead = measureOverhead; - } - - /* be sure that resetting of result will not smudge the further measurement */ - Tcl_ResetResult(interp); - - /* compile object */ - if (!direct) { - if (TclInterpReady(interp) != TCL_OK) { - return TCL_ERROR; - } - codePtr = TclCompileObj(interp, objPtr, NULL, 0); - TclPreserveByteCode(codePtr); - } - - /* get start and stop time */ -#ifdef TCL_WIDE_CLICKS - start = middle = TclpGetWideClicks(); - /* time to stop execution (in wide clicks) */ - stop = start + (maxms * 1000 / TclpWideClickInMicrosec()); -#else - Tcl_GetTime(&now); - start = now.sec; start *= 1000000; start += now.usec; - middle = start; - /* time to stop execution (in microsecs) */ - stop = start + maxms * 1000; -#endif - - /* start measurement */ - while (1) { - /* eval single iteration */ - count++; - - if (!direct) { - /* precompiled */ - rootPtr = TOP_CB(interp); - result = TclNRExecuteByteCode(interp, codePtr); - result = TclNRRunCallbacks(interp, result, rootPtr); - } else { - /* eval */ - result = TclEvalObjEx(interp, objPtr, 0, NULL, 0); - } - if (result != TCL_OK) { - goto done; - } - - /* don't check time up to threshold */ - if (--threshold > 0) continue; - - /* check stop time reached, estimate new threshold */ - #ifdef TCL_WIDE_CLICKS - middle = TclpGetWideClicks(); - #else - Tcl_GetTime(&now); - middle = now.sec; middle *= 1000000; middle += now.usec; - #endif - if (middle >= stop) { - break; - } - - /* don't calculate threshold by few iterations, because sometimes - * first iteration(s) can be too fast (cached, delayed clean up, etc) */ - if (count < 10) { - threshold = 1; continue; - } - - /* average iteration time in microsecs */ - threshold = (middle - start) / count; - if (threshold > maxIterTm) { - maxIterTm = threshold; - } - /* as relation between remaining time and time since last check */ - threshold = ((stop - middle) / maxIterTm) / 4; - if (threshold > 100000) { /* fix for too large threshold */ - threshold = 100000; - } - } - - { - Tcl_Obj *objarr[8], **objs = objarr; - Tcl_WideInt val; - const char *fmt; - - middle -= start; /* execution time in microsecs */ - - #ifdef TCL_WIDE_CLICKS - /* convert execution time in wide clicks to microsecs */ - middle *= TclpWideClickInMicrosec(); - #endif - - /* if not calibrate */ - if (!calibrate) { - /* minimize influence of measurement overhead */ - if (overhead > 0) { - /* estimate the time of overhead (microsecs) */ - Tcl_WideInt curOverhead = overhead * count; - if (middle > curOverhead) { - middle -= curOverhead; - } else { - middle = 1; - } - } - } else { - /* calibration - obtaining new measurement overhead */ - if (measureOverhead > (double)middle / count) { - measureOverhead = (double)middle / count; - } - objs[0] = Tcl_NewDoubleObj(measureOverhead); - TclNewLiteralStringObj(objs[1], "\xC2\xB5s/#-overhead"); /* mics */ - objs += 2; - } - - val = middle / count; /* microsecs per iteration */ - if (val >= 1000000) { - objs[0] = Tcl_NewWideIntObj(val); - } else { - if (val < 10) { fmt = "%.6f"; } else - if (val < 100) { fmt = "%.4f"; } else - if (val < 1000) { fmt = "%.3f"; } else - if (val < 10000) { fmt = "%.2f"; } else - { fmt = "%.1f"; }; - objs[0] = Tcl_ObjPrintf(fmt, ((double)middle)/count); - } - - objs[2] = Tcl_NewWideIntObj(count); /* iterations */ - - /* calculate speed as rate (count) per sec */ - if (!middle) middle++; /* +1 ms, just to avoid divide by zero */ - if (count < (0x7FFFFFFFFFFFFFFFL / 1000000)) { - val = (count * 1000000) / middle; - if (val < 100000) { - if (val < 100) { fmt = "%.3f"; } else - if (val < 1000) { fmt = "%.2f"; } else - { fmt = "%.1f"; }; - objs[4] = Tcl_ObjPrintf(fmt, ((double)(count * 1000000)) / middle); - } else { - objs[4] = Tcl_NewWideIntObj(val); - } - } else { - objs[4] = Tcl_NewWideIntObj((count / middle) * 1000000); - } - - /* estimated net execution time (in millisecs) */ - if (!calibrate) { - objs[6] = Tcl_ObjPrintf("%.3f", (double)middle / 1000); - TclNewLiteralStringObj(objs[7], "nett-ms"); - } - - /* - * Construct the result as a list because many programs have always parsed - * as such (extracting the first element, typically). - */ - - TclNewLiteralStringObj(objs[1], "\xC2\xB5s/#"); /* mics/# */ - TclNewLiteralStringObj(objs[3], "#"); - TclNewLiteralStringObj(objs[5], "#/sec"); - Tcl_SetObjResult(interp, Tcl_NewListObj(8, objarr)); - } - -done: - - if (codePtr != NULL) { - TclReleaseByteCode(codePtr); - } - - return result; -} - -/* - *---------------------------------------------------------------------- - * * Tcl_TryObjCmd, TclNRTryObjCmd -- * * This procedure is invoked to process the "try" Tcl command. See the diff --git a/generic/tclInt.h b/generic/tclInt.h index 333a665..5bd4324 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3437,9 +3437,6 @@ MODULE_SCOPE int Tcl_ThrowObjCmd(ClientData dummy, Tcl_Interp *interp, MODULE_SCOPE int Tcl_TimeObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -MODULE_SCOPE int Tcl_TimeRateObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); MODULE_SCOPE int Tcl_TraceObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); diff --git a/library/reg/pkgIndex.tcl b/library/reg/pkgIndex.tcl index ab022ab..b1fe234 100755 --- a/library/reg/pkgIndex.tcl +++ b/library/reg/pkgIndex.tcl @@ -1,19 +1,9 @@ if {([info commands ::tcl::pkgconfig] eq "") - || ([info sharedlibextension] ne ".dll")} return + || ([info sharedlibextension] ne ".dll")} return if {[::tcl::pkgconfig get debug]} { - if {[info exists [file join $dir tclreg13g.dll]]} { package ifneeded registry 1.3.2 \ [list load [file join $dir tclreg13g.dll] registry] - } else { - package ifneeded registry 1.3.2 \ - [list load tclreg13g registry] - } } else { - if {[info exists [file join $dir tclreg13.dll]]} { package ifneeded registry 1.3.2 \ [list load [file join $dir tclreg13.dll] registry] - } else { - package ifneeded registry 1.3.2 \ - [list load tclreg13 registry] - } } -- cgit v0.12