Yifu Wang : msvcp120: Implemented xtime functions.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Jan 9 11:49:15 CST 2015
Module: wine
Branch: master
Commit: b81e79ed08b1bde157e94f09960dc0c455d5f035
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b81e79ed08b1bde157e94f09960dc0c455d5f035
Author: Yifu Wang <ywang at esri.com>
Date: Tue Dec 16 16:33:21 2014 -0800
msvcp120: Implemented xtime functions.
---
configure | 1 +
configure.ac | 1 +
dlls/msvcp120/msvcp120.spec | 8 +--
dlls/msvcp120/tests/Makefile.in | 5 ++
dlls/msvcp120/tests/msvcp120.c | 139 ++++++++++++++++++++++++++++++++++++
dlls/msvcp120_app/msvcp120_app.spec | 8 +--
dlls/msvcp90/misc.c | 54 ++++++++++++++
7 files changed, 208 insertions(+), 8 deletions(-)
diff --git a/configure b/configure
index 062287e..d560f43 100755
--- a/configure
+++ b/configure
@@ -17246,6 +17246,7 @@ wine_fn_config_dll msvcp100 enable_msvcp100
wine_fn_config_test dlls/msvcp100/tests msvcp100_test
wine_fn_config_dll msvcp110 enable_msvcp110
wine_fn_config_dll msvcp120 enable_msvcp120
+wine_fn_config_test dlls/msvcp120/tests msvcp120_test
wine_fn_config_dll msvcp120_app enable_msvcp120_app
wine_fn_config_dll msvcp60 enable_msvcp60
wine_fn_config_test dlls/msvcp60/tests msvcp60_test
diff --git a/configure.ac b/configure.ac
index 50efb9f..8263c66 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3070,6 +3070,7 @@ WINE_CONFIG_DLL(msvcp100)
WINE_CONFIG_TEST(dlls/msvcp100/tests)
WINE_CONFIG_DLL(msvcp110)
WINE_CONFIG_DLL(msvcp120)
+WINE_CONFIG_TEST(dlls/msvcp120/tests)
WINE_CONFIG_DLL(msvcp120_app)
WINE_CONFIG_DLL(msvcp60)
WINE_CONFIG_TEST(dlls/msvcp60/tests)
diff --git a/dlls/msvcp120/msvcp120.spec b/dlls/msvcp120/msvcp120.spec
index 422f0b6..653b742 100644
--- a/dlls/msvcp120/msvcp120.spec
+++ b/dlls/msvcp120/msvcp120.spec
@@ -3838,9 +3838,9 @@
@ stub _Xp_setw
@ stub _Xp_sqrtx
@ stub _Xp_subx
-@ stub _Xtime_diff_to_millis
-@ stub _Xtime_diff_to_millis2
-@ cdecl _Xtime_get_ticks()
+@ cdecl _Xtime_diff_to_millis(ptr)
+@ cdecl _Xtime_diff_to_millis2(ptr ptr)
+@ cdecl -ret64 _Xtime_get_ticks()
# extern _Zero
@ stub __Wcrtomb_lk
-@ stub xtime_get
+@ cdecl xtime_get(ptr long)
diff --git a/dlls/msvcp120/tests/Makefile.in b/dlls/msvcp120/tests/Makefile.in
new file mode 100644
index 0000000..fc08699
--- /dev/null
+++ b/dlls/msvcp120/tests/Makefile.in
@@ -0,0 +1,5 @@
+TESTDLL = msvcp120.dll
+APPMODE = -mno-cygwin
+
+C_SRCS = \
+ msvcp120.c
diff --git a/dlls/msvcp120/tests/msvcp120.c b/dlls/msvcp120/tests/msvcp120.c
new file mode 100644
index 0000000..1b1dbf0
--- /dev/null
+++ b/dlls/msvcp120/tests/msvcp120.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2014 Yifu Wang for ESRI
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "wine/test.h"
+#include "winbase.h"
+
+typedef int MSVCRT_long;
+
+/* xtime */
+typedef struct {
+ __time64_t sec;
+ MSVCRT_long nsec;
+} xtime;
+
+static MSVCRT_long (__cdecl *p__Xtime_diff_to_millis2)(const xtime*, const xtime*);
+static int (__cdecl *p_xtime_get)(xtime*, int);
+
+static HMODULE msvcp;
+
+static BOOL init(void)
+{
+ msvcp = LoadLibraryA("msvcp120.dll");
+ if(!msvcp)
+ {
+ win_skip("msvcp120.dll not installed\n");
+ return FALSE;
+ }
+
+ p__Xtime_diff_to_millis2 = (void*)GetProcAddress(msvcp, "_Xtime_diff_to_millis2");
+ p_xtime_get = (void*)GetProcAddress(msvcp, "xtime_get");
+
+ return TRUE;
+}
+
+static void test__Xtime_diff_to_millis2(void)
+{
+ struct {
+ __time64_t sec_before;
+ MSVCRT_long nsec_before;
+ __time64_t sec_after;
+ MSVCRT_long nsec_after;
+ MSVCRT_long expect;
+ } tests[] = {
+ {1, 0, 2, 0, 1000},
+ {0, 1000000000, 0, 2000000000, 1000},
+ {1, 100000000, 2, 100000000, 1000},
+ {1, 100000000, 1, 200000000, 100},
+ {0, 0, 0, 1000000000, 1000},
+ {0, 0, 0, 1200000000, 1200},
+ {0, 0, 0, 1230000000, 1230},
+ {0, 0, 0, 1234000000, 1234},
+ {0, 0, 0, 1234100000, 1235},
+ {0, 0, 0, 1234900000, 1235},
+ {0, 0, 0, 1234010000, 1235},
+ {0, 0, 0, 1234090000, 1235},
+ {0, 0, 0, 1234000001, 1235},
+ {0, 0, 0, 1234000009, 1235},
+ {0, 0, -1, 0, 0},
+ {0, 0, 0, -10000000, 0},
+ {0, 0, -1, -100000000, 0},
+ {-1, 0, 0, 0, 1000},
+ {0, -100000000, 0, 0, 100},
+ {-1, -100000000, 0, 0, 1100},
+ {0, 0, -1, 2000000000, 1000},
+ {0, 0, -2, 2000000000, 0},
+ {0, 0, -2, 2100000000, 100}
+ };
+ int i;
+ MSVCRT_long ret;
+ xtime t1, t2;
+
+ for(i = 0; i < sizeof(tests) / sizeof(tests[0]); ++ i)
+ {
+ t1.sec = tests[i].sec_before;
+ t1.nsec = tests[i].nsec_before;
+ t2.sec = tests[i].sec_after;
+ t2.nsec = tests[i].nsec_after;
+ ret = p__Xtime_diff_to_millis2(&t2, &t1);
+ ok(ret == tests[i].expect,
+ "_Xtime_diff_to_millis2(): test: %d expect: %d, got: %d\n",
+ i, tests[i].expect, ret);
+ }
+}
+
+static void test_xtime_get(void)
+{
+ static const MSVCRT_long tests[] = {1, 50, 100, 200, 500};
+ MSVCRT_long diff;
+ xtime before, after;
+ int i;
+
+ for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i ++)
+ {
+ p_xtime_get(&before, 1);
+ Sleep(tests[i]);
+ p_xtime_get(&after, 1);
+
+ diff = p__Xtime_diff_to_millis2(&after, &before);
+
+ ok(diff >= tests[i],
+ "xtime_get() not functioning correctly, test: %d, expect: ge %d, got: %d\n",
+ i, tests[i], diff);
+ }
+
+ /* Test parameter and return value */
+ before.sec = 0xdeadbeef, before.nsec = 0xdeadbeef;
+ i = p_xtime_get(&before, 0);
+ ok(i == 0, "expect xtime_get() to return 0, got: %d\n", i);
+ ok(before.sec == 0xdeadbeef && before.nsec == 0xdeadbeef,
+ "xtime_get() shouldn't have modified the xtime struct with the given option\n");
+
+ before.sec = 0xdeadbeef, before.nsec = 0xdeadbeef;
+ i = p_xtime_get(&before, 1);
+ ok(i == 1, "expect xtime_get() to return 1, got: %d\n", i);
+ ok(before.sec != 0xdeadbeef && before.nsec != 0xdeadbeef,
+ "xtime_get() should have modified the xtime struct with the given option\n");
+}
+
+START_TEST(msvcp120)
+{
+ if(!init()) return;
+ test__Xtime_diff_to_millis2();
+ test_xtime_get();
+}
diff --git a/dlls/msvcp120_app/msvcp120_app.spec b/dlls/msvcp120_app/msvcp120_app.spec
index 6bc0374..390d470 100644
--- a/dlls/msvcp120_app/msvcp120_app.spec
+++ b/dlls/msvcp120_app/msvcp120_app.spec
@@ -3838,9 +3838,9 @@
@ stub _Xp_setw
@ stub _Xp_sqrtx
@ stub _Xp_subx
-@ stub _Xtime_diff_to_millis
-@ stub _Xtime_diff_to_millis2
-@ cdecl _Xtime_get_ticks() msvcp120._Xtime_get_ticks
+@ cdecl _Xtime_diff_to_millis(ptr) msvcp120._Xtime_diff_to_millis
+@ cdecl _Xtime_diff_to_millis2(ptr ptr) msvcp120._Xtime_diff_to_millis2
+@ cdecl -ret64 _Xtime_get_ticks() msvcp120._Xtime_get_ticks
# extern _Zero
@ stub __Wcrtomb_lk
-@ stub xtime_get
+@ cdecl xtime_get(ptr long) msvcp120.xtime_get
diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c
index 61e43c3..a030b01 100644
--- a/dlls/msvcp90/misc.c
+++ b/dlls/msvcp90/misc.c
@@ -33,6 +33,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcp);
#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY)
#define TICKSPERSEC 10000000
#define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKSPERSEC)
+#define NANOSEC_PER_MILLISEC 1000000
+#define MILLISEC_PER_SEC 1000
struct __Container_proxy;
@@ -350,6 +352,15 @@ void __thiscall _Container_base12__Swap_all(
that->proxy->cont = that;
}
+#if _MSVCP_VER >= 110
+typedef int MSVCRT_long;
+
+/* xtime */
+typedef struct {
+ __time64_t sec;
+ MSVCRT_long nsec;
+} xtime;
+
/* _Xtime_get_ticks */
LONGLONG __cdecl _Xtime_get_ticks(void)
{
@@ -361,6 +372,49 @@ LONGLONG __cdecl _Xtime_get_ticks(void)
return ((LONGLONG)ft.dwHighDateTime<<32) + ft.dwLowDateTime - TICKS_1601_TO_1970;
}
+/* _xtime_get */
+int __cdecl xtime_get(xtime* t, int unknown)
+{
+ LONGLONG ticks;
+
+ TRACE("(%p)\n", t);
+
+ if(unknown != 1)
+ return 0;
+
+ ticks = _Xtime_get_ticks();
+ t->sec = ticks / TICKSPERSEC;
+ t->nsec = ticks % TICKSPERSEC * 100;
+ return 1;
+}
+
+/* _Xtime_diff_to_millis2 */
+MSVCRT_long __cdecl _Xtime_diff_to_millis2(xtime *t1, xtime *t2)
+{
+ __time64_t diff_sec;
+ MSVCRT_long diff_nsec, ret;
+
+ TRACE("(%p, %p)\n", t1, t2);
+
+ diff_sec = t1->sec - t2->sec;
+ diff_nsec = t1->nsec - t2->nsec;
+ ret = diff_sec * MILLISEC_PER_SEC +
+ (diff_nsec + NANOSEC_PER_MILLISEC - 1) / NANOSEC_PER_MILLISEC;
+ return ret > 0 ? ret : 0;
+}
+
+/* _Xtime_diff_to_millis */
+MSVCRT_long __cdecl _Xtime_diff_to_millis(xtime *t)
+{
+ xtime now;
+
+ TRACE("%p\n", t);
+
+ xtime_get(&now, 1);
+ return _Xtime_diff_to_millis2(t, &now);
+}
+#endif
+
#if _MSVCP_VER >= 90
unsigned int __cdecl _Random_device(void)
{
More information about the wine-cvs
mailing list