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