Mercurial > emacs
changeset 100885:56164f0c606d
* w32.c: Use 64-bit arithmetic to do FILETIME conversions. (Bug#1766)
(utc_base): Declare as ULONGLONG, not long double.
(convert_time_raw): Delete.
(FILETIME_TO_U64, U64_TO_LISP_TIME): New macros.
(initialize_utc_base): New function.
(convert_time): Use FILETIME_TO_U64, initialize_utc_base.
(convert_from_time_t): Use initialize_utc_base; compute result with
64-bit arithmetic.
(process_times): Use FILETIME_TO_U64, U64_TO_LISP_TIME.
author | Juanma Barranquero <lekktu@gmail.com> |
---|---|
date | Sun, 04 Jan 2009 11:30:13 +0000 |
parents | 354b03900b09 |
children | 19c85c36798d |
files | src/ChangeLog src/w32.c |
diffstat | 2 files changed, 68 insertions(+), 63 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog Sun Jan 04 08:39:31 2009 +0000 +++ b/src/ChangeLog Sun Jan 04 11:30:13 2009 +0000 @@ -1,3 +1,15 @@ +2009-01-04 Juanma Barranquero <lekktu@gmail.com> + + * w32.c: Use 64-bit arithmetic to do FILETIME conversions. (Bug#1766) + (utc_base): Declare as ULONGLONG, not long double. + (convert_time_raw): Delete. + (FILETIME_TO_U64, U64_TO_LISP_TIME): New macros. + (initialize_utc_base): New function. + (convert_time): Use FILETIME_TO_U64, initialize_utc_base. + (convert_from_time_t): Use initialize_utc_base; compute result with + 64-bit arithmetic. + (process_times): Use FILETIME_TO_U64, U64_TO_LISP_TIME. + 2009-01-03 Eli Zaretskii <eliz@gnu.org> * process.c (Qeuid, Qegid, Qcomm, Qstate, Qppid, Qpgrp, Qsess)
--- a/src/w32.c Sun Jan 04 08:39:31 2009 +0000 +++ b/src/w32.c Sun Jan 04 11:30:13 2009 +0000 @@ -2739,76 +2739,69 @@ } static FILETIME utc_base_ft; -static long double utc_base; +static ULONGLONG utc_base; /* In 100ns units */ static int init = 0; -static long double -convert_time_raw (FILETIME ft) +#define FILETIME_TO_U64(result, ft) \ + do { \ + ULARGE_INTEGER uiTemp; \ + uiTemp.LowPart = (ft).dwLowDateTime; \ + uiTemp.HighPart = (ft).dwHighDateTime; \ + result = uiTemp.QuadPart; \ + } while (0) + +static void +initialize_utc_base () { - return - (long double) ft.dwHighDateTime - * 4096.0L * 1024.0L * 1024.0L + ft.dwLowDateTime; + /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */ + SYSTEMTIME st; + + st.wYear = 1970; + st.wMonth = 1; + st.wDay = 1; + st.wHour = 0; + st.wMinute = 0; + st.wSecond = 0; + st.wMilliseconds = 0; + + SystemTimeToFileTime (&st, &utc_base_ft); + FILETIME_TO_U64 (utc_base, utc_base_ft); } static time_t convert_time (FILETIME ft) { - long double ret; + ULONGLONG tmp; if (!init) { - /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */ - SYSTEMTIME st; - - st.wYear = 1970; - st.wMonth = 1; - st.wDay = 1; - st.wHour = 0; - st.wMinute = 0; - st.wSecond = 0; - st.wMilliseconds = 0; - - SystemTimeToFileTime (&st, &utc_base_ft); - utc_base = (long double) utc_base_ft.dwHighDateTime - * 4096.0L * 1024.0L * 1024.0L + utc_base_ft.dwLowDateTime; + initialize_utc_base(); init = 1; } if (CompareFileTime (&ft, &utc_base_ft) < 0) return 0; - return (time_t) ((convert_time_raw (ft) - utc_base) * 1e-7L); + FILETIME_TO_U64 (tmp, ft); + return (time_t) ((tmp - utc_base) / 10000000L); } void convert_from_time_t (time_t time, FILETIME * pft) { - long double tmp; + ULARGE_INTEGER tmp; if (!init) { - /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */ - SYSTEMTIME st; - - st.wYear = 1970; - st.wMonth = 1; - st.wDay = 1; - st.wHour = 0; - st.wMinute = 0; - st.wSecond = 0; - st.wMilliseconds = 0; - - SystemTimeToFileTime (&st, &utc_base_ft); - utc_base = (long double) utc_base_ft.dwHighDateTime - * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime; + initialize_utc_base (); init = 1; } /* time in 100ns units since 1-Jan-1601 */ - tmp = (long double) time * 1e7 + utc_base; - pft->dwHighDateTime = (DWORD) (tmp / (4096.0 * 1024 * 1024)); - pft->dwLowDateTime = (DWORD) (tmp - (4096.0 * 1024 * 1024) * pft->dwHighDateTime); + tmp.QuadPart = (ULONGLONG) time * 10000000L + utc_base; + pft->dwHighDateTime = tmp.HighPart; + pft->dwLowDateTime = tmp.LowPart; } #if 0 @@ -3770,6 +3763,8 @@ make_number (time_usec)); } +#define U64_TO_LISP_TIME(time) ltime ((time) / 1000000L, (time) % 1000000L) + static int process_times (h_proc, ctime, etime, stime, utime, ttime, pcpu) HANDLE h_proc; @@ -3777,9 +3772,7 @@ double *pcpu; { FILETIME ft_creation, ft_exit, ft_kernel, ft_user, ft_current; - long ctime_sec, ctime_usec, stime_sec, stime_usec, utime_sec, utime_usec; - long etime_sec, etime_usec, ttime_sec, ttime_usec; - long double tem1, tem2, tem; + ULONGLONG tem1, tem2, tem3, tem; if (!h_proc || !get_process_times_fn @@ -3789,29 +3782,29 @@ GetSystemTimeAsFileTime (&ft_current); - tem1 = convert_time_raw (ft_kernel) * 0.1L; - stime_usec = fmodl (tem1, 1000000.0L); - stime_sec = tem1 * 0.000001L; - *stime = ltime (stime_sec, stime_usec); - tem2 = convert_time_raw (ft_user) * 0.1L; - utime_usec = fmodl (tem2, 1000000.0L); - utime_sec = tem2 * 0.000001L; - *utime = ltime (utime_sec, utime_usec); - ttime_usec = fmodl (tem1 + tem2, 1000000.0L); - ttime_sec = (tem1 + tem2) * 0.000001L; - *ttime = ltime (ttime_sec, ttime_usec); - tem = convert_time_raw (ft_creation); + FILETIME_TO_U64 (tem1, ft_kernel); + tem1 /= 10L; + *stime = U64_TO_LISP_TIME (tem1); + + FILETIME_TO_U64 (tem2, ft_user); + tem2 /= 10L; + *utime = U64_TO_LISP_TIME (tem2); + + tem3 = tem1 + tem2; + *ttime = U64_TO_LISP_TIME (tem3); + + FILETIME_TO_U64 (tem, ft_creation); /* Process no 4 (System) returns zero creation time. */ if (tem) - tem = (tem - utc_base) * 0.1; - ctime_usec = fmodl (tem, 1000000.0L); - ctime_sec = tem * 0.000001L; - *ctime = ltime (ctime_sec, ctime_usec); + tem = (tem - utc_base) / 10L; + *ctime = U64_TO_LISP_TIME (tem); + if (tem) - tem = (convert_time_raw (ft_current) - utc_base) * 0.1L - tem; - etime_usec = fmodl (tem, 1000000.0L); - etime_sec = tem * 0.000001L; - *etime = ltime (etime_sec, etime_usec); + { + FILETIME_TO_U64 (tem3, ft_current); + tem = (tem3 - utc_base) / 10L - tem; + } + *etime = U64_TO_LISP_TIME (tem); if (tem) {