Piotr Caban : msvcp140_atomic_wait: Add __std_atomic_wait_direct implementation.

Alexandre Julliard julliard at winehq.org
Thu Apr 28 16:15:31 CDT 2022


Module: wine
Branch: master
Commit: 87f3b50b2d256726e9a150f3a53798de8791b2a7
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=87f3b50b2d256726e9a150f3a53798de8791b2a7

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Wed Apr 27 20:22:25 2022 +0200

msvcp140_atomic_wait: Add __std_atomic_wait_direct implementation.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52821
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msvcp140_atomic_wait/main.c                   |  7 ++
 .../msvcp140_atomic_wait/msvcp140_atomic_wait.spec |  2 +-
 .../tests/msvcp140_atomic_wait.c                   | 76 ++++++++++++++++++++++
 3 files changed, 84 insertions(+), 1 deletion(-)

diff --git a/dlls/msvcp140_atomic_wait/main.c b/dlls/msvcp140_atomic_wait/main.c
index a4ea3d619f5..bee7164e09f 100644
--- a/dlls/msvcp140_atomic_wait/main.c
+++ b/dlls/msvcp140_atomic_wait/main.c
@@ -74,3 +74,10 @@ void __stdcall __std_atomic_notify_all_direct(void *addr)
     TRACE("(%p)\n", addr);
     WakeByAddressAll(addr);
 }
+
+BOOL __stdcall __std_atomic_wait_direct(volatile void *addr, void *cmp,
+                                        SIZE_T size, DWORD timeout)
+{
+    TRACE("(%p %p %Id %ld)\n", addr, cmp, size, timeout);
+    return WaitOnAddress(addr, cmp, size, timeout);
+}
diff --git a/dlls/msvcp140_atomic_wait/msvcp140_atomic_wait.spec b/dlls/msvcp140_atomic_wait/msvcp140_atomic_wait.spec
index 0c99585c057..04b5bf2c7f9 100644
--- a/dlls/msvcp140_atomic_wait/msvcp140_atomic_wait.spec
+++ b/dlls/msvcp140_atomic_wait/msvcp140_atomic_wait.spec
@@ -7,7 +7,7 @@
 @ stdcall __std_atomic_notify_one_direct(ptr)
 @ stub __std_atomic_notify_one_indirect
 @ stub __std_atomic_set_api_level
-@ stub __std_atomic_wait_direct
+@ stdcall __std_atomic_wait_direct(ptr ptr long long)
 @ stub __std_atomic_wait_get_deadline
 @ stub __std_atomic_wait_get_remaining_timeout
 @ stub __std_atomic_wait_indirect
diff --git a/dlls/msvcp140_atomic_wait/tests/msvcp140_atomic_wait.c b/dlls/msvcp140_atomic_wait/tests/msvcp140_atomic_wait.c
index 42fefc4db03..c10217cf34f 100644
--- a/dlls/msvcp140_atomic_wait/tests/msvcp140_atomic_wait.c
+++ b/dlls/msvcp140_atomic_wait/tests/msvcp140_atomic_wait.c
@@ -17,6 +17,7 @@
  */
 
 #include <stdio.h>
+#include <process.h>
 
 #include "windef.h"
 #include "winbase.h"
@@ -29,6 +30,8 @@ static void (__stdcall *p___std_close_threadpool_work)(PTP_WORK);
 static PTP_WORK (__stdcall *p___std_create_threadpool_work)(PTP_WORK_CALLBACK, void*, PTP_CALLBACK_ENVIRON);
 static void (__stdcall *p___std_submit_threadpool_work)(PTP_WORK);
 static void (__stdcall *p___std_wait_for_threadpool_work_callbacks)(PTP_WORK, BOOL);
+static BOOL (__stdcall *p___std_atomic_wait_direct)(volatile void*, void*, size_t, DWORD);
+static void (__stdcall *p___std_atomic_notify_one_direct)(void*);
 
 #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)
@@ -46,6 +49,8 @@ static HMODULE init(void)
     SET(p___std_create_threadpool_work, "__std_create_threadpool_work");
     SET(p___std_submit_threadpool_work, "__std_submit_threadpool_work");
     SET(p___std_wait_for_threadpool_work_callbacks, "__std_wait_for_threadpool_work_callbacks");
+    SET(p___std_atomic_wait_direct, "__std_atomic_wait_direct");
+    SET(p___std_atomic_notify_one_direct, "__std_atomic_notify_one_direct");
     return msvcp;
 }
 
@@ -162,6 +167,76 @@ static void test_threadpool_work(void)
     ok(!work, "expected failure\n");
 }
 
+LONG64 address;
+static void __cdecl atomic_wait_thread(void *arg)
+{
+    LONG64 compare = 0;
+    int r;
+
+    r  = p___std_atomic_wait_direct(&address, &compare, sizeof(address), 2000);
+    ok(r == 1, "r = %d\n", r);
+}
+
+static void test___std_atomic_wait_direct(void)
+{
+    LONG64 compare;
+    HANDLE thread;
+    DWORD gle;
+    int r;
+
+    if (!GetProcAddress(GetModuleHandleA("kernelbase"), "WaitOnAddress"))
+    {
+        win_skip("WaitOnAddress not available\n");
+        return;
+    }
+
+    address = compare = 0;
+    SetLastError(0);
+    r = p___std_atomic_wait_direct(&address, &compare, 5, 0);
+    ok(!r, "r = %d\n", r);
+    gle = GetLastError();
+    ok(gle == ERROR_INVALID_PARAMETER, "expected %d, got %ld\n", ERROR_INVALID_PARAMETER, gle);
+
+    SetLastError(0);
+    r = p___std_atomic_wait_direct(&address, &compare, 1, 0);
+    ok(!r, "r = %d\n", r);
+    gle = GetLastError();
+    ok(gle == ERROR_TIMEOUT, "expected %d, got %ld\n", ERROR_TIMEOUT, gle);
+    r = p___std_atomic_wait_direct(&address, &compare, 2, 0);
+    ok(!r, "r = %d\n", r);
+    gle = GetLastError();
+    ok(gle == ERROR_TIMEOUT, "expected %d, got %ld\n", ERROR_TIMEOUT, gle);
+    r = p___std_atomic_wait_direct(&address, &compare, 4, 0);
+    ok(!r, "r = %d\n", r);
+    gle = GetLastError();
+    ok(gle == ERROR_TIMEOUT, "expected %d, got %ld\n", ERROR_TIMEOUT, gle);
+    r = p___std_atomic_wait_direct(&address, &compare, 8, 0);
+    ok(!r, "r = %d\n", r);
+    gle = GetLastError();
+    ok(gle == ERROR_TIMEOUT, "expected %d, got %ld\n", ERROR_TIMEOUT, gle);
+
+    SetLastError(0);
+    r = p___std_atomic_wait_direct(&address, &compare, 8, 1);
+    ok(!r, "r = %d\n", r);
+    gle = GetLastError();
+    ok(gle == ERROR_TIMEOUT, "expected %d, got %ld\n", ERROR_TIMEOUT, gle);
+
+    compare = 1;
+    SetLastError(0);
+    r = p___std_atomic_wait_direct(&address, &compare, 8, 0);
+    ok(r == 1, "r = %d\n", r);
+    gle = GetLastError();
+    ok(!gle, "expected 0, got %ld\n", gle);
+
+    thread = (HANDLE)_beginthread(atomic_wait_thread, 0, NULL);
+    ok(thread != INVALID_HANDLE_VALUE, "_beginthread failed\n");
+    Sleep(100);
+    address = 1;
+    p___std_atomic_notify_one_direct(&address);
+    WaitForSingleObject(thread, INFINITE);
+    CloseHandle(thread);
+}
+
 START_TEST(msvcp140_atomic_wait)
 {
     HMODULE msvcp;
@@ -172,5 +247,6 @@ START_TEST(msvcp140_atomic_wait)
     }
     test___std_parallel_algorithms_hw_threads();
     test_threadpool_work();
+    test___std_atomic_wait_direct();
     FreeLibrary(msvcp);
 }




More information about the wine-cvs mailing list