diff options
| author | Juanma Barranquero | 2009-01-04 11:30:13 +0000 |
|---|---|---|
| committer | Juanma Barranquero | 2009-01-04 11:30:13 +0000 |
| commit | 5da9424d149367340d9f9190a4f8583a0ba67706 (patch) | |
| tree | 68b4898613a1d3ac19dba956c6d40e77824de769 /src | |
| parent | 21927cd747e124a6ae7270e3453593271ae17392 (diff) | |
| download | emacs-5da9424d149367340d9f9190a4f8583a0ba67706.tar.gz emacs-5da9424d149367340d9f9190a4f8583a0ba67706.zip | |
* 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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 12 | ||||
| -rw-r--r-- | src/w32.c | 119 |
2 files changed, 68 insertions, 63 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index c03bac6fae1..c0cf92eb945 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2009-01-04 Juanma Barranquero <lekktu@gmail.com> | ||
| 2 | |||
| 3 | * w32.c: Use 64-bit arithmetic to do FILETIME conversions. (Bug#1766) | ||
| 4 | (utc_base): Declare as ULONGLONG, not long double. | ||
| 5 | (convert_time_raw): Delete. | ||
| 6 | (FILETIME_TO_U64, U64_TO_LISP_TIME): New macros. | ||
| 7 | (initialize_utc_base): New function. | ||
| 8 | (convert_time): Use FILETIME_TO_U64, initialize_utc_base. | ||
| 9 | (convert_from_time_t): Use initialize_utc_base; compute result with | ||
| 10 | 64-bit arithmetic. | ||
| 11 | (process_times): Use FILETIME_TO_U64, U64_TO_LISP_TIME. | ||
| 12 | |||
| 1 | 2009-01-03 Eli Zaretskii <eliz@gnu.org> | 13 | 2009-01-03 Eli Zaretskii <eliz@gnu.org> |
| 2 | 14 | ||
| 3 | * process.c (Qeuid, Qegid, Qcomm, Qstate, Qppid, Qpgrp, Qsess) | 15 | * process.c (Qeuid, Qegid, Qcomm, Qstate, Qppid, Qpgrp, Qsess) |
| @@ -2739,76 +2739,69 @@ sys_unlink (const char * path) | |||
| 2739 | } | 2739 | } |
| 2740 | 2740 | ||
| 2741 | static FILETIME utc_base_ft; | 2741 | static FILETIME utc_base_ft; |
| 2742 | static long double utc_base; | 2742 | static ULONGLONG utc_base; /* In 100ns units */ |
| 2743 | static int init = 0; | 2743 | static int init = 0; |
| 2744 | 2744 | ||
| 2745 | static long double | 2745 | #define FILETIME_TO_U64(result, ft) \ |
| 2746 | convert_time_raw (FILETIME ft) | 2746 | do { \ |
| 2747 | ULARGE_INTEGER uiTemp; \ | ||
| 2748 | uiTemp.LowPart = (ft).dwLowDateTime; \ | ||
| 2749 | uiTemp.HighPart = (ft).dwHighDateTime; \ | ||
| 2750 | result = uiTemp.QuadPart; \ | ||
| 2751 | } while (0) | ||
| 2752 | |||
| 2753 | static void | ||
| 2754 | initialize_utc_base () | ||
| 2747 | { | 2755 | { |
| 2748 | return | 2756 | /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */ |
| 2749 | (long double) ft.dwHighDateTime | 2757 | SYSTEMTIME st; |
| 2750 | * 4096.0L * 1024.0L * 1024.0L + ft.dwLowDateTime; | 2758 | |
| 2759 | st.wYear = 1970; | ||
| 2760 | st.wMonth = 1; | ||
| 2761 | st.wDay = 1; | ||
| 2762 | st.wHour = 0; | ||
| 2763 | st.wMinute = 0; | ||
| 2764 | st.wSecond = 0; | ||
| 2765 | st.wMilliseconds = 0; | ||
| 2766 | |||
| 2767 | SystemTimeToFileTime (&st, &utc_base_ft); | ||
| 2768 | FILETIME_TO_U64 (utc_base, utc_base_ft); | ||
| 2751 | } | 2769 | } |
| 2752 | 2770 | ||
| 2753 | static time_t | 2771 | static time_t |
| 2754 | convert_time (FILETIME ft) | 2772 | convert_time (FILETIME ft) |
| 2755 | { | 2773 | { |
| 2756 | long double ret; | 2774 | ULONGLONG tmp; |
| 2757 | 2775 | ||
| 2758 | if (!init) | 2776 | if (!init) |
| 2759 | { | 2777 | { |
| 2760 | /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */ | 2778 | initialize_utc_base(); |
| 2761 | SYSTEMTIME st; | ||
| 2762 | |||
| 2763 | st.wYear = 1970; | ||
| 2764 | st.wMonth = 1; | ||
| 2765 | st.wDay = 1; | ||
| 2766 | st.wHour = 0; | ||
| 2767 | st.wMinute = 0; | ||
| 2768 | st.wSecond = 0; | ||
| 2769 | st.wMilliseconds = 0; | ||
| 2770 | |||
| 2771 | SystemTimeToFileTime (&st, &utc_base_ft); | ||
| 2772 | utc_base = (long double) utc_base_ft.dwHighDateTime | ||
| 2773 | * 4096.0L * 1024.0L * 1024.0L + utc_base_ft.dwLowDateTime; | ||
| 2774 | init = 1; | 2779 | init = 1; |
| 2775 | } | 2780 | } |
| 2776 | 2781 | ||
| 2777 | if (CompareFileTime (&ft, &utc_base_ft) < 0) | 2782 | if (CompareFileTime (&ft, &utc_base_ft) < 0) |
| 2778 | return 0; | 2783 | return 0; |
| 2779 | 2784 | ||
| 2780 | return (time_t) ((convert_time_raw (ft) - utc_base) * 1e-7L); | 2785 | FILETIME_TO_U64 (tmp, ft); |
| 2786 | return (time_t) ((tmp - utc_base) / 10000000L); | ||
| 2781 | } | 2787 | } |
| 2782 | 2788 | ||
| 2783 | 2789 | ||
| 2784 | void | 2790 | void |
| 2785 | convert_from_time_t (time_t time, FILETIME * pft) | 2791 | convert_from_time_t (time_t time, FILETIME * pft) |
| 2786 | { | 2792 | { |
| 2787 | long double tmp; | 2793 | ULARGE_INTEGER tmp; |
| 2788 | 2794 | ||
| 2789 | if (!init) | 2795 | if (!init) |
| 2790 | { | 2796 | { |
| 2791 | /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */ | 2797 | initialize_utc_base (); |
| 2792 | SYSTEMTIME st; | ||
| 2793 | |||
| 2794 | st.wYear = 1970; | ||
| 2795 | st.wMonth = 1; | ||
| 2796 | st.wDay = 1; | ||
| 2797 | st.wHour = 0; | ||
| 2798 | st.wMinute = 0; | ||
| 2799 | st.wSecond = 0; | ||
| 2800 | st.wMilliseconds = 0; | ||
| 2801 | |||
| 2802 | SystemTimeToFileTime (&st, &utc_base_ft); | ||
| 2803 | utc_base = (long double) utc_base_ft.dwHighDateTime | ||
| 2804 | * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime; | ||
| 2805 | init = 1; | 2798 | init = 1; |
| 2806 | } | 2799 | } |
| 2807 | 2800 | ||
| 2808 | /* time in 100ns units since 1-Jan-1601 */ | 2801 | /* time in 100ns units since 1-Jan-1601 */ |
| 2809 | tmp = (long double) time * 1e7 + utc_base; | 2802 | tmp.QuadPart = (ULONGLONG) time * 10000000L + utc_base; |
| 2810 | pft->dwHighDateTime = (DWORD) (tmp / (4096.0 * 1024 * 1024)); | 2803 | pft->dwHighDateTime = tmp.HighPart; |
| 2811 | pft->dwLowDateTime = (DWORD) (tmp - (4096.0 * 1024 * 1024) * pft->dwHighDateTime); | 2804 | pft->dwLowDateTime = tmp.LowPart; |
| 2812 | } | 2805 | } |
| 2813 | 2806 | ||
| 2814 | #if 0 | 2807 | #if 0 |
| @@ -3770,6 +3763,8 @@ ltime (time_sec, time_usec) | |||
| 3770 | make_number (time_usec)); | 3763 | make_number (time_usec)); |
| 3771 | } | 3764 | } |
| 3772 | 3765 | ||
| 3766 | #define U64_TO_LISP_TIME(time) ltime ((time) / 1000000L, (time) % 1000000L) | ||
| 3767 | |||
| 3773 | static int | 3768 | static int |
| 3774 | process_times (h_proc, ctime, etime, stime, utime, ttime, pcpu) | 3769 | process_times (h_proc, ctime, etime, stime, utime, ttime, pcpu) |
| 3775 | HANDLE h_proc; | 3770 | HANDLE h_proc; |
| @@ -3777,9 +3772,7 @@ process_times (h_proc, ctime, etime, stime, utime, ttime, pcpu) | |||
| 3777 | double *pcpu; | 3772 | double *pcpu; |
| 3778 | { | 3773 | { |
| 3779 | FILETIME ft_creation, ft_exit, ft_kernel, ft_user, ft_current; | 3774 | FILETIME ft_creation, ft_exit, ft_kernel, ft_user, ft_current; |
| 3780 | long ctime_sec, ctime_usec, stime_sec, stime_usec, utime_sec, utime_usec; | 3775 | ULONGLONG tem1, tem2, tem3, tem; |
| 3781 | long etime_sec, etime_usec, ttime_sec, ttime_usec; | ||
| 3782 | long double tem1, tem2, tem; | ||
| 3783 | 3776 | ||
| 3784 | if (!h_proc | 3777 | if (!h_proc |
| 3785 | || !get_process_times_fn | 3778 | || !get_process_times_fn |
| @@ -3789,29 +3782,29 @@ process_times (h_proc, ctime, etime, stime, utime, ttime, pcpu) | |||
| 3789 | 3782 | ||
| 3790 | GetSystemTimeAsFileTime (&ft_current); | 3783 | GetSystemTimeAsFileTime (&ft_current); |
| 3791 | 3784 | ||
| 3792 | tem1 = convert_time_raw (ft_kernel) * 0.1L; | 3785 | FILETIME_TO_U64 (tem1, ft_kernel); |
| 3793 | stime_usec = fmodl (tem1, 1000000.0L); | 3786 | tem1 /= 10L; |
| 3794 | stime_sec = tem1 * 0.000001L; | 3787 | *stime = U64_TO_LISP_TIME (tem1); |
| 3795 | *stime = ltime (stime_sec, stime_usec); | 3788 | |
| 3796 | tem2 = convert_time_raw (ft_user) * 0.1L; | 3789 | FILETIME_TO_U64 (tem2, ft_user); |
| 3797 | utime_usec = fmodl (tem2, 1000000.0L); | 3790 | tem2 /= 10L; |
| 3798 | utime_sec = tem2 * 0.000001L; | 3791 | *utime = U64_TO_LISP_TIME (tem2); |
| 3799 | *utime = ltime (utime_sec, utime_usec); | 3792 | |
| 3800 | ttime_usec = fmodl (tem1 + tem2, 1000000.0L); | 3793 | tem3 = tem1 + tem2; |
| 3801 | ttime_sec = (tem1 + tem2) * 0.000001L; | 3794 | *ttime = U64_TO_LISP_TIME (tem3); |
| 3802 | *ttime = ltime (ttime_sec, ttime_usec); | 3795 | |
| 3803 | tem = convert_time_raw (ft_creation); | 3796 | FILETIME_TO_U64 (tem, ft_creation); |
| 3804 | /* Process no 4 (System) returns zero creation time. */ | 3797 | /* Process no 4 (System) returns zero creation time. */ |
| 3805 | if (tem) | 3798 | if (tem) |
| 3806 | tem = (tem - utc_base) * 0.1; | 3799 | tem = (tem - utc_base) / 10L; |
| 3807 | ctime_usec = fmodl (tem, 1000000.0L); | 3800 | *ctime = U64_TO_LISP_TIME (tem); |
| 3808 | ctime_sec = tem * 0.000001L; | 3801 | |
| 3809 | *ctime = ltime (ctime_sec, ctime_usec); | ||
| 3810 | if (tem) | 3802 | if (tem) |
| 3811 | tem = (convert_time_raw (ft_current) - utc_base) * 0.1L - tem; | 3803 | { |
| 3812 | etime_usec = fmodl (tem, 1000000.0L); | 3804 | FILETIME_TO_U64 (tem3, ft_current); |
| 3813 | etime_sec = tem * 0.000001L; | 3805 | tem = (tem3 - utc_base) / 10L - tem; |
| 3814 | *etime = ltime (etime_sec, etime_usec); | 3806 | } |
| 3807 | *etime = U64_TO_LISP_TIME (tem); | ||
| 3815 | 3808 | ||
| 3816 | if (tem) | 3809 | if (tem) |
| 3817 | { | 3810 | { |