[PATCH] msvcp140/tests: Initial tests for thread functions

Nikolay Sivov nsivov at codeweavers.com
Mon Aug 8 16:26:04 CDT 2016


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---

Duplicated from msvcp120 tests with necessary changes.


 configure.ac                    |   1 +
 dlls/msvcp140/tests/Makefile.in |   5 ++
 dlls/msvcp140/tests/msvcp140.c  | 193 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 199 insertions(+)
 create mode 100644 dlls/msvcp140/tests/Makefile.in
 create mode 100644 dlls/msvcp140/tests/msvcp140.c

diff --git a/configure.ac b/configure.ac
index bfb479b..5cd8a23 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3101,6 +3101,7 @@ WINE_CONFIG_DLL(msvcp120)
 WINE_CONFIG_TEST(dlls/msvcp120/tests)
 WINE_CONFIG_DLL(msvcp120_app)
 WINE_CONFIG_DLL(msvcp140)
+WINE_CONFIG_TEST(dlls/msvcp140/tests)
 WINE_CONFIG_DLL(msvcp60)
 WINE_CONFIG_TEST(dlls/msvcp60/tests)
 WINE_CONFIG_DLL(msvcp70)
diff --git a/dlls/msvcp140/tests/Makefile.in b/dlls/msvcp140/tests/Makefile.in
new file mode 100644
index 0000000..fde164b
--- /dev/null
+++ b/dlls/msvcp140/tests/Makefile.in
@@ -0,0 +1,5 @@
+TESTDLL   = msvcp140.dll
+APPMODE   = -mno-cygwin
+
+C_SRCS = \
+	msvcp140.c
diff --git a/dlls/msvcp140/tests/msvcp140.c b/dlls/msvcp140/tests/msvcp140.c
new file mode 100644
index 0000000..b720ce6
--- /dev/null
+++ b/dlls/msvcp140/tests/msvcp140.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2016 Nikolay Sivov
+ *
+ * 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 <locale.h>
+#include <stdio.h>
+#include <math.h>
+#include <limits.h>
+
+#include "wine/test.h"
+#include "winbase.h"
+
+typedef int MSVCRT_long;
+
+/* xtime */
+typedef struct {
+    __time64_t sec;
+    MSVCRT_long nsec;
+} xtime;
+
+/* thrd */
+typedef struct
+{
+    HANDLE hnd;
+    DWORD  id;
+} _Thrd_t;
+
+#define TIMEDELTA 250  /* 250 ms uncertainty allowed */
+
+static MSVCRT_long (__cdecl *p__Xtime_diff_to_millis2)(const xtime*, const xtime*);
+static int (__cdecl *p_xtime_get)(xtime*, int);
+typedef int (__cdecl *_Thrd_start_t)(void*);
+static int (__cdecl *p__Thrd_equal)(_Thrd_t, _Thrd_t);
+static void (__cdecl *p__Thrd_sleep)(const xtime*);
+static _Thrd_t (__cdecl *p__Thrd_current)(void);
+static int (__cdecl *p__Thrd_create)(_Thrd_t*, _Thrd_start_t, void*);
+static int (__cdecl *p__Thrd_join)(_Thrd_t, int*);
+static int (__cdecl *p__Thrd_detach)(_Thrd_t);
+
+#ifdef __i386__
+static ULONGLONG (__cdecl *p_i386_Thrd_current)(void);
+static _Thrd_t __cdecl i386_Thrd_current(void)
+{
+    union {
+        _Thrd_t thr;
+        ULONGLONG ull;
+    } r;
+    r.ull = p_i386_Thrd_current();
+    return r.thr;
+}
+#endif
+
+static HMODULE msvcp;
+#define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
+#define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
+static BOOL init(void)
+{
+    msvcp = LoadLibraryA("msvcp140.dll");
+    if (!msvcp)
+    {
+        win_skip("msvcp140.dll not installed\n");
+        return FALSE;
+    }
+
+    SET(p__Xtime_diff_to_millis2,
+            "_Xtime_diff_to_millis2");
+    SET(p_xtime_get,
+            "xtime_get");
+#ifdef __i386__
+    SET(p_i386_Thrd_current,
+            "_Thrd_current");
+    p__Thrd_current = i386_Thrd_current;
+#else
+    SET(p__Thrd_current,
+            "_Thrd_current");
+#endif
+    SET(p__Thrd_equal,
+            "_Thrd_equal");
+    SET(p__Thrd_sleep,
+            "_Thrd_sleep");
+    SET(p__Thrd_create,
+            "_Thrd_create");
+    SET(p__Thrd_join,
+            "_Thrd_join");
+    SET(p__Thrd_detach,
+            "_Thrd_detach");
+
+    return TRUE;
+}
+
+static int __cdecl thrd_thread(void *arg)
+{
+    _Thrd_t *thr = arg;
+
+    if(thr)
+        *thr = p__Thrd_current();
+    return 0x42;
+}
+
+static void test_thrd(void)
+{
+    int ret, i, r;
+    struct test {
+        _Thrd_t a;
+        _Thrd_t b;
+        int     r;
+    };
+    const HANDLE hnd1 = (HANDLE)0xcccccccc;
+    const HANDLE hnd2 = (HANDLE)0xdeadbeef;
+    xtime xt, before, after;
+    MSVCRT_long diff;
+    _Thrd_t ta, tb;
+
+    struct test testeq[] = {
+        { {0,    0}, {0,    0}, 1 },
+        { {0,    1}, {0,    0}, 0 },
+        { {hnd1, 0}, {hnd1, 1}, 0 },
+        { {hnd1, 0}, {hnd2, 0}, 1 }
+    };
+
+    /* test for equal */
+    for(i=0; i<sizeof(testeq)/sizeof(testeq[0]); i++) {
+        ret = p__Thrd_equal(testeq[i].a, testeq[i].b);
+        ok(ret == testeq[i].r, "(%p %u) = (%p %u) expected %d, got %d\n",
+            testeq[i].a.hnd, testeq[i].a.id, testeq[i].b.hnd, testeq[i].b.id, testeq[i].r, ret);
+    }
+
+    /* test for sleep */
+    if (0) /* crash on Windows */
+        p__Thrd_sleep(NULL);
+    p_xtime_get(&xt, 1);
+    xt.sec += 2;
+    p_xtime_get(&before, 1);
+    p__Thrd_sleep(&xt);
+    p_xtime_get(&after, 1);
+    diff = p__Xtime_diff_to_millis2(&after, &before);
+    ok(diff > 2000 - TIMEDELTA, "got %d\n", diff);
+
+    /* test for current */
+    ta = p__Thrd_current();
+    tb = p__Thrd_current();
+    ok(ta.id == tb.id, "got a %d b %d\n", ta.id, tb.id);
+    ok(ta.id == GetCurrentThreadId(), "expected %d, got %d\n", GetCurrentThreadId(), ta.id);
+    /* these can be different if new threads are created at same time */
+    ok(ta.hnd == tb.hnd, "got a %p b %p\n", ta.hnd, tb.hnd);
+    ok(!CloseHandle(ta.hnd), "handle %p not closed\n", ta.hnd);
+    ok(!CloseHandle(tb.hnd), "handle %p not closed\n", tb.hnd);
+
+    /* test for create/join */
+    if (0) /* crash on Windows */
+    {
+        p__Thrd_create(NULL, thrd_thread, NULL);
+        p__Thrd_create(&ta, NULL, NULL);
+    }
+    r = -1;
+    ret = p__Thrd_create(&ta, thrd_thread, (void*)&tb);
+    ok(!ret, "failed to create thread, got %d\n", ret);
+    ret = p__Thrd_join(ta, &r);
+    ok(!ret, "failed to join thread, got %d\n", ret);
+    ok(ta.id == tb.id, "expected %d, got %d\n", ta.id, tb.id);
+    ok(ta.hnd != tb.hnd, "same handles, got %p\n", ta.hnd);
+    ok(r == 0x42, "expected 0x42, got %d\n", r);
+    ret = p__Thrd_detach(ta);
+    ok(ret == 4, "_Thrd_detach should have failed with error 4, got %d\n", ret);
+
+    ret = p__Thrd_create(&ta, thrd_thread, NULL);
+    ok(!ret, "failed to create thread, got %d\n", ret);
+    ret = p__Thrd_detach(ta);
+    ok(!ret, "_Thrd_detach failed, got %d\n", ret);
+}
+
+START_TEST(msvcp140)
+{
+    if (!init()) return;
+
+    test_thrd();
+
+    FreeLibrary(msvcp);
+}
-- 
2.8.1




More information about the wine-patches mailing list