⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tclwintime.c

📁 这是leon3处理器的交叉编译链
💻 C
📖 第 1 页 / 共 2 页
字号:
	     * Skip the offset string and get the DST string.	     */	    p = zone + len;	    p += strspn(p, "+-:0123456789");	    if (*p != '\0') {		zone = p;		len = strlen(zone);		if (len > 3) {		    len = 3;		}	    }	}	Tcl_ExternalToUtf(NULL, NULL, zone, len, 0, NULL, name,		sizeof(tsdPtr->tzName), NULL, NULL, NULL);    }    if (name[0] == '\0') {	if (GetTimeZoneInformation(&tz) == TIME_ZONE_ID_UNKNOWN) {	    /*	     * MSDN: On NT this is returned if DST is not used in	     * the current TZ	     */	    dst = 0;	}	encoding = Tcl_GetEncoding(NULL, "unicode");	Tcl_ExternalToUtf(NULL, encoding, 		(char *) ((dst) ? tz.DaylightName : tz.StandardName), -1, 		0, NULL, name, sizeof(tsdPtr->tzName), NULL, NULL, NULL);	Tcl_FreeEncoding(encoding);    }     return name;}/* *---------------------------------------------------------------------- * * TclpGetDate -- * *	This function converts between seconds and struct tm.  If *	useGMT is true, then the returned date will be in Greenwich *	Mean Time (GMT).  Otherwise, it will be in the local time zone. * * Results: *	Returns a static tm structure. * * Side effects: *	None. * *---------------------------------------------------------------------- */struct tm *TclpGetDate(t, useGMT)    TclpTime_t t;    int useGMT;{    const time_t *tp = (const time_t *) t;    struct tm *tmPtr;    long time;    if (!useGMT) {	tzset();	/*	 * If we are in the valid range, let the C run-time library	 * handle it.  Otherwise we need to fake it.  Note that this	 * algorithm ignores daylight savings time before the epoch.	 */	if (*tp >= 0) {	    return localtime(tp);	}	time = *tp - _timezone;		/*	 * If we aren't near to overflowing the long, just add the bias and	 * use the normal calculation.  Otherwise we will need to adjust	 * the result at the end.	 */	if (*tp < (LONG_MAX - 2 * SECSPERDAY)		&& *tp > (LONG_MIN + 2 * SECSPERDAY)) {	    tmPtr = ComputeGMT(&time);	} else {	    tmPtr = ComputeGMT(tp);	    tzset();	    /*	     * Add the bias directly to the tm structure to avoid overflow.	     * Propagate seconds overflow into minutes, hours and days.	     */	    time = tmPtr->tm_sec - _timezone;	    tmPtr->tm_sec = (int)(time % 60);	    if (tmPtr->tm_sec < 0) {		tmPtr->tm_sec += 60;		time -= 60;	    }    	    time = tmPtr->tm_min + time/60;	    tmPtr->tm_min = (int)(time % 60);	    if (tmPtr->tm_min < 0) {		tmPtr->tm_min += 60;		time -= 60;	    }	    time = tmPtr->tm_hour + time/60;	    tmPtr->tm_hour = (int)(time % 24);	    if (tmPtr->tm_hour < 0) {		tmPtr->tm_hour += 24;		time -= 24;	    }	    time /= 24;	    tmPtr->tm_mday += time;	    tmPtr->tm_yday += time;	    tmPtr->tm_wday = (tmPtr->tm_wday + time) % 7;	}    } else {	tmPtr = ComputeGMT(tp);    }    return tmPtr;}/* *---------------------------------------------------------------------- * * ComputeGMT -- * *	This function computes GMT given the number of seconds since *	the epoch (midnight Jan 1 1970). * * Results: *	Returns a (per thread) statically allocated struct tm. * * Side effects: *	Updates the values of the static struct tm. * *---------------------------------------------------------------------- */static struct tm *ComputeGMT(tp)    const time_t *tp;{    struct tm *tmPtr;    long tmp, rem;    int isLeap;    int *days;    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);    tmPtr = &tsdPtr->tm;    /*     * Compute the 4 year span containing the specified time.     */    tmp = *tp / SECSPER4YEAR;    rem = *tp % SECSPER4YEAR;    /*     * Correct for weird mod semantics so the remainder is always positive.     */    if (rem < 0) {	tmp--;	rem += SECSPER4YEAR;    }    /*     * Compute the year after 1900 by taking the 4 year span and adjusting     * for the remainder.  This works because 2000 is a leap year, and     * 1900/2100 are out of the range.     */    tmp = (tmp * 4) + 70;    isLeap = 0;    if (rem >= SECSPERYEAR) {			  /* 1971, etc. */	tmp++;	rem -= SECSPERYEAR;	if (rem >= SECSPERYEAR) {		  /* 1972, etc. */	    tmp++;	    rem -= SECSPERYEAR;	    if (rem >= SECSPERYEAR + SECSPERDAY) { /* 1973, etc. */		tmp++;		rem -= SECSPERYEAR + SECSPERDAY;	    } else {		isLeap = 1;	    }	}    }    tmPtr->tm_year = tmp;    /*     * Compute the day of year and leave the seconds in the current day in     * the remainder.     */    tmPtr->tm_yday = rem / SECSPERDAY;    rem %= SECSPERDAY;        /*     * Compute the time of day.     */    tmPtr->tm_hour = rem / 3600;    rem %= 3600;    tmPtr->tm_min = rem / 60;    tmPtr->tm_sec = rem % 60;    /*     * Compute the month and day of month.     */    days = (isLeap) ? leapDays : normalDays;    for (tmp = 1; days[tmp] < tmPtr->tm_yday; tmp++) {    }    tmPtr->tm_mon = --tmp;    tmPtr->tm_mday = tmPtr->tm_yday - days[tmp];    /*     * Compute day of week.  Epoch started on a Thursday.     */    tmPtr->tm_wday = (*tp / SECSPERDAY) + 4;    if ((*tp % SECSPERDAY) < 0) {	tmPtr->tm_wday--;    }    tmPtr->tm_wday %= 7;    if (tmPtr->tm_wday < 0) {	tmPtr->tm_wday += 7;    }    return tmPtr;}/* *---------------------------------------------------------------------- * * CalibrationThread -- * *	Thread that manages calibration of the hi-resolution time *	derived from the performance counter, to keep it synchronized *	with the system clock. * * Parameters: *	arg -- Client data from the CreateThread call.  This parameter *             points to the static TimeInfo structure. * * Return value: *	None.  This thread embeds an infinite loop. * * Side effects: *	At an interval of clockCalibrateWakeupInterval ms, this thread *	performs virtual time discipline. * * Note: When this thread is entered, TclpInitLock has been called * to safeguard the static storage.  There is therefore no synchronization * in the body of this procedure. * *---------------------------------------------------------------------- */static DWORD WINAPICalibrationThread( LPVOID arg ){    FILETIME curFileTime;    DWORD waitResult;    /* Get initial system time and performance counter */    GetSystemTimeAsFileTime( &curFileTime );    QueryPerformanceCounter( &timeInfo.lastCounter );    QueryPerformanceFrequency( &timeInfo.curCounterFreq );    timeInfo.lastFileTime.LowPart = curFileTime.dwLowDateTime;    timeInfo.lastFileTime.HighPart = curFileTime.dwHighDateTime;    /* Initialize the working storage for the calibration callback */    timeInfo.lastPerfCounter = timeInfo.lastCounter.QuadPart;    timeInfo.estPerfCounterFreq = timeInfo.curCounterFreq.QuadPart;    /*     * Wake up the calling thread.  When it wakes up, it will release the     * initialization lock.     */    SetEvent( timeInfo.readyEvent );    /* Run the calibration once a second */    for ( ; ; ) {	/* If the exitEvent is set, break out of the loop. */	waitResult = WaitForSingleObjectEx(timeInfo.exitEvent, 1000, FALSE);	if ( waitResult == WAIT_OBJECT_0 ) {	    break;	}	UpdateTimeEachSecond();    }    /* lint */    return (DWORD) 0;}/* *---------------------------------------------------------------------- * * UpdateTimeEachSecond -- * *	Callback from the waitable timer in the clock calibration thread *	that updates system time. * * Parameters: *	info -- Pointer to the static TimeInfo structure * * Results: *	None. * * Side effects: *	Performs virtual time calibration discipline. * *---------------------------------------------------------------------- */static voidUpdateTimeEachSecond(){    LARGE_INTEGER curPerfCounter;				/* Current value returned from				 * QueryPerformanceCounter */    LONGLONG perfCounterDiff;	/* Difference between the current value				 * and the value of 1 second ago */    FILETIME curSysTime;	/* Current system time */    LARGE_INTEGER curFileTime;	/* File time at the time this callback				 * was scheduled. */    LONGLONG fileTimeDiff;	/* Elapsed time on the system clock				 * since the last time this procedure				 * was called */    LONGLONG instantFreq;	/* Instantaneous estimate of the				 * performance counter frequency */    LONGLONG delta;		/* Increment to add to the estimated				 * performance counter frequency in the				 * loop filter */    LONGLONG fuzz;		/* Tolerance for the perf counter frequency */    LONGLONG lowBound;		/* Lower bound for the frequency assuming				 * 1000 ppm tolerance */    LONGLONG hiBound;		/* Upper bound for the frequency */    /*     * Get current performance counter and system time.     */    QueryPerformanceCounter( &curPerfCounter );    GetSystemTimeAsFileTime( &curSysTime );    curFileTime.LowPart = curSysTime.dwLowDateTime;    curFileTime.HighPart = curSysTime.dwHighDateTime;    EnterCriticalSection( &timeInfo.cs );    /*     * Find out how many ticks of the performance counter and the     * system clock have elapsed since we got into this procedure.     * Estimate the current frequency.     */    perfCounterDiff = curPerfCounter.QuadPart - timeInfo.lastPerfCounter;    timeInfo.lastPerfCounter = curPerfCounter.QuadPart;    fileTimeDiff = curFileTime.QuadPart - timeInfo.lastSysTime;    timeInfo.lastSysTime = curFileTime.QuadPart;    instantFreq = ( 10000000 * perfCounterDiff / fileTimeDiff );    /*     * Consider this a timing glitch if instant frequency varies     * significantly from the current estimate.     */    fuzz = timeInfo.estPerfCounterFreq >> 10;    lowBound = timeInfo.estPerfCounterFreq - fuzz;    hiBound = timeInfo.estPerfCounterFreq + fuzz;    if ( instantFreq < lowBound || instantFreq > hiBound ) {	LeaveCriticalSection( &timeInfo.cs );	return;    }    /*     * Update the current estimate of performance counter frequency.     * This code is equivalent to the loop filter of a phase locked     * loop.     */    delta = ( instantFreq - timeInfo.estPerfCounterFreq ) >> 6;    timeInfo.estPerfCounterFreq += delta;    /*     * Update the current virtual time.     */    timeInfo.lastFileTime.QuadPart	+= ( ( curPerfCounter.QuadPart - timeInfo.lastCounter.QuadPart )	     * 10000000 / timeInfo.curCounterFreq.QuadPart );    timeInfo.lastCounter.QuadPart = curPerfCounter.QuadPart;    delta = curFileTime.QuadPart - timeInfo.lastFileTime.QuadPart;    if ( delta > 10000000 || delta < -10000000 ) {	/*	 * If the virtual time slip exceeds one second, then adjusting	 * the counter frequency is hopeless (it'll take over fifteen	 * minutes to line up with the system clock).  The most likely	 * cause of this large a slip is a sudden change to the system	 * clock, perhaps because it was being corrected by wristwatch	 * and eyeball.  Accept the system time, and set the performance	 * counter frequency to the current estimate.	 */	timeInfo.lastFileTime.QuadPart = curFileTime.QuadPart;	timeInfo.curCounterFreq.QuadPart = timeInfo.estPerfCounterFreq;    } else {	/*	 * Compute a counter frequency that will cause virtual time to line	 * up with system time one second from now, assuming that the	 * performance counter continues to tick at timeInfo.estPerfCounterFreq.	 */		timeInfo.curCounterFreq.QuadPart	    = 10000000 * timeInfo.estPerfCounterFreq / ( delta + 10000000 );	/*	 * Limit frequency excursions to 1000 ppm from estimate	 */		if ( timeInfo.curCounterFreq.QuadPart < lowBound ) {	    timeInfo.curCounterFreq.QuadPart = lowBound;	} else if ( timeInfo.curCounterFreq.QuadPart > hiBound ) {	    timeInfo.curCounterFreq.QuadPart = hiBound;	}    }    LeaveCriticalSection( &timeInfo.cs );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -