Compare commits

..
Author SHA1 Message Date
oehhar f7d1ffc3ae Added patch for win/configure.in into win/configure.ac 2016-03-31 07:11:27 +00:00
oehhar cfa6363187 The following patch against a stock tcl 8.6.5 source tree tries to
implement most of TIP #302 for UN*X and WIN32/64:



   * use clock_gettime(CLOCK_MONOTONIC) for relative timing (UN*X)

     when available (tested at runtime)

   * use PTHREAD_CONDATTR_SETCLOCK et.al. for pthread_cond (UN*X)

     when available (tested at runtime)

   * use GetTickCount64() for relative timing (WIN64)

   * use GetTickCount() for relative timing (WIN32 for WINNT<6.0)

   * configure (UN*X) detects availabilty of clock_gettime() and

     pthread_condattr_setclock() plus adds optional -lrt to LIBS

   * configure (WIN32) adds command line option --with-tickcount

     to turn on GetTickCount*() usage



Trade-off: implementation eliminates virtualized time, unfortunately.



Best regards,

Christian Werner

--- missing merge ---

diff -ur tcl8.6.5-orig/win/configure.in tcl8.6.5/win/configure.in

--- tcl8.6.5-orig/win/configure.in	2016-02-29 20:13:09.000000000 +0100

+++ tcl8.6.5/win/configure.in	2016-03-25 06:47:47.712516747 +0100

@@ -142,6 +142,15 @@

  ])

  AC_DEFINE(HAVE_ZLIB, 1, [Is there an installed zlib?])

  

+AC_ARG_WITH(tickcount,

+    AC_HELP_STRING([--with-tickcount],

+	[use GetTickCount for timers, turns off interp time limits]),

+    [tcl_ok=$withval], [tcl_ok=no])

+AC_MSG_RESULT([$tcl_ok])

+if test $tcl_ok = yes; then

+    AC_DEFINE(WIN32_USE_TICKCOUNT, 1, [Use GetTickCount for timers?])

+fi

+

  AC_CHECK_TYPE([intptr_t], [

      AC_DEFINE([HAVE_INTPTR_T], 1, [Do we have the intptr_t type?])], [

      AC_CACHE_CHECK([for pointer-size signed integer type], tcl_cv_intptr_t, [
2016-03-30 20:03:21 +00:00
76 changed files with 1292 additions and 1065 deletions
+7 -6
View File
@@ -89,9 +89,10 @@ have 59 or 61 seconds.
.TP
\fIunit\fR
One of the words, \fBseconds\fR, \fBminutes\fR, \fBhours\fR,
\fBdays\fR, \fBweekdays\fR, \fBweeks\fR, \fBmonths\fR, or \fByears\fR.
Used in conjunction with \fIcount\fR to identify an interval of time,
for example, \fI3 seconds\fR or \fI1 year\fR.
\fBdays\fR, \fBweeks\fR, \fBmonths\fR, or \fByears\fR, or
any unique prefix of such a word. Used in conjunction with \fIcount\fR
to identify an interval of time, for example, \fI3 seconds\fR or
\fI1 year\fR.
.SS "OPTIONS"
.TP
\fB\-base\fR time
@@ -174,7 +175,8 @@ given as its first argument. The remaining arguments (other than the
possible \fB\-timezone\fR, \fB\-locale\fR and \fB\-gmt\fR options)
are integers and keywords in alternation, where the keywords are chosen
from \fBseconds\fR, \fBminutes\fR, \fBhours\fR,
\fBdays\fR, \fBweekdays\fR, \fBweeks\fR, \fBmonths\fR, or \fByears\fR.
\fBdays\fR, \fBweeks\fR, \fBmonths\fR, or \fByears\fR, or
any unique prefix of such a word.
.PP
Addition of seconds, minutes and hours is fairly straightforward;
the given time increment (times sixty for minutes, or 3600 for hours)
@@ -211,8 +213,7 @@ the given time to a calendar day and time of day in the appropriate
time zone and locale. The requisite number of days (weeks are converted
to days by multiplying by seven) is added to the calendar day, and
the date and time are then converted back to a count of seconds from
the epoch time. The \fBweekdays\fR keyword is similar to \fBdays\fR,
with the only difference that weekends - Saturdays and Sundays - are skipped.
the epoch time.
.PP
Adding and subtracting a given number of days across the point that
the time changes at the start or end of summer time (Daylight Saving Time)
+3 -16
View File
@@ -256,33 +256,20 @@ static const chr brbacks[] = { /* \s within brackets */
CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
CHR(':'), CHR(']')
};
#define PUNCT_CONN \
CHR('_'), \
0x203f /* UNDERTIE */, \
0x2040 /* CHARACTER TIE */,\
0x2054 /* INVERTED UNDERTIE */,\
0xfe33 /* PRESENTATION FORM FOR VERTICAL LOW LINE */, \
0xfe34 /* PRESENTATION FORM FOR VERTICAL WAVY LOW LINE */, \
0xfe4d /* DASHED LOW LINE */, \
0xfe4e /* CENTRELINE LOW LINE */, \
0xfe4f /* WAVY LOW LINE */, \
0xff3f /* FULLWIDTH LOW LINE */
static const chr backw[] = { /* \w */
CHR('['), CHR('['), CHR(':'),
CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
CHR(':'), CHR(']'), PUNCT_CONN, CHR(']')
CHR(':'), CHR(']'), CHR('_'), CHR(']')
};
static const chr backW[] = { /* \W */
CHR('['), CHR('^'), CHR('['), CHR(':'),
CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
CHR(':'), CHR(']'), PUNCT_CONN, CHR(']')
CHR(':'), CHR(']'), CHR('_'), CHR(']')
};
static const chr brbackw[] = { /* \w within brackets */
CHR('['), CHR(':'),
CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
CHR(':'), CHR(']'), PUNCT_CONN
CHR(':'), CHR(']'), CHR('_')
};
/*
+9 -3
View File
@@ -866,7 +866,7 @@ CompileAssembleObj(
* Not valid, so free it and regenerate.
*/
TclFreeIntRep(objPtr);
FreeAssembleCodeInternalRep(objPtr);
}
/*
@@ -891,13 +891,15 @@ CompileAssembleObj(
*/
TclEmitOpcode(INST_DONE, &compEnv);
codePtr = TclInitByteCodeObj(objPtr, &assembleCodeType, &compEnv);
TclInitByteCodeObj(objPtr, &compEnv);
objPtr->typePtr = &assembleCodeType;
TclFreeCompileEnv(&compEnv);
/*
* Record the local variable context to which the bytecode pertains
*/
codePtr = objPtr->internalRep.twoPtrValue.ptr1;
if (iPtr->varFramePtr->localCachePtr) {
codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr;
codePtr->localCachePtr->refCount++;
@@ -4311,7 +4313,11 @@ FreeAssembleCodeInternalRep(
{
ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
TclReleaseByteCode(codePtr);
codePtr->refCount--;
if (codePtr->refCount <= 0) {
TclCleanupByteCode(codePtr);
}
objPtr->typePtr = NULL;
}
/*
+1 -1
View File
@@ -2755,7 +2755,7 @@ Tcl_LreplaceObjCmd(
* (to allow for replacing the last elem).
*/
if ((first > listLen) && (listLen > 0)) {
if ((first >= listLen) && (listLen > 0)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"list doesn't contain element %s", TclGetString(objv[2])));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LREPLACE", "BADIDX",
Regular → Executable
+43
View File
@@ -4124,10 +4124,23 @@ Tcl_TimeObjCmd(
register int i, result;
int count;
double totalMicroSec;
#ifdef WIN32_USE_TICKCOUNT
#if (_WIN32_WINNT >= 0x0600)
ULONGLONG start, stop;
#else
DWORD start, stop;
#endif
#else
#ifdef HAVE_CLOCK_GETTIME
int monoClock = 1;
struct timespec start, stop;
#else
#ifndef TCL_WIDE_CLICKS
Tcl_Time start, stop;
#else
Tcl_WideInt start, stop;
#endif
#endif
#endif
if (objc == 2) {
@@ -4144,10 +4157,25 @@ Tcl_TimeObjCmd(
objPtr = objv[1];
i = count;
#ifdef WIN32_USE_TICKCOUNT
#if (_WIN32_WINNT >= 0x0600)
start = GetTickCount64();
#else
start = GetTickCount();
#endif
#else
#ifdef HAVE_CLOCK_GETTIME
if (clock_gettime(CLOCK_MONOTONIC, &start) == -1) {
clock_gettime(CLOCK_REALTIME, &start);
monoClock = 0;
}
#else
#ifndef TCL_WIDE_CLICKS
Tcl_GetTime(&start);
#else
start = TclpGetWideClicks();
#endif
#endif
#endif
while (i-- > 0) {
result = Tcl_EvalObjEx(interp, objPtr, 0);
@@ -4155,6 +4183,19 @@ Tcl_TimeObjCmd(
return result;
}
}
#ifdef WIN32_USE_TICKCOUNT
#if (_WIN32_WINNT >= 0x0600)
stop = GetTickCount64();
#else
stop = GetTickCount();
#endif
totalMicroSec = (stop - start) * 1000.0;
#else
#ifdef HAVE_CLOCK_GETTIME
clock_gettime(monoClock ? CLOCK_MONOTONIC : CLOCK_REALTIME, &stop);
totalMicroSec = ((double) (stop.tv_sec - start.tv_sec)) * 1.0e6
+ (stop.tv_nsec - start.tv_nsec) / 1000.0;
#else
#ifndef TCL_WIDE_CLICKS
Tcl_GetTime(&stop);
totalMicroSec = ((double) (stop.sec - start.sec)) * 1.0e6
@@ -4162,6 +4203,8 @@ Tcl_TimeObjCmd(
#else
stop = TclpGetWideClicks();
totalMicroSec = ((double) TclpWideClicksToNanoseconds(stop - start))/1.0e3;
#endif
#endif
#endif
if (count <= 1) {
+7 -40
View File
@@ -1488,15 +1488,6 @@ TclCompileLreplaceCmd(
return TCL_ERROR;
}
/*
* idx1, idx2 are now in canonical form:
*
* - integer: [0,len+1]
* - end index: INDEX_END
* - -ive offset: INDEX_END-[len-1,0]
* - +ive offset: INDEX_END+1
*/
/*
* Compilation fails when one index is end-based but the other isn't.
* Fixing this will require more bytecodes, but this is a workaround for
@@ -1530,9 +1521,6 @@ TclCompileLreplaceCmd(
idx1 = 0;
goto dropEnd;
} else {
if (idx2 < idx1) {
idx2 = idx1 - 1;
}
if (idx1 > 0) {
tmpObj = Tcl_NewIntObj(idx1);
Tcl_IncrRefCount(tmpObj);
@@ -1560,7 +1548,9 @@ TclCompileLreplaceCmd(
idx1 = 0;
goto replaceTail;
} else {
if (idx2 < idx1) {
if (idx1 > 0 && idx2 > 0 && idx2 < idx1) {
idx2 = idx1 - 1;
} else if (idx1 < 0 && idx2 < 0 && idx2 < idx1) {
idx2 = idx1 - 1;
}
if (idx1 > 0) {
@@ -1576,7 +1566,7 @@ TclCompileLreplaceCmd(
* operate on.
*/
dropAll: /* This just ensures the arg is a list. */
dropAll:
TclEmitOpcode( INST_LIST_LENGTH, envPtr);
TclEmitOpcode( INST_POP, envPtr);
PushStringLiteral(envPtr, "");
@@ -1589,21 +1579,12 @@ TclCompileLreplaceCmd(
dropRange:
if (tmpObj != NULL) {
/*
* Emit bytecode to check the list length.
*/
TclEmitOpcode( INST_DUP, envPtr);
TclEmitOpcode( INST_LIST_LENGTH, envPtr);
TclEmitPush(TclAddLiteralObj(envPtr, tmpObj, NULL), envPtr);
TclEmitOpcode( INST_GE, envPtr);
TclEmitOpcode( INST_GT, envPtr);
offset = CurrentOffset(envPtr);
TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr);
/*
* Emit an error if we've been given an empty list.
*/
TclEmitOpcode( INST_DUP, envPtr);
TclEmitOpcode( INST_LIST_LENGTH, envPtr);
offset2 = CurrentOffset(envPtr);
@@ -1654,30 +1635,16 @@ TclCompileLreplaceCmd(
replaceRange:
if (tmpObj != NULL) {
/*
* Emit bytecode to check the list length.
*/
TclEmitOpcode( INST_DUP, envPtr);
TclEmitOpcode( INST_LIST_LENGTH, envPtr);
/*
* Check the list length vs idx1.
*/
TclEmitPush(TclAddLiteralObj(envPtr, tmpObj, NULL), envPtr);
TclEmitOpcode( INST_GE, envPtr);
TclEmitOpcode( INST_GT, envPtr);
offset = CurrentOffset(envPtr);
TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr);
/*
* Emit an error if we've been given an empty list.
*/
TclEmitOpcode( INST_DUP, envPtr);
TclEmitOpcode( INST_LIST_LENGTH, envPtr);
offset2 = CurrentOffset(envPtr);
TclEmitInstInt1( INST_JUMP_FALSE1, 0, envPtr);
TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr);
TclEmitPush(TclAddLiteralObj(envPtr, Tcl_ObjPrintf(
"list doesn't contain element %d", idx1), NULL), envPtr);
CompileReturnInternal(envPtr, INST_RETURN_IMM, TCL_ERROR, 0,
+5 -2
View File
@@ -2181,6 +2181,7 @@ ExecConstantExprTree(
CompileEnv *envPtr;
ByteCode *byteCodePtr;
int code;
Tcl_Obj *byteCodeObj = Tcl_NewObj();
NRE_callback *rootPtr = TOP_CB(interp);
/*
@@ -2194,12 +2195,14 @@ ExecConstantExprTree(
CompileExprTree(interp, nodes, index, litObjvPtr, NULL, NULL, envPtr,
0 /* optimize */);
TclEmitOpcode(INST_DONE, envPtr);
byteCodePtr = TclInitByteCode(envPtr);
Tcl_IncrRefCount(byteCodeObj);
TclInitByteCodeObj(byteCodeObj, envPtr);
TclFreeCompileEnv(envPtr);
TclStackFree(interp, envPtr);
byteCodePtr = byteCodeObj->internalRep.twoPtrValue.ptr1;
TclNRExecuteByteCode(interp, byteCodePtr);
code = TclNRRunCallbacks(interp, TCL_OK, rootPtr);
TclReleaseByteCode(byteCodePtr);
Tcl_DecrRefCount(byteCodeObj);
return code;
}
+55 -92
View File
@@ -661,7 +661,6 @@ InstructionDesc const tclInstructionTable[] = {
* Prototypes for procedures defined later in this file:
*/
static void CleanupByteCode(ByteCode *codePtr);
static ByteCode * CompileSubstObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
int flags);
static void DupByteCodeInternalRep(Tcl_Obj *srcPtr,
@@ -677,7 +676,6 @@ static void FreeSubstCodeInternalRep(Tcl_Obj *objPtr);
static int GetCmdLocEncodingSize(CompileEnv *envPtr);
static int IsCompactibleCompileEnv(Tcl_Interp *interp,
CompileEnv *envPtr);
static void PreventCycle(Tcl_Obj *objPtr, CompileEnv *envPtr);
#ifdef TCL_COMPILE_STATS
static void RecordByteCodeStats(ByteCode *codePtr);
#endif /* TCL_COMPILE_STATS */
@@ -868,7 +866,7 @@ TclSetByteCodeFromAny(
#endif /*TCL_COMPILE_DEBUG*/
if (result == TCL_OK) {
(void) TclInitByteCodeObj(objPtr, &tclByteCodeType, &compEnv);
TclInitByteCodeObj(objPtr, &compEnv);
#ifdef TCL_COMPILE_DEBUG
if (tclTraceCompile >= 2) {
TclPrintByteCodeObj(interp, objPtr);
@@ -969,13 +967,16 @@ FreeByteCodeInternalRep(
{
register ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
TclReleaseByteCode(codePtr);
objPtr->typePtr = NULL;
if (codePtr->refCount-- <= 1) {
TclCleanupByteCode(codePtr);
}
}
/*
*----------------------------------------------------------------------
*
* TclReleaseByteCode --
* TclCleanupByteCode --
*
* This procedure does all the real work of freeing up a bytecode
* object's ByteCode structure. It's called only when the structure's
@@ -992,26 +993,7 @@ FreeByteCodeInternalRep(
*/
void
TclPreserveByteCode(
register ByteCode *codePtr)
{
codePtr->refCount++;
}
void
TclReleaseByteCode(
register ByteCode *codePtr)
{
if (--codePtr->refCount) {
return;
}
/* Just dropped to refcount==0. Clean up. */
CleanupByteCode(codePtr);
}
static void
CleanupByteCode(
TclCleanupByteCode(
register ByteCode *codePtr) /* Points to the ByteCode to free. */
{
Tcl_Interp *interp = (Tcl_Interp *) *codePtr->interpHandle;
@@ -1278,6 +1260,8 @@ Tcl_NRSubstObj(
*
* Results:
* A (ByteCode *) is returned pointing to the resulting ByteCode.
* The caller must manage its refCount and arrange for a call to
* TclCleanupByteCode() when the last reference disappears.
*
* Side effects:
* The Tcl_ObjType of objPtr is changed to the "substcode" type, and the
@@ -1308,7 +1292,7 @@ CompileSubstObj(
|| (codePtr->nsEpoch != nsPtr->resolverEpoch)
|| (codePtr->localCachePtr !=
iPtr->varFramePtr->localCachePtr)) {
TclFreeIntRep(objPtr);
FreeSubstCodeInternalRep(objPtr);
}
}
if (objPtr->typePtr != &substCodeType) {
@@ -1322,9 +1306,11 @@ CompileSubstObj(
TclSubstCompile(interp, bytes, numBytes, flags, 1, &compEnv);
TclEmitOpcode(INST_DONE, &compEnv);
codePtr = TclInitByteCodeObj(objPtr, &substCodeType, &compEnv);
TclInitByteCodeObj(objPtr, &compEnv);
objPtr->typePtr = &substCodeType;
TclFreeCompileEnv(&compEnv);
codePtr = objPtr->internalRep.twoPtrValue.ptr1;
objPtr->internalRep.twoPtrValue.ptr1 = codePtr;
objPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(flags);
if (iPtr->varFramePtr->localCachePtr) {
@@ -1367,7 +1353,10 @@ FreeSubstCodeInternalRep(
{
register ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
TclReleaseByteCode(codePtr);
objPtr->typePtr = NULL;
if (codePtr->refCount-- <= 1) {
TclCleanupByteCode(codePtr);
}
}
static void
@@ -2708,40 +2697,11 @@ TclCompileNoOp(
*----------------------------------------------------------------------
*/
static void
PreventCycle(
Tcl_Obj *objPtr,
CompileEnv *envPtr)
{
int i;
for (i = 0; i < envPtr->literalArrayNext; i++) {
if (objPtr == TclFetchLiteral(envPtr, i)) {
/*
* Prevent circular reference where the bytecode intrep of
* a value contains a literal which is that same value.
* If this is allowed to happen, refcount decrements may not
* reach zero, and memory may leak. Bugs 467523, 3357771
*
* NOTE: [Bugs 3392070, 3389764] We make a copy based completely
* on the string value, and do not call Tcl_DuplicateObj() so we
* can be sure we do not have any lingering cycles hiding in
* the intrep.
*/
int numBytes;
const char *bytes = Tcl_GetStringFromObj(objPtr, &numBytes);
Tcl_Obj *copyPtr = Tcl_NewStringObj(bytes, numBytes);
Tcl_IncrRefCount(copyPtr);
TclReleaseLiteral((Tcl_Interp *)envPtr->iPtr, objPtr);
envPtr->literalArrayPtr[i].objPtr = copyPtr;
}
}
}
ByteCode *
TclInitByteCode(
void
TclInitByteCodeObj(
Tcl_Obj *objPtr, /* Points object that should be initialized,
* and whose string rep contains the source
* code. */
register CompileEnv *envPtr)/* Points to the CompileEnv structure from
* which to create a ByteCode structure. */
{
@@ -2792,8 +2752,7 @@ TclInitByteCode(
codePtr->compileEpoch = iPtr->compileEpoch;
codePtr->nsPtr = namespacePtr;
codePtr->nsEpoch = namespacePtr->resolverEpoch;
codePtr->refCount = 0;
TclPreserveByteCode(codePtr);
codePtr->refCount = 1;
if (namespacePtr->compiledVarResProc || iPtr->resolverPtr) {
codePtr->flags = TCL_BYTECODE_RESOLVE_VARS;
} else {
@@ -2819,7 +2778,29 @@ TclInitByteCode(
p += TCL_ALIGN(codeBytes); /* align object array */
codePtr->objArrayPtr = (Tcl_Obj **) p;
for (i = 0; i < numLitObjects; i++) {
codePtr->objArrayPtr[i] = TclFetchLiteral(envPtr, i);
Tcl_Obj *fetched = TclFetchLiteral(envPtr, i);
if (objPtr == fetched) {
/*
* Prevent circular reference where the bytecode intrep of
* a value contains a literal which is that same value.
* If this is allowed to happen, refcount decrements may not
* reach zero, and memory may leak. Bugs 467523, 3357771
*
* NOTE: [Bugs 3392070, 3389764] We make a copy based completely
* on the string value, and do not call Tcl_DuplicateObj() so we
* can be sure we do not have any lingering cycles hiding in
* the intrep.
*/
int numBytes;
const char *bytes = Tcl_GetStringFromObj(objPtr, &numBytes);
codePtr->objArrayPtr[i] = Tcl_NewStringObj(bytes, numBytes);
Tcl_IncrRefCount(codePtr->objArrayPtr[i]);
TclReleaseLiteral((Tcl_Interp *)iPtr, objPtr);
} else {
codePtr->objArrayPtr[i] = fetched;
}
}
p += TCL_ALIGN(objArrayBytes); /* align exception range array */
@@ -2861,6 +2842,15 @@ TclInitByteCode(
RecordByteCodeStats(codePtr);
#endif /* TCL_COMPILE_STATS */
/*
* Free the old internal rep then convert the object to a bytecode object
* by making its internal rep point to the just compiled ByteCode.
*/
TclFreeIntRep(objPtr);
objPtr->internalRep.twoPtrValue.ptr1 = codePtr;
objPtr->typePtr = &tclByteCodeType;
/*
* TIP #280. Associate the extended per-word line information with the
* byte code object (internal rep), for use with the bc compiler.
@@ -2874,33 +2864,6 @@ TclInitByteCode(
envPtr->iPtr = NULL;
codePtr->localCachePtr = NULL;
return codePtr;
}
ByteCode *
TclInitByteCodeObj(
Tcl_Obj *objPtr, /* Points object that should be initialized,
* and whose string rep contains the source
* code. */
const Tcl_ObjType *typePtr,
register CompileEnv *envPtr)/* Points to the CompileEnv structure from
* which to create a ByteCode structure. */
{
ByteCode *codePtr;
PreventCycle(objPtr, envPtr);
codePtr = TclInitByteCode(envPtr);
/*
* Free the old internal rep then convert the object to a bytecode object
* by making its internal rep point to the just compiled ByteCode.
*/
TclFreeIntRep(objPtr);
objPtr->internalRep.twoPtrValue.ptr1 = codePtr;
objPtr->typePtr = typePtr;
return codePtr;
}
/*
+3 -5
View File
@@ -1067,6 +1067,7 @@ MODULE_SCOPE ByteCode * TclCompileObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
MODULE_SCOPE int TclAttemptCompileProc(Tcl_Interp *interp,
Tcl_Parse *parsePtr, int depth, Command *cmdPtr,
CompileEnv *envPtr);
MODULE_SCOPE void TclCleanupByteCode(ByteCode *codePtr);
MODULE_SCOPE void TclCleanupStackForBreakContinue(CompileEnv *envPtr,
ExceptionAux *auxPtr);
MODULE_SCOPE void TclCompileCmdWord(Tcl_Interp *interp,
@@ -1118,9 +1119,8 @@ MODULE_SCOPE int TclFixupForwardJump(CompileEnv *envPtr,
int distThreshold);
MODULE_SCOPE void TclFreeCompileEnv(CompileEnv *envPtr);
MODULE_SCOPE void TclFreeJumpFixupArray(JumpFixupArray *fixupArrayPtr);
MODULE_SCOPE ByteCode * TclInitByteCode(CompileEnv *envPtr);
MODULE_SCOPE ByteCode * TclInitByteCodeObj(Tcl_Obj *objPtr,
const Tcl_ObjType *typePtr, CompileEnv *envPtr);
MODULE_SCOPE void TclInitByteCodeObj(Tcl_Obj *objPtr,
CompileEnv *envPtr);
MODULE_SCOPE void TclInitCompileEnv(Tcl_Interp *interp,
CompileEnv *envPtr, const char *string,
int numBytes, const CmdFrame *invoker, int word);
@@ -1157,8 +1157,6 @@ MODULE_SCOPE void TclPushVarName(Tcl_Interp *interp,
Tcl_Token *varTokenPtr, CompileEnv *envPtr,
int flags, int *localIndexPtr,
int *isScalarPtr);
MODULE_SCOPE void TclPreserveByteCode(ByteCode *codePtr);
MODULE_SCOPE void TclReleaseByteCode(ByteCode *codePtr);
MODULE_SCOPE void TclReleaseLiteral(Tcl_Interp *interp, Tcl_Obj *objPtr);
MODULE_SCOPE void TclInvalidateCmdLiteral(Tcl_Interp *interp,
const char *name, Namespace *nsPtr);
-3
View File
@@ -1043,9 +1043,6 @@ TclInitSubsystems(void)
#if USE_TCLALLOC
TclInitAlloc(); /* Process wide mutex init */
#endif
#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
TclpInitAllocCache();
#endif
#ifdef TCL_MEM_DEBUG
TclInitDbCkalloc(); /* Process wide mutex init */
#endif
+25 -23
View File
@@ -35,14 +35,14 @@
#endif
/*
* 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.
* 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.
*/
#ifndef ASYNC_CHECK_COUNT
# define ASYNC_CHECK_COUNT 64
#endif /* !ASYNC_CHECK_COUNT */
#ifndef ASYNC_CHECK_COUNT_MASK
# define ASYNC_CHECK_COUNT_MASK 63
#endif /* !ASYNC_CHECK_COUNT_MASK */
/*
* Boolean flag indicating whether the Tcl bytecode interpreter has been
@@ -1499,9 +1499,11 @@ ExprObjCallback(
*
* Results:
* A (ByteCode *) is returned pointing to the resulting ByteCode.
* The caller must manage its refCount and arrange for a call to
* TclCleanupByteCode() when the last reference disappears.
*
* Side effects:
* The Tcl_ObjType of objPtr is changed to the "exprcode" type,
* The Tcl_ObjType of objPtr is changed to the "bytecode" type,
* and the ByteCode is kept in the internal rep (along with context
* data for checking validity) for faster operations the next time
* CompileExprObj is called on the same value.
@@ -1534,7 +1536,7 @@ CompileExprObj(
|| (codePtr->nsPtr != namespacePtr)
|| (codePtr->nsEpoch != namespacePtr->resolverEpoch)
|| (codePtr->localCachePtr != iPtr->varFramePtr->localCachePtr)) {
TclFreeIntRep(objPtr);
FreeExprCodeInternalRep(objPtr);
}
}
if (objPtr->typePtr != &exprCodeType) {
@@ -1565,8 +1567,10 @@ CompileExprObj(
*/
TclEmitOpcode(INST_DONE, &compEnv);
codePtr = TclInitByteCodeObj(objPtr, &exprCodeType, &compEnv);
TclInitByteCodeObj(objPtr, &compEnv);
objPtr->typePtr = &exprCodeType;
TclFreeCompileEnv(&compEnv);
codePtr = objPtr->internalRep.twoPtrValue.ptr1;
if (iPtr->varFramePtr->localCachePtr) {
codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr;
codePtr->localCachePtr->refCount++;
@@ -1640,7 +1644,10 @@ FreeExprCodeInternalRep(
{
ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
TclReleaseByteCode(codePtr);
objPtr->typePtr = NULL;
if (codePtr->refCount-- <= 1) {
TclCleanupByteCode(codePtr);
}
}
/*
@@ -2026,7 +2033,7 @@ TclNRExecuteByteCode(
* sizeof(void *);
int numWords = (size + sizeof(Tcl_Obj *) - 1) / sizeof(Tcl_Obj *);
TclPreserveByteCode(codePtr);
codePtr->refCount++;
/*
* Reserve the stack, setup the TEBCdataPtr (TD) and CallFrame
@@ -2108,14 +2115,8 @@ TEBCresume(
* sporadically: no special need for speed.
*/
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. */
int instructionCount = 0; /* Counter that is used to work out when to
* call Tcl_AsyncReady() */
const char *curInstName;
#ifdef TCL_COMPILE_DEBUG
int traceInstructions; /* Whether we are doing instruction-level
@@ -2313,11 +2314,10 @@ TEBCresume(
/*
* Check for asynchronous handlers [Bug 746722]; we do the check every
* ASYNC_CHECK_COUNT instructions.
* ASYNC_CHECK_COUNT_MASK instruction, of the form (2**n-1).
*/
if ((--interruptCounter) == 0) {
interruptCounter = ASYNC_CHECK_COUNT;
if ((instructionCount++ & ASYNC_CHECK_COUNT_MASK) == 0) {
DECACHE_STACK_INFO();
if (TclAsyncReady(iPtr)) {
result = Tcl_AsyncInvoke(interp, result);
@@ -8182,7 +8182,9 @@ TEBCresume(
}
iPtr->cmdFramePtr = bcFramePtr->nextPtr;
TclReleaseByteCode(codePtr);
if (codePtr->refCount-- <= 1) {
TclCleanupByteCode(codePtr);
}
TclStackFree(interp, TD); /* free my stack */
return result;
-2
View File
@@ -3133,7 +3133,6 @@ MODULE_SCOPE int TclTrimLeft(const char *bytes, int numBytes,
MODULE_SCOPE int TclTrimRight(const char *bytes, int numBytes,
const char *trim, int numTrim);
MODULE_SCOPE int TclUtfCasecmp(const char *cs, const char *ct);
MODULE_SCOPE int TclUtfCount(int ch);
MODULE_SCOPE Tcl_Obj * TclpNativeToNormalized(ClientData clientData);
MODULE_SCOPE Tcl_Obj * TclpFilesystemPathType(Tcl_Obj *pathPtr);
MODULE_SCOPE int TclpDlopen(Tcl_Interp *interp, Tcl_Obj *pathPtr,
@@ -4085,7 +4084,6 @@ MODULE_SCOPE void TclFreeAllocCache(void *);
MODULE_SCOPE void * TclpGetAllocCache(void);
MODULE_SCOPE void TclpSetAllocCache(void *);
MODULE_SCOPE void TclpFreeAllocMutex(Tcl_Mutex *mutex);
MODULE_SCOPE void TclpInitAllocCache(void);
MODULE_SCOPE void TclpFreeAllocCache(void *);
/*
Regular → Executable
+26
View File
@@ -3416,8 +3416,24 @@ Tcl_LimitCheck(
((iPtr->limit.timeGranularity == 1) ||
(ticker % iPtr->limit.timeGranularity == 0))) {
Tcl_Time now;
#if (_WIN32_WINNT >= 0x0600) && defined(WIN32_USE_TICKCOUNT)
ULONGLONG ticks = GetTickCount64();
now.sec = ticks / 1000;
now.usec = (ticks % 1000) * 1000;
#else
#ifdef HAVE_CLOCK_GETTIME
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) {
clock_gettime(CLOCK_REALTIME, &ts);
}
now.sec = ts.tv_sec;
now.usec = ts.tv_nsec * 1000;
#else
Tcl_GetTime(&now);
#endif
#endif
if (iPtr->limit.time.sec < now.sec ||
(iPtr->limit.time.sec == now.sec &&
iPtr->limit.time.usec < now.usec)) {
@@ -3858,6 +3874,12 @@ Tcl_LimitTypeSet(
int type)
{
Interp *iPtr = (Interp *) interp;
#if (_WIN32_WINNT < 0x0600) && defined(WIN32_USE_TICKCOUNT)
if (type == TCL_LIMIT_TIME) {
/* not implemented for _WIN32 */
return;
}
#endif
iPtr->limit.active |= type;
}
@@ -4382,12 +4404,16 @@ InheritLimitsFromMaster(
slavePtr->limit.cmdCount = 0;
slavePtr->limit.cmdGranularity = masterPtr->limit.cmdGranularity;
}
#if (_WIN32_WINNT < 0x0600) && defined(WIN32_USE_TICKCOUNT)
/* not implemented for _WIN32 */
#else
if (masterPtr->limit.active & TCL_LIMIT_TIME) {
slavePtr->limit.active |= TCL_LIMIT_TIME;
memcpy(&slavePtr->limit.time, &masterPtr->limit.time,
sizeof(Tcl_Time));
slavePtr->limit.timeGranularity = masterPtr->limit.timeGranularity;
}
#endif
}
/*
+2 -3
View File
@@ -320,7 +320,7 @@ const Tcl_HashKeyType tclObjHashKeyType = {
* does allow them to delete a command when references to it are gone, which
* is fragile but useful given their somewhat-OO style. Because of this, this
* structure MUST NOT be const so that the C compiler puts the data in
* writable memory. [Bug 2558422] [Bug 07d13d99b0a9]
* writable memory. [Bug 2558422]
* TODO: Provide a better API for those extensions so that they can coexist...
*/
@@ -4176,8 +4176,7 @@ Tcl_GetCommandFromObj(
* had is invalid one way or another.
*/
/* See [07d13d99b0a9] why we cannot call SetCmdNameFromAny() directly here. */
if (tclCmdNameType.setFromAnyProc(interp, objPtr) != TCL_OK) {
if (SetCmdNameFromAny(interp, objPtr) != TCL_OK) {
return NULL;
}
resPtr = objPtr->internalRep.twoPtrValue.ptr1;
+80 -53
View File
@@ -69,8 +69,9 @@ const Tcl_ObjType tclProcBodyType = {
};
/*
* The [upvar]/[uplevel] level reference type. Uses the longValue field
* to remember the integer value of a parsed #<integer> format.
* The [upvar]/[uplevel] level reference type. Uses the twoPtrValue field,
* encoding the type of level reference in ptr and the actual parsed out
* offset in ptr2.
*
* Uses the default behaviour throughout, and never disposes of the string
* rep; it's just a cache type.
@@ -784,7 +785,7 @@ TclGetFrame(
* Results:
* The return value is -1 if an error occurred in finding the frame (in
* this case an error message is left in the interp's result). 1 is
* returned if objPtr was either an int or an int preceded by "#" and
* returned if objPtr was either a number or a number preceded by "#" and
* it specified a valid frame. 0 is returned if objPtr isn't one of the
* two things above (in this case, the lookup acts as if objPtr were
* "1"). The variable pointed to by framePtrPtr is filled in with the
@@ -806,69 +807,95 @@ TclObjGetFrame(
{
register Interp *iPtr = (Interp *) interp;
int curLevel, level, result;
const char *name = NULL;
CallFrame *framePtr;
const char *name;
/*
* Parse object to figure out which level number to go to.
*/
result = 0;
result = 1;
curLevel = iPtr->varFramePtr->level;
if (objPtr == NULL) {
name = "1";
goto haveLevel1;
}
name = TclGetString(objPtr);
if (objPtr->typePtr == &levelReferenceType) {
if (objPtr->internalRep.twoPtrValue.ptr1) {
level = curLevel - PTR2INT(objPtr->internalRep.twoPtrValue.ptr2);
} else {
level = PTR2INT(objPtr->internalRep.twoPtrValue.ptr2);
}
if (level < 0) {
goto levelError;
}
/* TODO: Consider skipping the typePtr checks */
} else if (objPtr->typePtr == &tclIntType
#ifndef TCL_WIDE_INT_IS_LONG
|| objPtr->typePtr == &tclWideIntType
#endif
) {
if (TclGetIntFromObj(NULL, objPtr, &level) != TCL_OK || level < 0) {
goto levelError;
}
level = curLevel - level;
} else if (*name == '#') {
if (Tcl_GetInt(interp, name+1, &level) != TCL_OK || level < 0) {
goto levelError;
}
/*
* Cache for future reference.
*/
TclFreeIntRep(objPtr);
objPtr->typePtr = &levelReferenceType;
objPtr->internalRep.twoPtrValue.ptr1 = (void *) 0;
objPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(level);
} else if (isdigit(UCHAR(*name))) { /* INTL: digit */
if (Tcl_GetInt(interp, name, &level) != TCL_OK) {
return -1;
}
/*
* Cache for future reference.
*/
TclFreeIntRep(objPtr);
objPtr->typePtr = &levelReferenceType;
objPtr->internalRep.twoPtrValue.ptr1 = (void *) 1;
objPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(level);
level = curLevel - level;
} else {
/*
* Don't cache as the object *isn't* a level reference (might even be
* NULL...)
*/
haveLevel1:
level = curLevel - 1;
result = 0;
}
/*
* Check for integer first, since that has potential to spare us
* a generation of a stringrep.
* Figure out which frame to use, and return it to the caller.
*/
if (objPtr == NULL) {
/* Do nothing */
} else if (TCL_OK == Tcl_GetIntFromObj(NULL, objPtr, &level)
&& (level >= 0)) {
level = curLevel - level;
result = 1;
} else if (objPtr->typePtr == &levelReferenceType) {
level = (int) objPtr->internalRep.longValue;
result = 1;
} else {
name = TclGetString(objPtr);
if (name[0] == '#') {
if (TCL_OK == Tcl_GetInt(NULL, name+1, &level) && level >= 0) {
TclFreeIntRep(objPtr);
objPtr->typePtr = &levelReferenceType;
objPtr->internalRep.longValue = level;
result = 1;
} else {
result = -1;
}
} else if (isdigit(UCHAR(name[0]))) { /* INTL: digit */
/*
* If this were an integer, we'd have succeeded already.
* Docs say we have to treat this as a 'bad level' error.
*/
result = -1;
}
}
if (result == 0) {
level = curLevel - 1;
name = "1";
}
if (result != -1) {
if (level >= 0) {
CallFrame *framePtr;
for (framePtr = iPtr->varFramePtr; framePtr != NULL;
framePtr = framePtr->callerVarPtr) {
if (framePtr->level == level) {
*framePtrPtr = framePtr;
return result;
}
}
}
if (name == NULL) {
name = TclGetString(objPtr);
for (framePtr = iPtr->varFramePtr; framePtr != NULL;
framePtr = framePtr->callerVarPtr) {
if (framePtr->level == level) {
break;
}
}
if (framePtr == NULL) {
goto levelError;
}
*framePtrPtr = framePtr;
return result;
levelError:
Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad level \"%s\"", name));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "STACKLEVEL", NULL);
return -1;
+2 -2
View File
@@ -2967,7 +2967,7 @@ ExtendStringRepWithUnicode(
*/
int i, origLength, size = 0;
char *dst;
char *dst, buf[TCL_UTF_MAX];
String *stringPtr = GET_STRING(objPtr);
if (numChars < 0) {
@@ -2993,7 +2993,7 @@ ExtendStringRepWithUnicode(
}
for (i = 0; i < numChars && size >= 0; i++) {
size += TclUtfCount(unicode[i]);
size += Tcl_UniCharToUtf((int) unicode[i], buf);
}
if (size < 0) {
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
Regular → Executable
+251 -4
View File
@@ -259,7 +259,33 @@ Tcl_CreateTimerHandler(
* Compute when the event should fire.
*/
#ifdef WIN32_USE_TICKCOUNT
#if (_WIN32_WINNT >= 0x0600)
ULONGLONG ticks = GetTickCount64();
time.sec = (long) ((ticks+milliseconds)/1000);
time.usec = (long) (((ticks+milliseconds)%1000)*1000);
#else
if (milliseconds > 0x7FFFFFFF) {
milliseconds = 0x7FFFFFFF;
} else if (milliseconds < 0) {
milliseconds = 0;
}
time.sec = milliseconds + GetTickCount();
time.usec = 0;
#endif
#else
#ifdef HAVE_CLOCK_GETTIME
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) {
clock_gettime(CLOCK_REALTIME, &ts);
}
time.sec = ts.tv_sec;
time.usec = ts.tv_nsec / 1000;
#else
Tcl_GetTime(&time);
#endif
time.sec += milliseconds/1000;
time.usec += (milliseconds%1000)*1000;
if (time.usec >= 1000000) {
@@ -316,9 +342,15 @@ TclCreateAbsoluteTimerHandler(
for (tPtr2 = tsdPtr->firstTimerHandlerPtr, prevPtr = NULL; tPtr2 != NULL;
prevPtr = tPtr2, tPtr2 = tPtr2->nextPtr) {
#if (_WIN32_WINNT < 0x0600) && defined(WIN32_USE_TICKCOUNT)
if (timerHandlerPtr->time.sec - tPtr2->time.sec < 0) {
break;
}
#else
if (TCL_TIME_BEFORE(timerHandlerPtr->time, tPtr2->time)) {
break;
}
#endif
}
timerHandlerPtr->nextPtr = tPtr2;
if (prevPtr == NULL) {
@@ -417,7 +449,46 @@ TimerSetupProc(
* Compute the timeout for the next timer on the list.
*/
#ifdef WIN32_USE_TICKCOUNT
#if (_WIN32_WINNT >= 0x0600)
ULONGLONG ticks = GetTickCount64();
blockTime.sec = (long)
((ULONGLONG) tsdPtr->firstTimerHandlerPtr->time.sec -
(ticks / 1000));
blockTime.usec = (long)
((ULONGLONG) tsdPtr->firstTimerHandlerPtr->time.usec -
(ticks % 1000) * 1000);
if (blockTime.usec < 0) {
blockTime.sec -= 1;
blockTime.usec += 1000000;
}
if (blockTime.sec < 0) {
blockTime.sec = 0;
blockTime.usec = 0;
}
#else
blockTime.sec = tsdPtr->firstTimerHandlerPtr->time.sec - GetTickCount();
if (blockTime.sec <= 0) {
blockTime.sec = 0;
blockTime.usec = 0;
} else {
blockTime.usec = (blockTime.sec % 1000) * 1000;
blockTime.sec /= 1000;
}
#endif
#else
#ifdef HAVE_CLOCK_GETTIME
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) {
clock_gettime(CLOCK_REALTIME, &ts);
}
blockTime.sec = ts.tv_sec;
blockTime.usec = ts.tv_nsec / 1000;
#else
Tcl_GetTime(&blockTime);
#endif
blockTime.sec = tsdPtr->firstTimerHandlerPtr->time.sec - blockTime.sec;
blockTime.usec = tsdPtr->firstTimerHandlerPtr->time.usec -
blockTime.usec;
@@ -429,6 +500,7 @@ TimerSetupProc(
blockTime.sec = 0;
blockTime.usec = 0;
}
#endif
} else {
return;
}
@@ -468,7 +540,46 @@ TimerCheckProc(
* Compute the timeout for the next timer on the list.
*/
#ifdef WIN32_USE_TICKCOUNT
#if (_WIN32_WINNT >= 0x0600)
ULONGLONG ticks = GetTickCount64();
blockTime.sec = (long)
((ULONGLONG) tsdPtr->firstTimerHandlerPtr->time.sec -
(ticks / 1000));
blockTime.usec = (long)
((ULONGLONG) tsdPtr->firstTimerHandlerPtr->time.usec -
(ticks % 1000) * 1000);
if (blockTime.usec < 0) {
blockTime.sec -= 1;
blockTime.usec += 1000000;
}
if (blockTime.sec < 0) {
blockTime.sec = 0;
blockTime.usec = 0;
}
#else
blockTime.sec = tsdPtr->firstTimerHandlerPtr->time.sec - GetTickCount();
if (blockTime.sec <= 0) {
blockTime.sec = 0;
blockTime.usec = 0;
} else {
blockTime.usec = (blockTime.sec % 1000) * 1000;
blockTime.sec /= 1000;
}
#endif
#else
#ifdef HAVE_CLOCK_GETTIME
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) {
clock_gettime(CLOCK_REALTIME, &ts);
}
blockTime.sec = ts.tv_sec;
blockTime.usec = ts.tv_nsec / 1000;
#else
Tcl_GetTime(&blockTime);
#endif
blockTime.sec = tsdPtr->firstTimerHandlerPtr->time.sec - blockTime.sec;
blockTime.usec = tsdPtr->firstTimerHandlerPtr->time.usec -
blockTime.usec;
@@ -480,6 +591,7 @@ TimerCheckProc(
blockTime.sec = 0;
blockTime.usec = 0;
}
#endif
/*
* If the first timer has expired, stick an event on the queue.
@@ -526,6 +638,12 @@ TimerHandlerEventProc(
Tcl_Time time;
int currentTimerId;
ThreadSpecificData *tsdPtr = InitTimer();
#ifdef HAVE_CLOCK_GETTIME
struct timespec ts;
#endif
#if (_WIN32_WINNT >= 0x0600) && defined(WIN32_USE_TICKCOUNT)
ULONGLONG ticks;
#endif
/*
* Do nothing if timers aren't enabled. This leaves the event on the
@@ -564,7 +682,26 @@ TimerHandlerEventProc(
tsdPtr->timerPending = 0;
currentTimerId = tsdPtr->lastTimerId;
#ifdef WIN32_USE_TICKCOUNT
#if (_WIN32_WINNT >= 0x0600)
ticks = GetTickCount64();
time.sec = ticks / 1000;
time.usec = (ticks % 1000) * 1000;
#else
time.sec = GetTickCount();
time.usec = 0;
#endif
#else
#ifdef HAVE_CLOCK_GETTIME
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) {
clock_gettime(CLOCK_REALTIME, &ts);
}
time.sec = ts.tv_sec;
time.usec = ts.tv_nsec / 1000;
#else
Tcl_GetTime(&time);
#endif
#endif
while (1) {
nextPtrPtr = &tsdPtr->firstTimerHandlerPtr;
timerHandlerPtr = tsdPtr->firstTimerHandlerPtr;
@@ -572,10 +709,16 @@ TimerHandlerEventProc(
break;
}
#if (_WIN32_WINNT < 0x0600) && defined(WIN32_USE_TICKCOUNT)
if (time.sec - timerHandlerPtr->time.sec < 0) {
break;
}
#else
if (TCL_TIME_BEFORE(time, timerHandlerPtr->time)) {
break;
}
#endif
/*
* Bail out if the next timer is of a newer generation.
*/
@@ -845,6 +988,13 @@ Tcl_AfterObjCmd(
switch (index) {
case -1: {
#ifdef HAVE_CLOCK_GETTIME
struct timespec ts;
#endif
#if (_WIN32_WINNT >= 0x0600) && defined(WIN32_USE_TICKCOUNT)
ULONGLONG ticks;
#endif
if (ms < 0) {
ms = 0;
}
@@ -872,13 +1022,43 @@ Tcl_AfterObjCmd(
afterPtr->id = tsdPtr->afterId;
tsdPtr->afterId += 1;
+#ifdef WIN32_USE_TICKCOUNT
+#if (_WIN32_WINNT >= 0x0600)
+ ticks = GetTickCount64();
+ wakeup.sec = ticks / 1000;
+ wakeup.usec = (ticks % 1000) * 1000;
+ wakeup.sec += (long)(ms / 1000);
+ wakeup.usec += ((long)(ms % 1000)) * 1000;
+ if (wakeup.usec > 1000000) {
+ wakeup.sec++;
+ wakeup.usec -= 1000000;
+ }
#else
if (ms > 0x7FFFFFFF) {
ms = 0x7FFFFFFF;
} else if (ms < 0) {
ms = 0;
}
wakeup.sec = ms + GetTickCount();
wakeup.usec = 0;
#endif
#else
#ifdef HAVE_CLOCK_GETTIME
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) {
clock_gettime(CLOCK_REALTIME, &ts);
}
wakeup.sec = ts.tv_sec;
wakeup.usec = ts.tv_nsec / 1000;
#else
Tcl_GetTime(&wakeup);
#endif
wakeup.sec += (long)(ms / 1000);
wakeup.usec += ((long)(ms % 1000)) * 1000;
if (wakeup.usec > 1000000) {
wakeup.sec++;
wakeup.usec -= 1000000;
}
#endif
afterPtr->token = TclCreateAbsoluteTimerHandler(&wakeup,
AfterProc, afterPtr);
afterPtr->nextPtr = assocPtr->firstAfterPtr;
@@ -1012,12 +1192,15 @@ AfterDelay(
Tcl_Interp *interp,
Tcl_WideInt ms)
{
Interp *iPtr = (Interp *) interp;
Tcl_Time endTime, now;
#ifdef WIN32_USE_TICKCOUNT
#if (_WIN32_WINNT >= 0x0600)
Interp *iPtr = (Interp *) interp;
ULONGLONG ticks = GetTickCount64();
Tcl_WideInt diff;
Tcl_GetTime(&now);
now.sec = ticks/1000;
now.usec = (ticks%1000)*1000;
endTime = now;
endTime.sec += (long)(ms/1000);
endTime.usec += ((int)(ms%1000))*1000;
@@ -1025,6 +1208,41 @@ AfterDelay(
endTime.sec++;
endTime.usec -= 1000000;
}
#else
int diff;
now.sec = GetTickCount();
now.usec = 0;
if (ms > 0x7FFFFFFF) {
ms = 0x7FFFFFFF;
} else if (ms < 0) {
ms = 0;
}
endTime.sec = now.sec + ms;
endTime.usec = 0;
#endif
#else
Interp *iPtr = (Interp *) interp;
Tcl_WideInt diff;
#ifdef HAVE_CLOCK_GETTIME
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) {
clock_gettime(CLOCK_REALTIME, &ts);
}
now.sec = ts.tv_sec;
now.usec = ts.tv_nsec/1000;
#else
Tcl_GetTime(&now);
#endif
endTime = now;
endTime.sec += (long)(ms/1000);
endTime.usec += ((int)(ms%1000))*1000;
if (endTime.usec >= 1000000) {
endTime.sec++;
endTime.usec -= 1000000;
}
#endif
do {
if (Tcl_AsyncReady()) {
@@ -1035,6 +1253,15 @@ AfterDelay(
if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) {
return TCL_ERROR;
}
#if (_WIN32_WINNT < 0x0600) && defined(WIN32_USE_TICKCOUNT)
diff = endTime.sec - now.sec;
if (diff > 0) {
Tcl_Sleep((long) diff);
} else {
break;
}
now.sec = GetTickCount();
#else
if (iPtr->limit.timeEvent != NULL
&& TCL_TIME_BEFORE(iPtr->limit.time, now)) {
iPtr->limit.granularityTicker = 0;
@@ -1083,8 +1310,28 @@ AfterDelay(
return TCL_ERROR;
}
}
#if (_WIN32_WINNT >= 0x0600) && defined(WIN32_USE_TICKCOUNT)
ticks = GetTickCount64();
now.sec = ticks / 1000;
now.usec = (ticks % 1000) * 1000;
#else
#ifdef HAVE_CLOCK_GETTIME
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) {
clock_gettime(CLOCK_REALTIME, &ts);
}
now.sec = ts.tv_sec;
now.usec = ts.tv_nsec / 1000;
#else
Tcl_GetTime(&now);
} while (TCL_TIME_BEFORE(now, endTime));
#endif
#endif
#endif
}
#if (_WIN32_WINNT < 0x0600) && defined(WIN32_USE_TICKCOUNT)
while (now.sec - endTime.sec < 0);
#else
while (TCL_TIME_BEFORE(now, endTime));
#endif
return TCL_OK;
}
+14 -8
View File
@@ -84,11 +84,17 @@ static const unsigned char totalBytes[256] = {
1,1,1,1
#endif
};
/*
* Functions used only in this module.
*/
static int UtfCount(int ch);
/*
*---------------------------------------------------------------------------
*
* TclUtfCount --
* UtfCount --
*
* Find the number of bytes in the Utf character "ch".
*
@@ -101,8 +107,8 @@ static const unsigned char totalBytes[256] = {
*---------------------------------------------------------------------------
*/
int
TclUtfCount(
INLINE static int
UtfCount(
int ch) /* The Tcl_UniChar whose size is returned. */
{
if ((ch > 0) && (ch < UNICODE_SELF)) {
@@ -137,7 +143,7 @@ TclUtfCount(
*---------------------------------------------------------------------------
*/
int
INLINE int
Tcl_UniCharToUtf(
int ch, /* The Tcl_UniChar to be stored in the
* buffer. */
@@ -823,7 +829,7 @@ Tcl_UtfToUpper(
* char to dst if its size is <= the original char.
*/
if (bytes < TclUtfCount(upChar)) {
if (bytes < UtfCount(upChar)) {
memcpy(dst, src, (size_t) bytes);
dst += bytes;
} else {
@@ -876,7 +882,7 @@ Tcl_UtfToLower(
* char to dst if its size is <= the original char.
*/
if (bytes < TclUtfCount(lowChar)) {
if (bytes < UtfCount(lowChar)) {
memcpy(dst, src, (size_t) bytes);
dst += bytes;
} else {
@@ -926,7 +932,7 @@ Tcl_UtfToTitle(
bytes = TclUtfToUniChar(src, &ch);
titleChar = Tcl_UniCharToTitle(ch);
if (bytes < TclUtfCount(titleChar)) {
if (bytes < UtfCount(titleChar)) {
memcpy(dst, src, (size_t) bytes);
dst += bytes;
} else {
@@ -938,7 +944,7 @@ Tcl_UtfToTitle(
bytes = TclUtfToUniChar(src, &ch);
lowChar = Tcl_UniCharToLower(ch);
if (bytes < TclUtfCount(lowChar)) {
if (bytes < UtfCount(lowChar)) {
memcpy(dst, src, (size_t) bytes);
dst += bytes;
} else {
+90 -10
View File
@@ -202,9 +202,14 @@ MODULE_SCOPE Var * TclLookupSimpleVar(Tcl_Interp *interp,
static Tcl_DupInternalRepProc DupLocalVarName;
static Tcl_FreeInternalRepProc FreeLocalVarName;
static Tcl_UpdateStringProc PanicOnUpdateVarName;
static Tcl_FreeInternalRepProc FreeParsedVarName;
static Tcl_DupInternalRepProc DupParsedVarName;
static Tcl_UpdateStringProc UpdateParsedVarName;
static Tcl_UpdateStringProc PanicOnUpdateVarName;
static Tcl_SetFromAnyProc PanicOnSetVarName;
/*
* Types of Tcl_Objs used to cache variable lookups.
@@ -227,12 +232,12 @@ static Tcl_DupInternalRepProc DupParsedVarName;
static const Tcl_ObjType localVarNameType = {
"localVarName",
FreeLocalVarName, DupLocalVarName, NULL, NULL
FreeLocalVarName, DupLocalVarName, PanicOnUpdateVarName, PanicOnSetVarName
};
static const Tcl_ObjType tclParsedVarNameType = {
"parsedVarName",
FreeParsedVarName, DupParsedVarName, NULL, NULL
FreeParsedVarName, DupParsedVarName, UpdateParsedVarName, PanicOnSetVarName
};
/*
@@ -531,6 +536,7 @@ TclObjLookupVarEx(
const char *errMsg = NULL;
CallFrame *varFramePtr = iPtr->varFramePtr;
const char *part2 = part2Ptr? TclGetString(part2Ptr):NULL;
char *newPart2 = NULL;
*arrayPtrPtr = NULL;
if (typePtr == &localVarNameType) {
@@ -577,7 +583,9 @@ TclObjLookupVarEx(
}
return NULL;
}
if ((part2Ptr = part1Ptr->internalRep.twoPtrValue.ptr2)) {
part2 = newPart2 = part1Ptr->internalRep.twoPtrValue.ptr2;
if (newPart2) {
part2Ptr = Tcl_NewStringObj(newPart2, -1);
if (createPart2) {
Tcl_IncrRefCount(part2Ptr);
}
@@ -621,7 +629,11 @@ TclObjLookupVarEx(
len2 = len1 - i - 2;
len1 = i;
part2Ptr = Tcl_NewStringObj(part2, len2);
newPart2 = ckalloc(len2 + 1);
memcpy(newPart2, part2, (unsigned) len2);
*(newPart2+len2) = '\0';
part2 = newPart2;
part2Ptr = Tcl_NewStringObj(newPart2, -1);
if (createPart2) {
Tcl_IncrRefCount(part2Ptr);
}
@@ -646,8 +658,7 @@ TclObjLookupVarEx(
Tcl_IncrRefCount(part1Ptr);
objPtr->internalRep.twoPtrValue.ptr1 = part1Ptr;
Tcl_IncrRefCount(part2Ptr);
objPtr->internalRep.twoPtrValue.ptr2 = part2Ptr;
objPtr->internalRep.twoPtrValue.ptr2 = (void *) part2;
typePtr = part1Ptr->typePtr;
part1 = TclGetString(part1Ptr);
@@ -672,6 +683,9 @@ TclObjLookupVarEx(
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME",
TclGetString(part1Ptr), NULL);
}
if (newPart2) {
Tcl_DecrRefCount(part2Ptr);
}
return NULL;
}
@@ -720,6 +734,9 @@ TclObjLookupVarEx(
*arrayPtrPtr = varPtr;
varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr, flags, msg,
createPart1, createPart2, varPtr, -1);
if (newPart2) {
Tcl_DecrRefCount(part2Ptr);
}
}
return varPtr;
}
@@ -5500,6 +5517,28 @@ TclObjVarErrMsg(
*----------------------------------------------------------------------
*/
/*
* Panic functions that should never be called in normal operation.
*/
static void
PanicOnUpdateVarName(
Tcl_Obj *objPtr)
{
Tcl_Panic("%s of type %s should not be called", "updateStringProc",
objPtr->typePtr->name);
}
static int
PanicOnSetVarName(
Tcl_Interp *interp,
Tcl_Obj *objPtr)
{
Tcl_Panic("%s of type %s should not be called", "setFromAnyProc",
objPtr->typePtr->name);
return TCL_ERROR;
}
/*
* localVarName -
*
@@ -5553,11 +5592,11 @@ FreeParsedVarName(
Tcl_Obj *objPtr)
{
register Tcl_Obj *arrayPtr = objPtr->internalRep.twoPtrValue.ptr1;
register Tcl_Obj *elem = objPtr->internalRep.twoPtrValue.ptr2;
register char *elem = objPtr->internalRep.twoPtrValue.ptr2;
if (arrayPtr != NULL) {
TclDecrRefCount(arrayPtr);
TclDecrRefCount(elem);
ckfree(elem);
}
objPtr->typePtr = NULL;
}
@@ -5568,17 +5607,58 @@ DupParsedVarName(
Tcl_Obj *dupPtr)
{
register Tcl_Obj *arrayPtr = srcPtr->internalRep.twoPtrValue.ptr1;
register Tcl_Obj *elem = srcPtr->internalRep.twoPtrValue.ptr2;
register char *elem = srcPtr->internalRep.twoPtrValue.ptr2;
char *elemCopy;
unsigned elemLen;
if (arrayPtr != NULL) {
Tcl_IncrRefCount(arrayPtr);
Tcl_IncrRefCount(elem);
elemLen = strlen(elem);
elemCopy = ckalloc(elemLen + 1);
memcpy(elemCopy, elem, elemLen);
*(elemCopy + elemLen) = '\0';
elem = elemCopy;
}
dupPtr->internalRep.twoPtrValue.ptr1 = arrayPtr;
dupPtr->internalRep.twoPtrValue.ptr2 = elem;
dupPtr->typePtr = &tclParsedVarNameType;
}
static void
UpdateParsedVarName(
Tcl_Obj *objPtr)
{
Tcl_Obj *arrayPtr = objPtr->internalRep.twoPtrValue.ptr1;
char *part2 = objPtr->internalRep.twoPtrValue.ptr2;
const char *part1;
char *p;
int len1, len2, totalLen;
if (arrayPtr == NULL) {
/*
* This is a parsed scalar name: what is it doing here?
*/
Tcl_Panic("scalar parsedVarName without a string rep");
}
part1 = TclGetStringFromObj(arrayPtr, &len1);
len2 = strlen(part2);
totalLen = len1 + len2 + 2;
p = ckalloc(totalLen + 1);
objPtr->bytes = p;
objPtr->length = totalLen;
memcpy(p, part1, (unsigned) len1);
p += len1;
*p++ = '(';
memcpy(p, part2, (unsigned) len2);
p += len2;
*p++ = ')';
*p = '\0';
}
/*
*----------------------------------------------------------------------
+4 -5
View File
@@ -1194,12 +1194,11 @@ Tcl_ZlibStreamPut(
zshPtr->stream.next_out = (Bytef *) dataTmp;
e = deflate(&zshPtr->stream, flush);
while (e == Z_BUF_ERROR || (flush == Z_FINISH && e == Z_OK)) {
while (e == Z_BUF_ERROR) {
/*
* Output buffer too small to hold the data being generated or we
* are doing the end-of-stream flush (which can spit out masses of
* data). This means we need to put a new buffer into place after
* saving the old generated data to the outData list.
* Output buffer too small to hold the data being generated; so
* put a new buffer into place after saving the old generated
* data to the outData list.
*/
obj = Tcl_NewByteArrayObj((unsigned char *) dataTmp, outSize);
+4 -56
View File
@@ -4248,7 +4248,7 @@ proc ::tcl::clock::add { clockval args } {
?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?\""
}
if { [catch { expr {wide($clockval)} } result] } {
return -code error "expected integer but got \"$clockval\""
return -code error $result
}
set offsets {}
@@ -4287,6 +4287,9 @@ proc ::tcl::clock::add { clockval args } {
-errorcode [list CLOCK gmtWithTimezone] \
"cannot use -gmt and -timezone in same call"
}
if { [catch { expr { wide($clockval) } } result] } {
return -code error "expected integer but got \"$clockval\""
}
if { ![string is boolean -strict $gmt] } {
return -code error "expected boolean value but got \"$gmt\""
} elseif { $gmt } {
@@ -4323,11 +4326,6 @@ proc ::tcl::clock::add { clockval args } {
$changeover]
}
weekdays - weekday {
set clockval [AddWeekDays $quantity $clockval $timezone \
$changeover]
}
hours - hour {
set clockval [expr { 3600 * $quantity + $clockval }]
}
@@ -4425,56 +4423,6 @@ proc ::tcl::clock::AddMonths { months clockval timezone changeover } {
}
#----------------------------------------------------------------------
#
# AddWeekDays --
#
# Add a given number of week days (skipping Saturdays and Sundays)
# to a given clock value in a given time zone.
#
# Parameters:
# days - Number of days to add (may be negative)
# clockval - Seconds since the epoch before the operation
# timezone - Time zone in which the operation is to be performed
# changeover - Julian Day on which the Gregorian calendar was adopted
# in the target locale.
#
# Results:
# Returns the new clock value as a number of seconds since the epoch.
#
# Side effects:
# None.
#
#----------------------------------------------------------------------
proc ::tcl::clock::AddWeekDays { days clockval timezone changeover } {
if {$days == 0} {
return $clockval
}
set day [format $clockval -format %u]
set weeks [expr {$days / 5}]
set rdays [expr {$days % 5}]
set toAdd [expr {7 * $weeks + $rdays}]
set resDay [expr {$day + ($toAdd % 7)}]
# Adjust if we start from a weekend
if {$day > 5} {
set adj [expr {5 - $day}]
incr toAdd $adj
incr resDay $adj
}
# Adjust if we end up on a weekend
if {$resDay > 5} {
incr toAdd 2
}
AddDays $toAdd $clockval $timezone $changeover
}
#----------------------------------------------------------------------
#
# AddDays --
-1
View File
@@ -6,5 +6,4 @@ set TZData(:America/Caracas) {
{-1826739140 -16200 0 VET}
{-157750200 -14400 0 VET}
{1197183600 -16200 0 VET}
{1462086000 -14400 0 VET}
}
+51 -52
View File
@@ -2,56 +2,55 @@
set TZData(:Asia/Almaty) {
{-9223372036854775808 18468 0 LMT}
{-1441170468 18000 0 +05}
{-1247547600 21600 0 +06}
{354909600 25200 1 +07}
{370717200 21600 0 +06}
{386445600 25200 1 +07}
{402253200 21600 0 +06}
{417981600 25200 1 +07}
{433789200 21600 0 +06}
{449604000 25200 1 +07}
{465336000 21600 0 +06}
{481060800 25200 1 +07}
{496785600 21600 0 +06}
{512510400 25200 1 +07}
{528235200 21600 0 +06}
{543960000 25200 1 +07}
{559684800 21600 0 +06}
{575409600 25200 1 +07}
{591134400 21600 0 +06}
{606859200 25200 1 +07}
{622584000 21600 0 +06}
{638308800 25200 1 +07}
{654638400 21600 0 +06}
{670363200 18000 0 +05}
{670366800 21600 1 +06}
{686091600 18000 0 +05}
{695768400 21600 0 +06}
{701812800 25200 1 +07}
{717537600 21600 0 +06}
{733262400 25200 1 +07}
{748987200 21600 0 +06}
{764712000 25200 1 +07}
{780436800 21600 0 +06}
{796161600 25200 1 +07}
{811886400 21600 0 +06}
{828216000 25200 1 +07}
{846360000 21600 0 +06}
{859665600 25200 1 +07}
{877809600 21600 0 +06}
{891115200 25200 1 +07}
{909259200 21600 0 +06}
{922564800 25200 1 +07}
{941313600 21600 0 +06}
{954014400 25200 1 +07}
{972763200 21600 0 +06}
{985464000 25200 1 +07}
{1004212800 21600 0 +06}
{1017518400 25200 1 +07}
{1035662400 21600 0 +06}
{1048968000 25200 1 +07}
{1067112000 21600 0 +06}
{1080417600 25200 1 +07}
{1099166400 21600 0 +06}
{-1441170468 18000 0 ALMT}
{-1247547600 21600 0 ALMT}
{354909600 25200 1 ALMST}
{370717200 21600 0 ALMT}
{386445600 25200 1 ALMST}
{402253200 21600 0 ALMT}
{417981600 25200 1 ALMST}
{433789200 21600 0 ALMT}
{449604000 25200 1 ALMST}
{465336000 21600 0 ALMT}
{481060800 25200 1 ALMST}
{496785600 21600 0 ALMT}
{512510400 25200 1 ALMST}
{528235200 21600 0 ALMT}
{543960000 25200 1 ALMST}
{559684800 21600 0 ALMT}
{575409600 25200 1 ALMST}
{591134400 21600 0 ALMT}
{606859200 25200 1 ALMST}
{622584000 21600 0 ALMT}
{638308800 25200 1 ALMST}
{654638400 21600 0 ALMT}
{662666400 21600 0 ALMT}
{694202400 21600 0 ALMT}
{701802000 25200 1 ALMST}
{717523200 21600 0 ALMT}
{733262400 25200 1 ALMST}
{748987200 21600 0 ALMT}
{764712000 25200 1 ALMST}
{780436800 21600 0 ALMT}
{796161600 25200 1 ALMST}
{811886400 21600 0 ALMT}
{828216000 25200 1 ALMST}
{846360000 21600 0 ALMT}
{859665600 25200 1 ALMST}
{877809600 21600 0 ALMT}
{891115200 25200 1 ALMST}
{909259200 21600 0 ALMT}
{922564800 25200 1 ALMST}
{941313600 21600 0 ALMT}
{954014400 25200 1 ALMST}
{972763200 21600 0 ALMT}
{985464000 25200 1 ALMST}
{1004212800 21600 0 ALMT}
{1017518400 25200 1 ALMST}
{1035662400 21600 0 ALMT}
{1048968000 25200 1 ALMST}
{1067112000 21600 0 ALMT}
{1080417600 25200 1 ALMST}
{1099166400 21600 0 ALMT}
{1110823200 21600 0 ALMT}
}
+2 -2
View File
@@ -29,8 +29,8 @@ set TZData(:Asia/Anadyr) {
{670345200 43200 1 ANAST}
{686070000 39600 0 ANAT}
{695746800 43200 0 ANAMMTT}
{701791200 46800 1 ANAST}
{717516000 43200 0 ANAT}
{701780400 46800 1 ANAST}
{717501600 43200 0 ANAT}
{733240800 46800 1 ANAST}
{748965600 43200 0 ANAT}
{764690400 46800 1 ANAST}
+53 -54
View File
@@ -2,58 +2,57 @@
set TZData(:Asia/Aqtau) {
{-9223372036854775808 12064 0 LMT}
{-1441164064 14400 0 +04}
{-1247544000 18000 0 +05}
{-220942800 18000 0 +05}
{370724400 21600 0 +06}
{386445600 18000 0 +05}
{386449200 21600 1 +06}
{402256800 18000 0 +05}
{417985200 21600 1 +06}
{433792800 18000 0 +05}
{449607600 21600 1 +06}
{465339600 18000 0 +05}
{481064400 21600 1 +06}
{496789200 18000 0 +05}
{512514000 21600 1 +06}
{528238800 18000 0 +05}
{543963600 21600 1 +06}
{559688400 18000 0 +05}
{575413200 21600 1 +06}
{591138000 18000 0 +05}
{606862800 21600 1 +06}
{622587600 18000 0 +05}
{638312400 21600 1 +06}
{654642000 18000 0 +05}
{670366800 14400 0 +04}
{670370400 18000 1 +05}
{686095200 14400 0 +04}
{695772000 18000 0 +05}
{701816400 21600 1 +06}
{717541200 18000 0 +05}
{733266000 21600 1 +06}
{748990800 18000 0 +05}
{764715600 21600 1 +06}
{780440400 18000 0 +05}
{780444000 14400 0 +04}
{796168800 18000 1 +05}
{811893600 14400 0 +04}
{828223200 18000 1 +05}
{846367200 14400 0 +04}
{859672800 18000 1 +05}
{877816800 14400 0 +04}
{891122400 18000 1 +05}
{909266400 14400 0 +04}
{922572000 18000 1 +05}
{941320800 14400 0 +04}
{954021600 18000 1 +05}
{972770400 14400 0 +04}
{985471200 18000 1 +05}
{1004220000 14400 0 +04}
{1017525600 18000 1 +05}
{1035669600 14400 0 +04}
{1048975200 18000 1 +05}
{1067119200 14400 0 +04}
{1080424800 18000 1 +05}
{1099173600 18000 0 +05}
{-1441164064 14400 0 FORT}
{-1247544000 18000 0 FORT}
{-220942800 18000 0 SHET}
{370724400 21600 0 SHET}
{386445600 18000 0 SHET}
{386449200 21600 1 SHEST}
{402256800 18000 0 SHET}
{417985200 21600 1 SHEST}
{433792800 18000 0 SHET}
{449607600 21600 1 SHEST}
{465339600 18000 0 SHET}
{481064400 21600 1 SHEST}
{496789200 18000 0 SHET}
{512514000 21600 1 SHEST}
{528238800 18000 0 SHET}
{543963600 21600 1 SHEST}
{559688400 18000 0 SHET}
{575413200 21600 1 SHEST}
{591138000 18000 0 SHET}
{606862800 21600 1 SHEST}
{622587600 18000 0 SHET}
{638312400 21600 1 SHEST}
{654642000 18000 0 SHET}
{662670000 18000 0 SHET}
{692823600 18000 0 AQTT}
{701805600 21600 1 AQTST}
{717526800 18000 0 AQTT}
{733266000 21600 1 AQTST}
{748990800 18000 0 AQTT}
{764715600 21600 1 AQTST}
{780440400 18000 0 AQTT}
{796165200 14400 0 AQTT}
{796168800 18000 1 AQTST}
{811893600 14400 0 AQTT}
{828223200 18000 1 AQTST}
{846367200 14400 0 AQTT}
{859672800 18000 1 AQTST}
{877816800 14400 0 AQTT}
{891122400 18000 1 AQTST}
{909266400 14400 0 AQTT}
{922572000 18000 1 AQTST}
{941320800 14400 0 AQTT}
{954021600 18000 1 AQTST}
{972770400 14400 0 AQTT}
{985471200 18000 1 AQTST}
{1004220000 14400 0 AQTT}
{1017525600 18000 1 AQTST}
{1035669600 14400 0 AQTT}
{1048975200 18000 1 AQTST}
{1067119200 14400 0 AQTT}
{1080424800 18000 1 AQTST}
{1099173600 14400 0 AQTT}
{1110830400 18000 0 AQTT}
}
+52 -53
View File
@@ -2,57 +2,56 @@
set TZData(:Asia/Aqtobe) {
{-9223372036854775808 13720 0 LMT}
{-1441165720 14400 0 +04}
{-1247544000 18000 0 +05}
{354913200 21600 1 +06}
{370720800 21600 0 +06}
{386445600 18000 0 +05}
{386449200 21600 1 +06}
{402256800 18000 0 +05}
{417985200 21600 1 +06}
{433792800 18000 0 +05}
{449607600 21600 1 +06}
{465339600 18000 0 +05}
{481064400 21600 1 +06}
{496789200 18000 0 +05}
{512514000 21600 1 +06}
{528238800 18000 0 +05}
{543963600 21600 1 +06}
{559688400 18000 0 +05}
{575413200 21600 1 +06}
{591138000 18000 0 +05}
{606862800 21600 1 +06}
{622587600 18000 0 +05}
{638312400 21600 1 +06}
{654642000 18000 0 +05}
{670366800 14400 0 +04}
{670370400 18000 1 +05}
{686095200 14400 0 +04}
{695772000 18000 0 +05}
{701816400 21600 1 +06}
{717541200 18000 0 +05}
{733266000 21600 1 +06}
{748990800 18000 0 +05}
{764715600 21600 1 +06}
{780440400 18000 0 +05}
{796165200 21600 1 +06}
{811890000 18000 0 +05}
{828219600 21600 1 +06}
{846363600 18000 0 +05}
{859669200 21600 1 +06}
{877813200 18000 0 +05}
{891118800 21600 1 +06}
{909262800 18000 0 +05}
{922568400 21600 1 +06}
{941317200 18000 0 +05}
{954018000 21600 1 +06}
{972766800 18000 0 +05}
{985467600 21600 1 +06}
{1004216400 18000 0 +05}
{1017522000 21600 1 +06}
{1035666000 18000 0 +05}
{1048971600 21600 1 +06}
{1067115600 18000 0 +05}
{1080421200 21600 1 +06}
{1099170000 18000 0 +05}
{-1441165720 14400 0 AKTT}
{-1247544000 18000 0 AKTT}
{354913200 21600 1 AKTST}
{370720800 21600 0 AKTT}
{386445600 18000 0 AKTT}
{386449200 21600 1 AKTST}
{402256800 18000 0 AKTT}
{417985200 21600 1 AKTST}
{433792800 18000 0 AKTT}
{449607600 21600 1 AKTST}
{465339600 18000 0 AKTT}
{481064400 21600 1 AKTST}
{496789200 18000 0 AKTT}
{512514000 21600 1 AKTST}
{528238800 18000 0 AKTT}
{543963600 21600 1 AKTST}
{559688400 18000 0 AKTT}
{575413200 21600 1 AKTST}
{591138000 18000 0 AKTT}
{606862800 21600 1 AKTST}
{622587600 18000 0 AKTT}
{638312400 21600 1 AKTST}
{654642000 18000 0 AKTT}
{662670000 18000 0 AKTT}
{692823600 18000 0 AQTT}
{701805600 21600 1 AQTST}
{717526800 18000 0 AQTT}
{733266000 21600 1 AQTST}
{748990800 18000 0 AQTT}
{764715600 21600 1 AQTST}
{780440400 18000 0 AQTT}
{796165200 21600 1 AQTST}
{811890000 18000 0 AQTT}
{828219600 21600 1 AQTST}
{846363600 18000 0 AQTT}
{859669200 21600 1 AQTST}
{877813200 18000 0 AQTT}
{891118800 21600 1 AQTST}
{909262800 18000 0 AQTT}
{922568400 21600 1 AQTST}
{941317200 18000 0 AQTT}
{954018000 21600 1 AQTST}
{972766800 18000 0 AQTT}
{985467600 21600 1 AQTST}
{1004216400 18000 0 AQTT}
{1017522000 21600 1 AQTST}
{1035666000 18000 0 AQTT}
{1048971600 21600 1 AQTST}
{1067115600 18000 0 AQTT}
{1080421200 21600 1 AQTST}
{1099170000 18000 0 AQTT}
{1110826800 18000 0 AQTT}
}
+1 -1
View File
@@ -27,7 +27,7 @@ set TZData(:Asia/Baku) {
{670370400 14400 1 BAKST}
{683496000 14400 0 AZST}
{686098800 10800 0 AZT}
{701823600 14400 1 AZST}
{701812800 14400 1 AZST}
{717537600 14400 0 AZT}
{820440000 14400 0 AZT}
{828234000 18000 1 AZST}
+2 -2
View File
@@ -28,8 +28,8 @@ set TZData(:Asia/Barnaul) {
{670363200 25200 1 +07}
{686088000 21600 0 +06}
{695764800 25200 0 +08}
{701809200 28800 1 +08}
{717534000 25200 0 +07}
{701798400 28800 1 +08}
{717519600 25200 0 +07}
{733258800 28800 1 +08}
{748983600 25200 0 +07}
{764708400 28800 1 +08}
+2 -2
View File
@@ -28,8 +28,8 @@ set TZData(:Asia/Chita) {
{670356000 32400 1 YAKST}
{686080800 28800 0 YAKT}
{695757600 32400 0 YAKMMTT}
{701802000 36000 1 YAKST}
{717526800 32400 0 YAKT}
{701791200 36000 1 YAKST}
{717512400 32400 0 YAKT}
{733251600 36000 1 YAKST}
{748976400 32400 0 YAKT}
{764701200 36000 1 YAKST}
+2 -2
View File
@@ -29,8 +29,8 @@ set TZData(:Asia/Irkutsk) {
{670359600 28800 1 IRKST}
{686084400 25200 0 IRKT}
{695761200 28800 0 IRKMMTT}
{701805600 32400 1 IRKST}
{717530400 28800 0 IRKT}
{701794800 32400 1 IRKST}
{717516000 28800 0 IRKT}
{733255200 32400 1 IRKST}
{748980000 28800 0 IRKT}
{764704800 32400 1 IRKST}
+2 -2
View File
@@ -28,8 +28,8 @@ set TZData(:Asia/Kamchatka) {
{670345200 43200 1 PETST}
{686070000 39600 0 PETT}
{695746800 43200 0 PETMMTT}
{701791200 46800 1 PETST}
{717516000 43200 0 PETT}
{701780400 46800 1 PETST}
{717501600 43200 0 PETT}
{733240800 46800 1 PETST}
{748965600 43200 0 PETT}
{764690400 46800 1 PETST}
+2 -2
View File
@@ -28,8 +28,8 @@ set TZData(:Asia/Khandyga) {
{670356000 32400 1 YAKST}
{686080800 28800 0 YAKT}
{695757600 32400 0 YAKMMTT}
{701802000 36000 1 YAKST}
{717526800 32400 0 YAKT}
{701791200 36000 1 YAKST}
{717512400 32400 0 YAKT}
{733251600 36000 1 YAKST}
{748976400 32400 0 YAKT}
{764701200 36000 1 YAKST}
+2 -2
View File
@@ -28,8 +28,8 @@ set TZData(:Asia/Krasnoyarsk) {
{670363200 25200 1 KRAST}
{686088000 21600 0 KRAT}
{695764800 25200 0 KRAMMTT}
{701809200 28800 1 KRAST}
{717534000 25200 0 KRAT}
{701798400 28800 1 KRAST}
{717519600 25200 0 KRAT}
{733258800 28800 1 KRAST}
{748983600 25200 0 KRAT}
{764708400 28800 1 KRAST}
+2 -3
View File
@@ -28,8 +28,8 @@ set TZData(:Asia/Magadan) {
{670348800 39600 1 MAGST}
{686073600 36000 0 MAGT}
{695750400 39600 0 MAGMMTT}
{701794800 43200 1 MAGST}
{717519600 39600 0 MAGT}
{701784000 43200 1 MAGST}
{717505200 39600 0 MAGT}
{733244400 43200 1 MAGST}
{748969200 39600 0 MAGT}
{764694000 43200 1 MAGST}
@@ -68,5 +68,4 @@ set TZData(:Asia/Magadan) {
{1288450800 39600 0 MAGT}
{1301151600 43200 0 MAGT}
{1414245600 36000 0 MAGT}
{1461427200 39600 0 MAGT}
}
+2 -2
View File
@@ -28,8 +28,8 @@ set TZData(:Asia/Novokuznetsk) {
{670363200 25200 1 KRAST}
{686088000 21600 0 KRAT}
{695764800 25200 0 KRAMMTT}
{701809200 28800 1 KRAST}
{717534000 25200 0 KRAT}
{701798400 28800 1 KRAST}
{717519600 25200 0 KRAT}
{733258800 28800 1 KRAST}
{748983600 25200 0 KRAT}
{764708400 28800 1 KRAST}
+2 -2
View File
@@ -28,8 +28,8 @@ set TZData(:Asia/Novosibirsk) {
{670363200 25200 1 NOVST}
{686088000 21600 0 NOVT}
{695764800 25200 0 NOVMMTT}
{701809200 28800 1 NOVST}
{717534000 25200 0 NOVT}
{701798400 28800 1 NOVST}
{717519600 25200 0 NOVT}
{733258800 28800 1 NOVST}
{738090000 25200 0 NOVST}
{748987200 21600 0 NOVT}
+2 -2
View File
@@ -28,8 +28,8 @@ set TZData(:Asia/Omsk) {
{670366800 21600 1 OMSST}
{686091600 18000 0 OMST}
{695768400 21600 0 OMSMMTT}
{701812800 25200 1 OMSST}
{717537600 21600 0 OMST}
{701802000 25200 1 OMSST}
{717523200 21600 0 OMST}
{733262400 25200 1 OMSST}
{748987200 21600 0 OMST}
{764712000 25200 1 OMSST}
+53 -53
View File
@@ -2,57 +2,57 @@
set TZData(:Asia/Oral) {
{-9223372036854775808 12324 0 LMT}
{-1441164324 14400 0 +04}
{-1247544000 18000 0 +05}
{354913200 21600 1 +06}
{370720800 21600 0 +06}
{386445600 18000 0 +05}
{386449200 21600 1 +06}
{402256800 18000 0 +05}
{417985200 21600 1 +06}
{433792800 18000 0 +05}
{449607600 21600 1 +06}
{465339600 18000 0 +05}
{481064400 21600 1 +06}
{496789200 18000 0 +05}
{512514000 21600 1 +06}
{528238800 18000 0 +05}
{543963600 21600 1 +06}
{559688400 18000 0 +05}
{575413200 21600 1 +06}
{591138000 18000 0 +05}
{606862800 14400 0 +04}
{606866400 18000 1 +05}
{622591200 14400 0 +04}
{638316000 18000 1 +05}
{654645600 14400 0 +04}
{670370400 18000 1 +05}
{686095200 14400 0 +04}
{701816400 14400 0 +04}
{701820000 18000 1 +05}
{717544800 14400 0 +04}
{733269600 18000 1 +05}
{748994400 14400 0 +04}
{764719200 18000 1 +05}
{780444000 14400 0 +04}
{796168800 18000 1 +05}
{811893600 14400 0 +04}
{828223200 18000 1 +05}
{846367200 14400 0 +04}
{859672800 18000 1 +05}
{877816800 14400 0 +04}
{891122400 18000 1 +05}
{909266400 14400 0 +04}
{922572000 18000 1 +05}
{941320800 14400 0 +04}
{954021600 18000 1 +05}
{972770400 14400 0 +04}
{985471200 18000 1 +05}
{1004220000 14400 0 +04}
{1017525600 18000 1 +05}
{1035669600 14400 0 +04}
{1048975200 18000 1 +05}
{1067119200 14400 0 +04}
{1080424800 18000 1 +05}
{1099173600 18000 0 +05}
{-1441164324 14400 0 URAT}
{-1247544000 18000 0 URAT}
{354913200 21600 1 URAST}
{370720800 21600 0 URAT}
{386445600 18000 0 URAT}
{386449200 21600 1 URAST}
{402256800 18000 0 URAT}
{417985200 21600 1 URAST}
{433792800 18000 0 URAT}
{449607600 21600 1 URAST}
{465339600 18000 0 URAT}
{481064400 21600 1 URAST}
{496789200 18000 0 URAT}
{512514000 21600 1 URAST}
{528238800 18000 0 URAT}
{543963600 21600 1 URAST}
{559688400 18000 0 URAT}
{575413200 21600 1 URAST}
{591138000 18000 0 URAT}
{606862800 14400 0 URAT}
{606866400 18000 1 URAST}
{622591200 14400 0 URAT}
{638316000 18000 1 URAST}
{654645600 14400 0 URAT}
{662673600 14400 0 URAT}
{692827200 14400 0 ORAT}
{701809200 18000 1 ORAST}
{717530400 14400 0 ORAT}
{733269600 18000 1 ORAST}
{748994400 14400 0 ORAT}
{764719200 18000 1 ORAST}
{780444000 14400 0 ORAT}
{796168800 18000 1 ORAST}
{811893600 14400 0 ORAT}
{828223200 18000 1 ORAST}
{846367200 14400 0 ORAT}
{859672800 18000 1 ORAST}
{877816800 14400 0 ORAT}
{891122400 18000 1 ORAST}
{909266400 14400 0 ORAT}
{922572000 18000 1 ORAST}
{941320800 14400 0 ORAT}
{954021600 18000 1 ORAST}
{972770400 14400 0 ORAT}
{985471200 18000 1 ORAST}
{1004220000 14400 0 ORAT}
{1017525600 18000 1 ORAST}
{1035669600 14400 0 ORAT}
{1048975200 18000 1 ORAST}
{1067119200 14400 0 ORAT}
{1080424800 18000 1 ORAST}
{1099173600 14400 0 ORAT}
{1110830400 18000 0 ORAT}
}
+53 -52
View File
@@ -2,56 +2,57 @@
set TZData(:Asia/Qyzylorda) {
{-9223372036854775808 15712 0 LMT}
{-1441167712 14400 0 +04}
{-1247544000 18000 0 +05}
{354913200 21600 1 +06}
{370720800 21600 0 +06}
{386445600 18000 0 +05}
{386449200 21600 1 +06}
{402256800 18000 0 +05}
{417985200 21600 1 +06}
{433792800 18000 0 +05}
{449607600 21600 1 +06}
{465339600 18000 0 +05}
{481064400 21600 1 +06}
{496789200 18000 0 +05}
{512514000 21600 1 +06}
{528238800 18000 0 +05}
{543963600 21600 1 +06}
{559688400 18000 0 +05}
{575413200 21600 1 +06}
{591138000 18000 0 +05}
{606862800 21600 1 +06}
{622587600 18000 0 +05}
{638312400 21600 1 +06}
{654642000 18000 0 +05}
{670366800 14400 0 +04}
{670370400 18000 1 +05}
{701812800 18000 0 +05}
{701816400 21600 1 +06}
{717541200 18000 0 +05}
{733266000 21600 1 +06}
{748990800 18000 0 +05}
{764715600 21600 1 +06}
{780440400 18000 0 +05}
{796165200 21600 1 +06}
{811890000 18000 0 +05}
{828219600 21600 1 +06}
{846363600 18000 0 +05}
{859669200 21600 1 +06}
{877813200 18000 0 +05}
{891118800 21600 1 +06}
{909262800 18000 0 +05}
{922568400 21600 1 +06}
{941317200 18000 0 +05}
{954018000 21600 1 +06}
{972766800 18000 0 +05}
{985467600 21600 1 +06}
{1004216400 18000 0 +05}
{1017522000 21600 1 +06}
{1035666000 18000 0 +05}
{1048971600 21600 1 +06}
{1067115600 18000 0 +05}
{1080421200 21600 1 +06}
{1099170000 21600 0 +06}
{-1441167712 14400 0 KIZT}
{-1247544000 18000 0 KIZT}
{354913200 21600 1 KIZST}
{370720800 21600 0 KIZT}
{386445600 18000 0 KIZT}
{386449200 21600 1 KIZST}
{402256800 18000 0 KIZT}
{417985200 21600 1 KIZST}
{433792800 18000 0 KIZT}
{449607600 21600 1 KIZST}
{465339600 18000 0 KIZT}
{481064400 21600 1 KIZST}
{496789200 18000 0 KIZT}
{512514000 21600 1 KIZST}
{528238800 18000 0 KIZT}
{543963600 21600 1 KIZST}
{559688400 18000 0 KIZT}
{575413200 21600 1 KIZST}
{591138000 18000 0 KIZT}
{606862800 21600 1 KIZST}
{622587600 18000 0 KIZT}
{638312400 21600 1 KIZST}
{654642000 18000 0 KIZT}
{662670000 18000 0 KIZT}
{692823600 18000 0 QYZT}
{695768400 21600 0 QYZT}
{701802000 25200 1 QYZST}
{717523200 21600 0 QYZT}
{733262400 25200 1 QYZST}
{748987200 21600 0 QYZT}
{764712000 25200 1 QYZST}
{780436800 21600 0 QYZT}
{796161600 25200 1 QYZST}
{811886400 21600 0 QYZT}
{828216000 25200 1 QYZST}
{846360000 21600 0 QYZT}
{859665600 25200 1 QYZST}
{877809600 21600 0 QYZT}
{891115200 25200 1 QYZST}
{909259200 21600 0 QYZT}
{922564800 25200 1 QYZST}
{941313600 21600 0 QYZT}
{954014400 25200 1 QYZST}
{972763200 21600 0 QYZT}
{985464000 25200 1 QYZST}
{1004212800 21600 0 QYZT}
{1017518400 25200 1 QYZST}
{1035662400 21600 0 QYZT}
{1048968000 25200 1 QYZST}
{1067112000 21600 0 QYZT}
{1080417600 25200 1 QYZST}
{1099166400 21600 0 QYZT}
{1110823200 21600 0 QYZT}
}
+2 -2
View File
@@ -29,8 +29,8 @@ set TZData(:Asia/Sakhalin) {
{670348800 39600 1 SAKST}
{686073600 36000 0 SAKT}
{695750400 39600 0 SAKMMTT}
{701794800 43200 1 SAKST}
{717519600 39600 0 SAKT}
{701784000 43200 1 SAKST}
{717505200 39600 0 SAKT}
{733244400 43200 1 SAKST}
{748969200 39600 0 SAKT}
{764694000 43200 1 SAKST}
+2 -2
View File
@@ -28,8 +28,8 @@ set TZData(:Asia/Srednekolymsk) {
{670348800 39600 1 MAGST}
{686073600 36000 0 MAGT}
{695750400 39600 0 MAGMMTT}
{701794800 43200 1 MAGST}
{717519600 39600 0 MAGT}
{701784000 43200 1 MAGST}
{717505200 39600 0 MAGT}
{733244400 43200 1 MAGST}
{748969200 39600 0 MAGT}
{764694000 43200 1 MAGST}
-73
View File
@@ -1,73 +0,0 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:Asia/Tomsk) {
{-9223372036854775808 20391 0 LMT}
{-1578807591 21600 0 +06}
{-1247551200 25200 0 +08}
{354906000 28800 1 +08}
{370713600 25200 0 +07}
{386442000 28800 1 +08}
{402249600 25200 0 +07}
{417978000 28800 1 +08}
{433785600 25200 0 +07}
{449600400 28800 1 +08}
{465332400 25200 0 +07}
{481057200 28800 1 +08}
{496782000 25200 0 +07}
{512506800 28800 1 +08}
{528231600 25200 0 +07}
{543956400 28800 1 +08}
{559681200 25200 0 +07}
{575406000 28800 1 +08}
{591130800 25200 0 +07}
{606855600 28800 1 +08}
{622580400 25200 0 +07}
{638305200 28800 1 +08}
{654634800 25200 0 +07}
{670359600 21600 0 +07}
{670363200 25200 1 +07}
{686088000 21600 0 +06}
{695764800 25200 0 +08}
{701809200 28800 1 +08}
{717534000 25200 0 +07}
{733258800 28800 1 +08}
{748983600 25200 0 +07}
{764708400 28800 1 +08}
{780433200 25200 0 +07}
{796158000 28800 1 +08}
{811882800 25200 0 +07}
{828212400 28800 1 +08}
{846356400 25200 0 +07}
{859662000 28800 1 +08}
{877806000 25200 0 +07}
{891111600 28800 1 +08}
{909255600 25200 0 +07}
{922561200 28800 1 +08}
{941310000 25200 0 +07}
{954010800 28800 1 +08}
{972759600 25200 0 +07}
{985460400 28800 1 +08}
{1004209200 25200 0 +07}
{1017514800 28800 1 +08}
{1020196800 25200 0 +07}
{1035662400 21600 0 +06}
{1048968000 25200 1 +07}
{1067112000 21600 0 +06}
{1080417600 25200 1 +07}
{1099166400 21600 0 +06}
{1111867200 25200 1 +07}
{1130616000 21600 0 +06}
{1143316800 25200 1 +07}
{1162065600 21600 0 +06}
{1174766400 25200 1 +07}
{1193515200 21600 0 +06}
{1206820800 25200 1 +07}
{1224964800 21600 0 +06}
{1238270400 25200 1 +07}
{1256414400 21600 0 +06}
{1269720000 25200 1 +07}
{1288468800 21600 0 +06}
{1301169600 25200 0 +07}
{1414263600 21600 0 +06}
{1464465600 25200 0 +07}
}
+2 -2
View File
@@ -27,8 +27,8 @@ set TZData(:Asia/Ust-Nera) {
{670348800 39600 1 MAGST}
{686073600 36000 0 MAGT}
{695750400 39600 0 MAGMMTT}
{701794800 43200 1 MAGST}
{717519600 39600 0 MAGT}
{701784000 43200 1 MAGST}
{717505200 39600 0 MAGT}
{733244400 43200 1 MAGST}
{748969200 39600 0 MAGT}
{764694000 43200 1 MAGST}
+2 -2
View File
@@ -28,8 +28,8 @@ set TZData(:Asia/Vladivostok) {
{670352400 36000 1 VLAST}
{686077200 32400 0 VLAT}
{695754000 36000 0 VLAMMTT}
{701798400 39600 1 VLAST}
{717523200 36000 0 VLAT}
{701787600 39600 1 VLAST}
{717508800 36000 0 VLAT}
{733248000 39600 1 VLAST}
{748972800 36000 0 VLAT}
{764697600 39600 1 VLAST}
+2 -2
View File
@@ -28,8 +28,8 @@ set TZData(:Asia/Yakutsk) {
{670356000 32400 1 YAKST}
{686080800 28800 0 YAKT}
{695757600 32400 0 YAKMMTT}
{701802000 36000 1 YAKST}
{717526800 32400 0 YAKT}
{701791200 36000 1 YAKST}
{717512400 32400 0 YAKT}
{733251600 36000 1 YAKST}
{748976400 32400 0 YAKT}
{764701200 36000 1 YAKST}
+2 -2
View File
@@ -29,8 +29,8 @@ set TZData(:Asia/Yekaterinburg) {
{670370400 18000 1 SVEST}
{686095200 14400 0 SVET}
{695772000 18000 0 YEKMMTT}
{701816400 21600 1 YEKST}
{717541200 18000 0 YEKT}
{701805600 21600 1 YEKST}
{717526800 18000 0 YEKT}
{733266000 21600 1 YEKST}
{748990800 18000 0 YEKT}
{764715600 21600 1 YEKST}
+3 -3
View File
@@ -27,8 +27,8 @@ set TZData(:Asia/Yerevan) {
{670370400 14400 1 YERST}
{685569600 14400 0 AMST}
{686098800 10800 0 AMT}
{701823600 14400 1 AMST}
{717548400 10800 0 AMT}
{701812800 14400 1 AMST}
{717534000 10800 0 AMT}
{733273200 14400 1 AMST}
{748998000 10800 0 AMT}
{764722800 14400 1 AMST}
@@ -66,5 +66,5 @@ set TZData(:Asia/Yerevan) {
{1288476000 14400 0 AMT}
{1301176800 18000 1 AMST}
{1319925600 14400 0 AMT}
{1328731200 14400 0 AMT}
{1332626400 14400 0 AMT}
}
+2 -3
View File
@@ -26,9 +26,8 @@ set TZData(:Europe/Astrakhan) {
{638319600 14400 1 +04}
{654649200 10800 0 +03}
{670374000 14400 0 +04}
{701820000 10800 0 +04}
{701823600 14400 1 +04}
{717548400 10800 0 +03}
{701820000 14400 0 +04}
{717534000 10800 0 +03}
{733273200 14400 1 +04}
{748998000 10800 0 +03}
{764722800 14400 1 +04}
+2 -2
View File
@@ -42,8 +42,8 @@ set TZData(:Europe/Kaliningrad) {
{654652800 7200 0 EET}
{670377600 10800 1 EEST}
{686102400 7200 0 EET}
{701827200 10800 1 EEST}
{717552000 7200 0 EET}
{701816400 10800 1 EEST}
{717537600 7200 0 EET}
{733276800 10800 1 EEST}
{749001600 7200 0 EET}
{764726400 10800 1 EEST}
-70
View File
@@ -1,70 +0,0 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:Europe/Kirov) {
{-9223372036854775808 11928 0 LMT}
{-1593825528 10800 0 +03}
{-1247540400 14400 0 +05}
{354916800 18000 1 +05}
{370724400 14400 0 +04}
{386452800 18000 1 +05}
{402260400 14400 0 +04}
{417988800 18000 1 +05}
{433796400 14400 0 +04}
{449611200 18000 1 +05}
{465343200 14400 0 +04}
{481068000 18000 1 +05}
{496792800 14400 0 +04}
{512517600 18000 1 +05}
{528242400 14400 0 +04}
{543967200 18000 1 +05}
{559692000 14400 0 +04}
{575416800 18000 1 +05}
{591141600 14400 0 +04}
{606866400 10800 0 +04}
{606870000 14400 1 +04}
{622594800 10800 0 +03}
{638319600 14400 1 +04}
{654649200 10800 0 +03}
{670374000 14400 0 +04}
{701820000 10800 0 +04}
{701823600 14400 1 +04}
{717548400 10800 0 +03}
{733273200 14400 1 +04}
{748998000 10800 0 +03}
{764722800 14400 1 +04}
{780447600 10800 0 +03}
{796172400 14400 1 +04}
{811897200 10800 0 +03}
{828226800 14400 1 +04}
{846370800 10800 0 +03}
{859676400 14400 1 +04}
{877820400 10800 0 +03}
{891126000 14400 1 +04}
{909270000 10800 0 +03}
{922575600 14400 1 +04}
{941324400 10800 0 +03}
{954025200 14400 1 +04}
{972774000 10800 0 +03}
{985474800 14400 1 +04}
{1004223600 10800 0 +03}
{1017529200 14400 1 +04}
{1035673200 10800 0 +03}
{1048978800 14400 1 +04}
{1067122800 10800 0 +03}
{1080428400 14400 1 +04}
{1099177200 10800 0 +03}
{1111878000 14400 1 +04}
{1130626800 10800 0 +03}
{1143327600 14400 1 +04}
{1162076400 10800 0 +03}
{1174777200 14400 1 +04}
{1193526000 10800 0 +03}
{1206831600 14400 1 +04}
{1224975600 10800 0 +03}
{1238281200 14400 1 +04}
{1256425200 10800 0 +03}
{1269730800 14400 1 +04}
{1288479600 10800 0 +03}
{1301180400 14400 0 +04}
{1414274400 10800 0 +03}
}
+1 -2
View File
@@ -33,8 +33,7 @@ set TZData(:Europe/Minsk) {
{670374000 10800 1 EEST}
{686102400 7200 0 EET}
{701820000 10800 1 EEST}
{717544800 10800 0 EEST}
{717552000 7200 0 EET}
{717544800 7200 0 EET}
{733276800 10800 1 EEST}
{749001600 7200 0 EET}
{764726400 10800 1 EEST}
+2 -2
View File
@@ -40,8 +40,8 @@ set TZData(:Europe/Moscow) {
{670377600 10800 1 EEST}
{686102400 7200 0 EET}
{695779200 10800 0 MSD}
{701823600 14400 1 MSD}
{717548400 10800 0 MSK}
{701812800 14400 1 MSD}
{717534000 10800 0 MSK}
{733273200 14400 1 MSD}
{748998000 10800 0 MSK}
{764722800 14400 1 MSD}
+2 -2
View File
@@ -30,8 +30,8 @@ set TZData(:Europe/Samara) {
{670377600 10800 1 EEST}
{686102400 10800 0 SAMT}
{687916800 14400 0 SAMT}
{701820000 18000 1 SAMST}
{717544800 14400 0 SAMT}
{701809200 18000 1 SAMST}
{717530400 14400 0 SAMT}
{733269600 18000 1 SAMST}
{748994400 14400 0 SAMT}
{764719200 18000 1 SAMST}
+2 -2
View File
@@ -29,8 +29,8 @@ set TZData(:Europe/Ulyanovsk) {
{670377600 10800 1 +03}
{686102400 7200 0 +02}
{695779200 10800 0 +04}
{701823600 14400 1 +04}
{717548400 10800 0 +03}
{701812800 14400 1 +04}
{717534000 10800 0 +03}
{733273200 14400 1 +04}
{748998000 10800 0 +03}
{764722800 14400 1 +04}
+2 -3
View File
@@ -28,9 +28,8 @@ set TZData(:Europe/Volgograd) {
{638319600 14400 1 VOLST}
{654649200 10800 0 VOLT}
{670374000 14400 0 VOLT}
{701820000 10800 0 MSD}
{701823600 14400 1 MSD}
{717548400 10800 0 MSK}
{701820000 14400 0 MSD}
{717534000 10800 0 MSK}
{733273200 14400 1 MSD}
{748998000 10800 0 MSK}
{764722800 14400 1 MSD}
-55
View File
@@ -34992,10 +34992,6 @@ test clock-29.1800 {time parsing} {
} 86399
# END testcases29
# BEGIN testcases30
# Test [clock add]
test clock-30.1 {clock add years} {
set t [clock scan 2000-01-01 -format %Y-%m-%d -timezone :UTC]
set f [clock add $t 1 year -timezone :UTC]
@@ -35222,57 +35218,6 @@ test clock-30.25 {clock add seconds at DST conversion} {
set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
} {2004-10-31 01:00:00 -0500}
test clock-30.26 {clock add weekdays} {
set t [clock scan {2013-11-20}] ;# Wednesday
set f1 [clock add $t 3 weekdays]
set x1 [clock format $f1 -format {%Y-%m-%d}]
} {2013-11-25}
test clock-30.27 {clock add weekdays starting on Saturday} {
set t [clock scan {2013-11-23}] ;# Saturday
set f1 [clock add $t 1 weekday]
set x1 [clock format $f1 -format {%Y-%m-%d}]
} {2013-11-25}
test clock-30.28 {clock add weekdays starting on Sunday} {
set t [clock scan {2013-11-24}] ;# Sunday
set f1 [clock add $t 1 weekday]
set x1 [clock format $f1 -format {%Y-%m-%d}]
} {2013-11-25}
test clock-30.29 {clock add 0 weekdays starting on a weekend} {
set t [clock scan {2016-02-27}] ;# Saturday
set f1 [clock add $t 0 weekdays]
set x1 [clock format $f1 -format {%Y-%m-%d}]
} {2016-02-27}
test clock-30.30 {clock add weekdays and back} -body {
set n [clock seconds]
# we start on each day of the week
for {set i 0} {$i < 7} {incr i} {
set start [clock add $n $i days]
set startu [clock format $start -format %u]
# add 0 - 100 weekdays
for {set j 0} {$j < 100} {incr j} {
set forth [clock add $start $j weekdays]
set back [clock add $forth -$j weekdays]
# If $s was a weekday or $j was 0, $b must be the same day.
# Otherwise, $b must be the immediately preceeding Friday
set fail 0
if {$j == 0 || $startu < 6} {
if {$start != $back} { set fail 1}
} else {
set friday [clock add $start -[expr {$startu % 5}] days]
if {$friday != $back} { set fail 1 }
}
if {$fail} {
set sdate [clock format $start -format {%Y-%m-%d}]
set bdate [clock format $back -format {%Y-%m-%d}]
return "$sdate + $j - $j := $bdate"
}
}
}
return "OK"
} -result {OK}
# END testcases30
test clock-31.1 {system locale} \
-constraints win \
+3 -40
View File
@@ -98,12 +98,7 @@ test lreplace-1.26 {lreplace command} {
[set foo [lreplace $foo end end]] \
[set foo [lreplace $foo end end]]
} {a {} {}}
test lreplace-1.27 {lreplace command} {
lreplace x 1 1
} x
test lreplace-1.28 {lreplace command} {
lreplace x 1 1 y
} {x y}
test lreplace-2.1 {lreplace errors} {
list [catch lreplace msg] $msg
@@ -124,8 +119,8 @@ test lreplace-2.6 {lreplace errors} {
list [catch {lreplace x 3 2} msg] $msg
} {1 {list doesn't contain element 3}}
test lreplace-2.7 {lreplace errors} {
list [catch {lreplace x 2 2} msg] $msg
} {1 {list doesn't contain element 2}}
list [catch {lreplace x 1 1} msg] $msg
} {1 {list doesn't contain element 1}}
test lreplace-3.1 {lreplace won't modify shared argument objects} {
proc p {} {
@@ -186,12 +181,6 @@ test lreplace-4.11 {lreplace end index first} {
test lreplace-4.12 {lreplace end index first} {
lreplace {0 1 2 3 4} end-2 2 a b c
} {0 1 a b c 3 4}
test lreplace-4.13 {lreplace empty list} {
lreplace {} 1 1 1
} 1
test lreplace-4.14 {lreplace empty list} {
lreplace {} 2 2 2
} 2
test lreplace-5.1 {compiled lreplace: Bug 47ac84309b} {
apply {x {
@@ -203,32 +192,6 @@ test lreplace-5.2 {compiled lreplace: Bug 47ac84309b} {
lreplace $x end 0 A
}} {a b c}
} {a b A c}
# Testing for compiled behaviour. Far too many variations to check with
# spelt-out tests. Note that this *just* checks whether the compiled version
# and the interpreted version are the same, not whether the interpreted
# version is correct.
apply {{} {
set lss {{} {a} {a b c} {a b c d}}
set ins {{} A {A B}}
set idxs {-2 -1 0 1 2 3 end-3 end-2 end-1 end end+1 end+2}
set lreplace lreplace
foreach ls $lss {
foreach a $idxs {
foreach b $idxs {
foreach i $ins {
set expected [list [catch {$lreplace $ls $a $b {*}$i} m] $m]
set tester [list lreplace $ls $a $b {*}$i]
set script [list catch $tester m]
set script "list \[$script\] \$m"
test lreplace-6.[incr n] {lreplace battery} \
[list apply [list {} $script]] $expected
}
}
}
}
}}
# cleanup
catch {unset foo}
-99
View File
@@ -101,105 +101,6 @@ test uplevel-4.4 {error: not enough args} -returnCodes error -body {
uplevel 1
}}
} -result {wrong # args: should be "uplevel ?level? command ?arg ...?"}
test uplevel-4.5 {level parsing} {
apply {{} {uplevel 0 {}}}
} {}
test uplevel-4.6 {level parsing} {
apply {{} {uplevel #0 {}}}
} {}
test uplevel-4.7 {level parsing} {
apply {{} {uplevel [expr 0] {}}}
} {}
test uplevel-4.8 {level parsing} {
apply {{} {uplevel #[expr 0] {}}}
} {}
test uplevel-4.9 {level parsing} {
apply {{} {uplevel -0 {}}}
} {}
test uplevel-4.10 {level parsing} {
apply {{} {uplevel #-0 {}}}
} {}
test uplevel-4.11 {level parsing} {
apply {{} {uplevel [expr -0] {}}}
} {}
test uplevel-4.12 {level parsing} {
apply {{} {uplevel #[expr -0] {}}}
} {}
test uplevel-4.13 {level parsing} {
apply {{} {uplevel 1 {}}}
} {}
test uplevel-4.14 {level parsing} {
apply {{} {uplevel #1 {}}}
} {}
test uplevel-4.15 {level parsing} {
apply {{} {uplevel [expr 1] {}}}
} {}
test uplevel-4.16 {level parsing} {
apply {{} {uplevel #[expr 1] {}}}
} {}
test uplevel-4.17 {level parsing} {
apply {{} {uplevel -0xffffffff {}}}
} {}
test uplevel-4.18 {level parsing} {
apply {{} {uplevel #-0xffffffff {}}}
} {}
test uplevel-4.19 {level parsing} {
apply {{} {uplevel [expr -0xffffffff] {}}}
} {}
test uplevel-4.20 {level parsing} {
apply {{} {uplevel #[expr -0xffffffff] {}}}
} {}
test uplevel-4.21 {level parsing} -body {
apply {{} {uplevel -1 {}}}
} -returnCodes error -result {invalid command name "-1"}
test uplevel-4.22 {level parsing} -body {
apply {{} {uplevel #-1 {}}}
} -returnCodes error -result {bad level "#-1"}
test uplevel-4.23 {level parsing} -body {
apply {{} {uplevel [expr -1] {}}}
} -returnCodes error -result {invalid command name "-1"}
test uplevel-4.24 {level parsing} -body {
apply {{} {uplevel #[expr -1] {}}}
} -returnCodes error -result {bad level "#-1"}
test uplevel-4.25 {level parsing} -body {
apply {{} {uplevel 0xffffffff {}}}
} -returnCodes error -result {bad level "0xffffffff"}
test uplevel-4.26 {level parsing} -body {
apply {{} {uplevel #0xffffffff {}}}
} -returnCodes error -result {bad level "#0xffffffff"}
test uplevel-4.27 {level parsing} -body {
apply {{} {uplevel [expr 0xffffffff] {}}}
} -returnCodes error -result {bad level "4294967295"}
test uplevel-4.28 {level parsing} -body {
apply {{} {uplevel #[expr 0xffffffff] {}}}
} -returnCodes error -result {bad level "#4294967295"}
test uplevel-4.29 {level parsing} -body {
apply {{} {uplevel 0.2 {}}}
} -returnCodes error -result {bad level "0.2"}
test uplevel-4.30 {level parsing} -body {
apply {{} {uplevel #0.2 {}}}
} -returnCodes error -result {bad level "#0.2"}
test uplevel-4.31 {level parsing} -body {
apply {{} {uplevel [expr 0.2] {}}}
} -returnCodes error -result {bad level "0.2"}
test uplevel-4.32 {level parsing} -body {
apply {{} {uplevel #[expr 0.2] {}}}
} -returnCodes error -result {bad level "#0.2"}
test uplevel-4.33 {level parsing} -body {
apply {{} {uplevel .2 {}}}
} -returnCodes error -result {invalid command name ".2"}
test uplevel-4.34 {level parsing} -body {
apply {{} {uplevel #.2 {}}}
} -returnCodes error -result {bad level "#.2"}
test uplevel-4.35 {level parsing} -body {
apply {{} {uplevel [expr .2] {}}}
} -returnCodes error -result {bad level "0.2"}
test uplevel-4.36 {level parsing} -body {
apply {{} {uplevel #[expr .2] {}}}
} -returnCodes error -result {bad level "#0.2"}
proc a2 {} {
uplevel a3
+1 -1
View File
@@ -302,7 +302,7 @@ test utf-21.1 {TclUniCharIsAlnum} {
} {1}
test utf-21.2 {unicode alnum char in regc_locale.c} {
# this returns 1 with Unicode 7 compliance
list [regexp {^[[:alnum:]]+$} \u1040\u021f\u0220] [regexp {^\w+$} \u1040\u021f\u0220_\u203f\u2040\u2054\ufe33\ufe34\ufe4d\ufe4e\ufe4f\uff3f]
list [regexp {^[[:alnum:]]+$} \u1040\u021f\u0220] [regexp {^\w+$} \u1040\u021f\u0220]
} {1 1}
test utf-21.3 {unicode print char in regc_locale.c} {
# this returns 1 with Unicode 7 compliance
-18
View File
@@ -875,24 +875,6 @@ test zlib-11.3 {Bug 3595576 variant} -setup {
} -cleanup {
removeFile $file
} -returnCodes error -result {can't set "noSuchNs::foo": parent namespace doesn't exist}
test zlib-12.1 {Tk Bug 9eb55debc5} -constraints zlib -setup {
set stream [zlib stream compress]
} -body {
for {set opts {};set y 0} {$y < 60} {incr y} {
for {set line {};set x 0} {$x < 100} {incr x} {
append line [binary format ccc $x $y 128]
}
if {$y == 59} {
set opts -finalize
}
$stream put {*}$opts $line
}
set data [$stream get]
list [string length $data] [string length [zlib decompress $data]]
} -cleanup {
$stream close
} -result {12026 18000}
::tcltest::cleanupTests
return
+54 -1
View File
@@ -4209,7 +4209,7 @@ $as_echo "$as_me: WARNING: Don't know how to find pthread lib on your system - y
ac_saved_libs=$LIBS
LIBS="$LIBS $THREADS_LIBS"
for ac_func in pthread_attr_setstacksize pthread_atfork
for ac_func in pthread_attr_setstacksize pthread_atfork pthread_condattr_setclock
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -4509,6 +4509,59 @@ fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5
$as_echo_n "checking for clock_gettime in -lrt... " >&6; }
if ${ac_cv_lib_rt_clock_gettime+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lrt $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char clock_gettime ();
int
main ()
{
return clock_gettime ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_rt_clock_gettime=yes
else
ac_cv_lib_rt_clock_gettime=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5
$as_echo "$ac_cv_lib_rt_clock_gettime" >&6; }
if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then :
LIBS="$LIBS -lrt"
fi
for ac_func in clock_gettime clock_nanosleep
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
done
# Add the threads support libraries
LIBS="$LIBS$THREADS_LIBS"
Regular → Executable
+3 -1
View File
@@ -678,7 +678,7 @@ AC_DEFUN([SC_ENABLE_THREADS], [
ac_saved_libs=$LIBS
LIBS="$LIBS $THREADS_LIBS"
AC_CHECK_FUNCS(pthread_attr_setstacksize pthread_atfork)
AC_CHECK_FUNCS(pthread_attr_setstacksize pthread_atfork pthread_condattr_setclock)
LIBS=$ac_saved_libs
else
TCL_THREADS=0
@@ -2539,6 +2539,8 @@ AC_DEFUN([SC_TCL_LINK_LIBS], [
fi
AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
[LIBS="$LIBS -lnsl"])])
AC_CHECK_LIB(rt, clock_gettime, [LIBS="$LIBS -lrt"])
AC_CHECK_FUNCS(clock_gettime clock_nanosleep)
])
#--------------------------------------------------------------------
Regular → Executable
+6
View File
@@ -19,6 +19,9 @@
/* Define to 1 if you have the `chflags' function. */
#undef HAVE_CHFLAGS
/* Define to 1 if you have the `clock_gettime' function. */
#undef HAVE_CLOCK_GETTIME
/* Define to 1 if you have the `copyfile' function. */
#undef HAVE_COPYFILE
@@ -169,6 +172,9 @@
/* Define to 1 if you have the `pthread_attr_setstacksize' function. */
#undef HAVE_PTHREAD_ATTR_SETSTACKSIZE
/* Define to 1 if you have the `pthread_condattr_setclock' function. */
#undef HAVE_PTHREAD_CONDATTR_SETCLOCK
/* Does putenv() copy strings or incorporate them by reference? */
#undef HAVE_PUTENV_THAT_COPIES
Regular → Executable
+20 -1
View File
@@ -1763,12 +1763,16 @@ TclUnixWaitForFile(
* at all, and a value of -1 means wait
* forever. */
{
Tcl_Time abortTime = {0, 0}, now; /* silence gcc 4 warning */
Tcl_Time abortTime = {0, 0}, now = { 0, 0 }; /* silence gcc 4 warning */
struct timeval blockTime, *timeoutPtr;
int numFound, result = 0;
fd_set readableMask;
fd_set writableMask;
fd_set exceptionMask;
#ifdef HAVE_CLOCK_GETTIME
int monoClock = 1;
struct timespec ts;
#endif
#ifndef _DARWIN_C_SOURCE
/*
@@ -1787,7 +1791,16 @@ TclUnixWaitForFile(
*/
if (timeout > 0) {
#ifdef HAVE_CLOCK_GETTIME
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) {
clock_gettime(CLOCK_REALTIME, &ts);
monoClock = 0;
}
now.sec = ts.tv_sec;
now.usec = ts.tv_nsec / 1000;
#else
Tcl_GetTime(&now);
#endif
abortTime.sec = now.sec + timeout/1000;
abortTime.usec = now.usec + (timeout%1000)*1000;
if (abortTime.usec >= 1000000) {
@@ -1876,7 +1889,13 @@ TclUnixWaitForFile(
* The select returned early, so we need to recompute the timeout.
*/
#ifdef HAVE_CLOCK_GETTIME
clock_gettime(monoClock ? CLOCK_MONOTONIC : CLOCK_REALTIME, &ts);
now.sec = ts.tv_sec;
now.usec = ts.tv_nsec / 1000;
#else
Tcl_GetTime(&now);
#endif
if ((abortTime.sec < now.sec)
|| (abortTime.sec==now.sec && abortTime.usec<=now.usec)) {
break;
Regular → Executable
+18
View File
@@ -42,7 +42,19 @@ Tcl_Sleep(
* time really has elapsed. If it's too early, go back to sleep again.
*/
#ifdef HAVE_CLOCK_GETTIME
int monoClock = 1;
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) {
clock_gettime(CLOCK_REALTIME, &ts);
monoClock = 0;
}
before.sec = ts.tv_sec;
before.usec = ts.tv_nsec / 1000;
#else
Tcl_GetTime(&before);
#endif
after = before;
after.sec += ms/1000;
after.usec += (ms%1000)*1000;
@@ -81,7 +93,13 @@ Tcl_Sleep(
}
(void) select(0, (SELECT_MASK *) 0, (SELECT_MASK *) 0,
(SELECT_MASK *) 0, &delay);
#ifdef HAVE_CLOCK_GETTIME
clock_gettime(monoClock ? CLOCK_MONOTONIC : CLOCK_REALTIME, &ts);
before.sec = ts.tv_sec;
before.usec = ts.tv_nsec / 1000;
#else
Tcl_GetTime(&before);
#endif
}
}
Regular → Executable
+40 -7
View File
@@ -100,6 +100,9 @@ typedef struct ThreadSpecificData {
pthread_cond_t waitCV; /* Any other thread alerts a notifier that an
* event is ready to be processed by signaling
* this condition variable. */
#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK)
int monoClock; /* When true use CLOCK_MONOTONIC */
#endif
#endif /* __CYGWIN__ */
int waitCVinitialized; /* Variable to flag initialization of the structure */
int eventReady; /* True if an event is ready to be processed.
@@ -352,8 +355,25 @@ Tcl_InitNotifier(void)
TclWinGetTclInstance(), NULL);
tsdPtr->event = CreateEventW(NULL, 1 /* manual */,
0 /* !signaled */, NULL);
#else
#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK)
pthread_condattr_t attr;
pthread_condattr_init(&attr);
tsdPtr->monoClock =
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) == 0;
if (tsdPtr->monoClock) {
if (pthread_cond_init(&tsdPtr->waitCV, &attr)) {
tsdPtr->monoClock = 0;
pthread_cond_init(&tsdPtr->waitCV, NULL);
}
} else {
pthread_cond_init(&tsdPtr->waitCV, NULL);
}
pthread_condattr_destroy(&attr);
#else
pthread_cond_init(&tsdPtr->waitCV, NULL);
#endif
#endif /* __CYGWIN__ */
tsdPtr->waitCVinitialized = 1;
}
@@ -995,16 +1015,29 @@ Tcl_WaitForEvent(
}
#else
if (timePtr != NULL) {
Tcl_Time now;
struct timespec ptime;
struct timespec ptime;
Tcl_GetTime(&now);
ptime.tv_sec = timePtr->sec + now.sec + (timePtr->usec + now.usec) / 1000000;
ptime.tv_nsec = 1000 * ((timePtr->usec + now.usec) % 1000000);
#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK)
if (tsdPtr->monoClock) {
clock_gettime(CLOCK_MONOTONIC, &ptime);
} else {
clock_gettime(CLOCK_REALTIME, &ptime);
}
ptime.tv_sec += timePtr->sec +
(timePtr->usec * 1000 + ptime.tv_nsec) / 1000000000;
ptime.tv_nsec = (timePtr->usec * 1000 + ptime.tv_nsec) %
1000000000;
#else
Tcl_Time now;
pthread_cond_timedwait(&tsdPtr->waitCV, &notifierMutex, &ptime);
Tcl_GetTime(&now);
ptime.tv_sec = timePtr->sec + now.sec +
(timePtr->usec + now.usec) / 1000000;
ptime.tv_nsec = 1000 * ((timePtr->usec + now.usec) % 1000000);
#endif
pthread_cond_timedwait(&tsdPtr->waitCV, &notifierMutex, &ptime);
} else {
pthread_cond_wait(&tsdPtr->waitCV, &notifierMutex);
pthread_cond_wait(&tsdPtr->waitCV, &notifierMutex);
}
#endif /* __CYGWIN__ */
}
Regular → Executable
+19
View File
@@ -638,6 +638,25 @@ extern char ** environ;
# endif /* __llvm__ */
#endif /* __APPLE__ */
/*
*---------------------------------------------------------------------------
* Use clock_gettime() only if _POSIX_MONOTONIC_CLOCK present.
*---------------------------------------------------------------------------
*/
#if defined(HAVE_CLOCK_GETTIME) && !defined(_POSIX_MONOTONIC_CLOCK)
# undef HAVE_CLOCK_GETTIME
#endif
#ifdef TCL_THREADS
# ifndef HAVE_CLOCK_GETTIME
# undef HAVE_PTHREAD_CONDATTR_SETCLOCK
# endif
# ifndef HAVE_PTHREAD_CONDATTR_SETCLOCK
# undef HAVE_CLOCK_GETTIME
# endif
#endif
/*
*---------------------------------------------------------------------------
* The following macros and declarations represent the interface between
Regular → Executable
+49 -9
View File
@@ -520,6 +520,9 @@ Tcl_ConditionWait(
pthread_cond_t *pcondPtr;
pthread_mutex_t *pmutexPtr;
struct timespec ptime;
#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK)
int *flagPtr;
#endif
if (*condPtr == NULL) {
pthread_mutex_lock(&masterLock);
@@ -530,8 +533,26 @@ Tcl_ConditionWait(
*/
if (*condPtr == NULL) {
#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK)
pthread_condattr_t attr;
pcondPtr = ckalloc(sizeof(pthread_cond_t) + sizeof(int));
flagPtr = (int *) (pcondPtr + 1);
pthread_condattr_init(&attr);
*flagPtr = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) == 0;
if (*flagPtr) {
if (pthread_cond_init(pcondPtr, &attr)) {
*flagPtr = 0;
pthread_cond_init(pcondPtr, NULL);
}
} else {
pthread_cond_init(pcondPtr, NULL);
}
pthread_condattr_destroy(&attr);
#else
pcondPtr = ckalloc(sizeof(pthread_cond_t));
pthread_cond_init(pcondPtr, NULL);
#endif
*condPtr = (Tcl_Condition) pcondPtr;
TclRememberCondition(condPtr);
}
@@ -542,6 +563,17 @@ Tcl_ConditionWait(
if (timePtr == NULL) {
pthread_cond_wait(pcondPtr, pmutexPtr);
} else {
#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK)
flagPtr = (int *) (pcondPtr + 1);
if (*flagPtr) {
clock_gettime(CLOCK_MONOTONIC, &ptime);
} else {
clock_gettime(CLOCK_REALTIME, &ptime);
}
ptime.tv_sec += timePtr->sec +
(timePtr->usec * 1000 + ptime.tv_nsec) / 1000000000;
ptime.tv_nsec = (timePtr->usec * 1000 + ptime.tv_nsec) % 1000000000;
#else
Tcl_Time now;
/*
@@ -553,6 +585,7 @@ Tcl_ConditionWait(
ptime.tv_sec = timePtr->sec + now.sec +
(timePtr->usec + now.usec) / 1000000;
ptime.tv_nsec = 1000 * ((timePtr->usec + now.usec) % 1000000);
#endif
pthread_cond_timedwait(pcondPtr, pmutexPtr, &ptime);
}
}
@@ -673,6 +706,7 @@ TclpInetNtoa(
*/
#ifdef USE_THREAD_ALLOC
static volatile int initialized = 0;
static pthread_key_t key;
typedef struct allocMutex {
@@ -708,14 +742,6 @@ TclpFreeAllocMutex(
free(lockPtr);
}
void
TclpInitAllocCache(void)
{
pthread_mutex_lock(allocLockPtr);
pthread_key_create(&key, TclpFreeAllocCache);
pthread_mutex_unlock(allocLockPtr);
}
void
TclpFreeAllocCache(
void *ptr)
@@ -728,14 +754,28 @@ TclpFreeAllocCache(
TclFreeAllocCache(ptr);
pthread_setspecific(key, NULL);
} else {
} else if (initialized) {
/*
* Called by us in TclFinalizeThreadAlloc() during the library
* finalization initiated from Tcl_Finalize()
*/
pthread_key_delete(key);
initialized = 0;
}
}
void *
TclpGetAllocCache(void)
{
if (!initialized) {
pthread_mutex_lock(allocLockPtr);
if (!initialized) {
pthread_key_create(&key, TclpFreeAllocCache);
initialized = 1;
}
pthread_mutex_unlock(allocLockPtr);
}
return pthread_getspecific(key);
}
Regular → Executable
+11
View File
@@ -105,6 +105,14 @@ TclpGetClicks(void)
{
unsigned long now;
#ifdef HAVE_CLOCK_GETTIME
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) {
clock_gettime(CLOCK_REALTIME, &ts);
}
now = ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
#else
#ifdef NO_GETTOD
if (tclGetTimeProcPtr != NativeGetTime) {
Tcl_Time time;
@@ -124,6 +132,7 @@ TclpGetClicks(void)
tclGetTimeProcPtr(&time, tclTimeClientData);
now = time.sec*1000000 + time.usec;
#endif
#endif
return now;
@@ -376,9 +385,11 @@ Tcl_SetTimeProc(
Tcl_ScaleTimeProc *scaleProc,
ClientData clientData)
{
#ifndef HAVE_CLOCK_GETTIME
tclGetTimeProcPtr = getProc;
tclScaleTimeProcPtr = scaleProc;
tclTimeClientData = clientData;
#endif
}
/*
-1
View File
@@ -34,7 +34,6 @@ tclsdl 0x10B20000 0x00080000
vqtcl 0x10C00000 0x00010000
tdbc 0x10C40000 0x00010000
thread 0x10C80000 0x00020000
nsf 0x10ca0000 0x00080000
;
; insert new packages here
;
+28
View File
@@ -1401,6 +1401,8 @@ Optional Packages:
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-encoding encoding for configuration values
--with-celib=DIR use Windows/CE support library from DIR
--with-tickcount use GetTickCount for timers, turns off interp time
limits
Some influential environment variables:
CC C compiler command
@@ -4673,6 +4675,32 @@ case ${host_alias} in
;;
esac
# *** HaO 2016-03-30 this may be at the wrong place.
# *** should be in Line 4410 betwen
# _ACEOF
# and
# echo "$as_me:$LINENO: checking for intptr_t" >&5
# echo $ECHO_N "checking for intptr_t... $ECHO_C" >&6
# if test "${ac_cv_type_intptr_t+set}" = set; then
# Check whether --with-tickcount or --without-tickcount was given.
if test "${with_tickcount+set}" = set; then
withval="$with_tickcount"
tcl_ok=$withval
else
tcl_ok=no
fi;
echo "$as_me:$LINENO: result: $tcl_ok" >&5
echo "${ECHO_T}$tcl_ok" >&6
if test $tcl_ok = yes; then
cat >>confdefs.h <<\_ACEOF
#define WIN32_USE_TICKCOUNT 1
_ACEOF
fi
#------------------------------------------------------------------------
# Add stuff for zlib; note that this is mostly done in the makefile now
# as we just assume that the platform hasn't got a usable z.lib
Regular → Executable
+9
View File
@@ -142,6 +142,15 @@ AS_IF([test "$tcl_ok" = "yes"], [
])
AC_DEFINE(HAVE_ZLIB, 1, [Is there an installed zlib?])
AC_ARG_WITH(tickcount,
AC_HELP_STRING([--with-tickcount],
[use GetTickCount for timers, turns off interp time limits]),
[tcl_ok=$withval], [tcl_ok=no])
AC_MSG_RESULT([$tcl_ok])
if test $tcl_ok = yes; then
AC_DEFINE(WIN32_USE_TICKCOUNT, 1, [Use GetTickCount for timers?])
fi
AC_CHECK_TYPE([intptr_t], [
AC_DEFINE([HAVE_INTPTR_T], 1, [Do we have the intptr_t type?])], [
AC_CACHE_CHECK([for pointer-size signed integer type], tcl_cv_intptr_t, [
Regular → Executable
+56 -18
View File
@@ -51,8 +51,7 @@ static Tcl_ThreadDataKey dataKey;
static int notifierCount = 0;
static const TCHAR className[] = TEXT("TclNotifier");
static int initialized = 0;
static CRITICAL_SECTION notifierMutex;
TCL_DECLARE_MUTEX(notifierMutex)
/*
* Static routines defined in this file.
@@ -86,19 +85,12 @@ Tcl_InitNotifier(void)
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
WNDCLASS class;
TclpMasterLock();
if (!initialized) {
initialized = 1;
InitializeCriticalSection(&notifierMutex);
}
TclpMasterUnlock();
/*
* Register Notifier window class if this is the first thread to use
* this module.
*/
EnterCriticalSection(&notifierMutex);
Tcl_MutexLock(&notifierMutex);
if (notifierCount == 0) {
class.style = 0;
class.cbClsExtra = 0;
@@ -116,7 +108,7 @@ Tcl_InitNotifier(void)
}
}
notifierCount++;
LeaveCriticalSection(&notifierMutex);
Tcl_MutexUnlock(&notifierMutex);
tsdPtr->pending = 0;
tsdPtr->timerActive = 0;
@@ -191,14 +183,12 @@ Tcl_FinalizeNotifier(
* notifier window class.
*/
EnterCriticalSection(&notifierMutex);
if (notifierCount) {
notifierCount--;
if (notifierCount == 0) {
UnregisterClass(className, TclWinGetTclInstance());
}
Tcl_MutexLock(&notifierMutex);
notifierCount--;
if (notifierCount == 0) {
UnregisterClass(className, TclWinGetTclInstance());
}
LeaveCriticalSection(&notifierMutex);
Tcl_MutexUnlock(&notifierMutex);
}
}
@@ -455,6 +445,12 @@ Tcl_WaitForEvent(
*/
if (timePtr) {
#if (_WIN32_WINNT < 0x0600) && defined(WIN32_USE_TICKCOUNT)
timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
if (timeout == INFINITE) {
timeout--;
}
#else
/*
* TIP #233 (Virtualized Time). Convert virtual domain delay to
* real-time.
@@ -470,6 +466,7 @@ Tcl_WaitForEvent(
}
timeout = myTime.sec * 1000 + myTime.usec / 1000;
#endif
} else {
timeout = INFINITE;
}
@@ -558,6 +555,46 @@ void
Tcl_Sleep(
int ms) /* Number of milliseconds to sleep. */
{
#ifdef WIN32_USE_TICKCOUNT
#if (_WIN32_WINNT >= 0x0600)
ULONGLONG now; /* Current wall clock time. */
ULONGLONG desired; /* Desired wakeup time. */
ULONGLONG sleepTime;
now = GetTickCount64();
#else
DWORD now; /* Current wall clock time. */
DWORD desired; /* Desired wakeup time. */
DWORD sleepTime;
now = GetTickCount();
#endif
if (ms < 0) {
ms = 0;
#if (_WIN32_WINNT < 0x0600)
} else if (ms > 0x7FFFFFFF) {
ms = 0x7FFFFFFF;
#endif
}
desired = now + ms;
sleepTime = ms;
for (;;) {
SleepEx(sleepTime, TRUE);
#if (_WIN32_WINNT >= 0x0600)
now = GetTickCount64();
if (now - desired >= 0) {
break;
}
#else
now = GetTickCount();
if ((long) now - (long) desired >= 0) {
break;
}
#endif
sleepTime = desired - now;
}
#else
/*
* Simply calling 'Sleep' for the requisite number of milliseconds can
* make the process appear to wake up early because it isn't synchronized
@@ -607,6 +644,7 @@ Tcl_Sleep(
tclScaleTimeProcPtr(&vdelay, tclTimeClientData);
sleepTime = vdelay.sec * 1000 + vdelay.usec / 1000;
}
#endif
}
/*
+1 -1
View File
@@ -2052,6 +2052,7 @@ Tcl_OpenTcpServer(
char channelName[SOCK_CHAN_LENGTH];
u_long flag = 1; /* Indicates nonblocking mode. */
const char *errorMsg = NULL;
ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey);
if (TclpHasSockets(interp) != TCL_OK) {
return NULL;
@@ -2167,7 +2168,6 @@ error:
}
if (statePtr != NULL) {
ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey);
statePtr->acceptProc = acceptProc;
statePtr->acceptProcData = acceptProcData;
+18 -15
View File
@@ -119,6 +119,7 @@ typedef struct WinCondition {
*/
#ifdef USE_THREAD_ALLOC
static int once;
static DWORD tlsKey;
typedef struct allocMutex {
@@ -967,24 +968,24 @@ TclpFreeAllocMutex(
free(lockPtr);
}
void
TclpInitAllocCache(void)
{
/*
* We need to make sure that TclpFreeAllocCache is called on each
* thread that calls this, but only on threads that call this.
*/
tlsKey = TlsAlloc();
if (tlsKey == TLS_OUT_OF_INDEXES) {
Tcl_Panic("could not allocate thread local storage");
}
}
void *
TclpGetAllocCache(void)
{
void *result;
if (!once) {
/*
* We need to make sure that TclpFreeAllocCache is called on each
* thread that calls this, but only on threads that call this.
*/
tlsKey = TlsAlloc();
once = 1;
if (tlsKey == TLS_OUT_OF_INDEXES) {
Tcl_Panic("could not allocate thread local storage");
}
}
result = TlsGetValue(tlsKey);
if ((result == NULL) && (GetLastError() != NO_ERROR)) {
Tcl_Panic("TlsGetValue failed from TclpGetAllocCache");
@@ -1020,7 +1021,7 @@ TclpFreeAllocCache(
if (!success) {
Tcl_Panic("TlsSetValue failed from TclpFreeAllocCache");
}
} else {
} else if (once) {
/*
* Called by us in TclFinalizeThreadAlloc() during the library
* finalization initiated from Tcl_Finalize()
@@ -1030,7 +1031,9 @@ TclpFreeAllocCache(
if (!success) {
Tcl_Panic("TlsFree failed from TclpFreeAllocCache");
}
once = 0; /* reset for next time. */
}
}
#endif /* USE_THREAD_ALLOC */
Regular → Executable
+12 -1
View File
@@ -113,7 +113,7 @@ static TimeInfo timeInfo = {
* Declarations for functions defined later in this file.
*/
static struct tm * ComputeGMT(const time_t *tp);
#ifndef WIN32_USE_TICKCOUNT
static void StopCalibration(ClientData clientData);
static DWORD WINAPI CalibrationThread(LPVOID arg);
static void UpdateTimeEachSecond(void);
@@ -121,6 +121,7 @@ static void ResetCounterSamples(Tcl_WideUInt fileTime,
Tcl_WideInt perfCounter, Tcl_WideInt perfFreq);
static Tcl_WideInt AccumulateSample(Tcl_WideInt perfCounter,
Tcl_WideUInt fileTime);
#endif
static void NativeScaleTime(Tcl_Time* timebuf,
ClientData clientData);
static void NativeGetTime(Tcl_Time* timebuf,
@@ -294,6 +295,9 @@ NativeGetTime(
if (!timeInfo.initialized) {
TclpInitLock();
if (!timeInfo.initialized) {
#ifdef WIN32_USE_TICKCOUNT
timeInfo.perfCounterAvailable = 0;
#else
timeInfo.perfCounterAvailable =
QueryPerformanceFrequency(&timeInfo.nominalFreq);
@@ -387,6 +391,7 @@ NativeGetTime(
CloseHandle(timeInfo.readyEvent);
Tcl_CreateExitHandler(StopCalibration, NULL);
}
#endif /* !WIN32_USE_TICKCOUNT */
timeInfo.initialized = TRUE;
}
TclpInitUnlock();
@@ -452,6 +457,7 @@ NativeGetTime(
}
}
#ifndef WIN32_USE_TICKCOUNT
/*
*----------------------------------------------------------------------
*
@@ -485,6 +491,7 @@ StopCalibration(
CloseHandle(timeInfo.exitEvent);
CloseHandle(timeInfo.calibrationThread);
}
#endif /* !WIN32_USE_TICKCOUNT */
/*
*----------------------------------------------------------------------
@@ -707,6 +714,7 @@ ComputeGMT(
return tmPtr;
}
#ifndef WIN32_USE_TICKCOUNT
/*
*----------------------------------------------------------------------
*
@@ -1033,6 +1041,7 @@ AccumulateSample(
return estFreq;
}
}
#endif /* !WIN32_USE_TICKCOUNT */
/*
*----------------------------------------------------------------------
@@ -1118,9 +1127,11 @@ Tcl_SetTimeProc(
Tcl_ScaleTimeProc *scaleProc,
ClientData clientData)
{
#if !defined(WIN32_USE_TICKCOUNT) || (_WIN32_WINNT >= 0x0600)
tclGetTimeProcPtr = getProc;
tclScaleTimeProcPtr = scaleProc;
tclTimeClientData = clientData;
#endif
}
/*