Commit b5d84635f2

kprotty <kbutcher6200@gmail.com>
2019-11-07 22:46:57
remove WaitOnAddress backend in std.ThreadParker
1 parent b535e86
Changed files (2)
lib
std
lib/std/os/windows/kernel32.zig
@@ -82,8 +82,6 @@ pub extern "kernel32" stdcallcc fn GetFileAttributesW(lpFileName: [*]const WCHAR
 
 pub extern "kernel32" stdcallcc fn GetModuleFileNameW(hModule: ?HMODULE, lpFilename: [*]u16, nSize: DWORD) DWORD;
 
-pub extern "kernel32" stdcallcc fn GetModuleHandleA(lpModuleName: ?[*]const CHAR) ?HMODULE;
-
 pub extern "kernel32" stdcallcc fn GetModuleHandleW(lpModuleName: ?[*]const WCHAR) HMODULE;
 
 pub extern "kernel32" stdcallcc fn GetLastError() DWORD;
@@ -206,8 +204,6 @@ pub extern "kernel32" stdcallcc fn WriteFile(
 
 pub extern "kernel32" stdcallcc fn WriteFileEx(hFile: HANDLE, lpBuffer: [*]const u8, nNumberOfBytesToWrite: DWORD, lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE) BOOL;
 
-pub extern "kernel32" stdcallcc fn LoadLibraryA(lpLibFileName: [*]const u8) ?HMODULE;
-
 pub extern "kernel32" stdcallcc fn LoadLibraryW(lpLibFileName: [*]const u16) ?HMODULE;
 
 pub extern "kernel32" stdcallcc fn GetProcAddress(hModule: HMODULE, lpProcName: [*]const u8) ?FARPROC;
lib/std/parker.zig
@@ -76,107 +76,39 @@ const WindowsParker = struct {
     pub fn deinit(self: *WindowsParker) void {}
 
     pub fn unpark(self: *WindowsParker, ptr: *const u32) void {
-        switch (Backend.get().*) {
-            .WaitAddress => |*backend| backend.unpark(ptr, &self.waiters),
-            .KeyedEvent => |*backend| backend.unpark(ptr, &self.waiters),
+        const handle = getEventHandlePtr().*;
+        const key = @ptrCast(*const c_void, ptr);
+        var waiting = @atomicLoad(u32, &self.waiters, .Monotonic);
+        while (waiting != 0) {
+            waiting = @cmpxchgWeak(u32, &self.waiters, waiting, waiting - 1, .Acquire, .Monotonic) orelse {
+                const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null);
+                assert(rc == 0);
+                return;
+            };
         }
     }
 
     pub fn park(self: *WindowsParker, ptr: *const u32, expected: u32) void {
-        switch (Backend.get().*) {
-            .WaitAddress => |*backend| backend.park(ptr, expected, &self.waiters),
-            .KeyedEvent => |*backend| backend.park(ptr, expected, &self.waiters),
+        const handle = getEventHandlePtr().*;
+        const key = @ptrCast(*const c_void, ptr);
+        while (@atomicLoad(u32, ptr, .Acquire) == expected) {
+            _ = @atomicRmw(u32, &self.waiters, .Add, 1, .Release);
+            const rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null);
+            assert(rc == 0);
         }
     }
 
-    const Backend = union(enum) {
-        WaitAddress: WaitAddress,
-        KeyedEvent: KeyedEvent,
-
-        var backend = std.lazyInit(Backend);
-
-        fn get() *const Backend {
-            return backend.get() orelse {
-                // Statically linking to the KeyedEvent functions should mean its supported.
-                // TODO: Maybe add a CreateSemaphore backend for systems older than Windows XP ?
-                backend.data = WaitAddress.init() 
-                    orelse KeyedEvent.init()
-                    orelse unreachable; 
-                backend.resolve();
-                return &backend.data;
-            };
-        }
-
-        const WaitAddress = struct {
-            WakeByAddressSingle: stdcallcc fn(Address: *const c_void) void,
-            WaitOnAddress: stdcallcc fn (
-                Address: *const c_void,
-                CompareAddress: *const c_void,
-                AddressSize: windows.SIZE_T,
-                dwMilliseconds: windows.DWORD,
-            ) windows.BOOL,
-
-            fn init() ?Backend {
-                const dll_name = c"api-ms-win-core-synch-l1-2-0";
-                const dll = windows.kernel32.GetModuleHandleA(dll_name)
-                    orelse windows.kernel32.LoadLibraryA(dll_name)
-                    orelse return null;
-
-                var self: WaitAddress = undefined;
-                const WaitOnAddress = windows.kernel32.GetProcAddress(dll, c"WaitOnAddress") orelse return null;
-                self.WaitOnAddress = @intToPtr(@typeOf(self.WaitOnAddress), @ptrToInt(WaitOnAddress));
-                const WakeByAddressSingle = windows.kernel32.GetProcAddress(dll, c"WakeByAddressSingle") orelse return null;
-                self.WakeByAddressSingle = @intToPtr(@typeOf(self.WakeByAddressSingle), @ptrToInt(WakeByAddressSingle));
-                return Backend{ .WaitAddress = self };
-            }
-
-            fn unpark(self: WaitAddress, ptr: *const u32, waiters: *u32) void {
-                const addr = @ptrCast(*const c_void, ptr);
-                self.WakeByAddressSingle(addr);
-            }
+    var event_handle = std.lazyInit(windows.HANDLE);
 
-            fn park(self: WaitAddress, ptr: *const u32, expected: u32, waiters: *u32) void {
-                var compare = expected;
-                const addr = @ptrCast(*const c_void, ptr);
-                const cmp = @ptrCast(*const c_void, &compare);
-                while (@atomicLoad(u32, ptr, .Acquire) == expected)
-                    _ = self.WaitOnAddress(addr, cmp, @sizeOf(u32), windows.INFINITE);
-            }
+    fn getEventHandlePtr() *const windows.HANDLE {
+        return event_handle.get() orelse {
+            const access_mask = windows.GENERIC_READ | windows.GENERIC_WRITE;
+            if (windows.ntdll.NtCreateKeyedEvent(&event_handle.data, access_mask, null, 0) != 0)
+                @panic("Failed to setup an NT Keyed Event handle for the process");
+            event_handle.resolve();
+            return &event_handle.data;
         };
-
-        const KeyedEvent = struct {
-            handle: windows.HANDLE,
-
-            fn init() ?Backend {
-                var self: KeyedEvent = undefined;
-                const access_mask = windows.GENERIC_READ | windows.GENERIC_WRITE;
-                if (windows.ntdll.NtCreateKeyedEvent(&self.handle, access_mask, null, 0) != 0)
-                    return null;
-                return Backend{ .KeyedEvent = self };
-            }
-
-            fn unpark(self: KeyedEvent, ptr: *const u32, waiters: *u32) void {
-                const key = @ptrCast(*const c_void, ptr);
-                var waiting = @atomicLoad(u32, waiters, .Acquire);
-                while (waiting != 0) {
-                    waiting = @cmpxchgWeak(u32, waiters, waiting, waiting - 1, .Acquire, .Monotonic) orelse {
-                        const rc = windows.ntdll.NtReleaseKeyedEvent(self.handle, key, windows.FALSE, null);
-                        assert(rc == 0);
-                        return;
-                    };
-                }
-            }
-
-            fn park(self: KeyedEvent, ptr: *const u32, expected: u32, waiters: *u32) void {
-                const key = @ptrCast(*const c_void, ptr);
-                while (@atomicLoad(u32, ptr, .Acquire) == expected) {
-                    _ = @atomicRmw(u32, waiters, .Add, 1, .Release);
-                    const rc = windows.ntdll.NtWaitForKeyedEvent(self.handle, key, windows.FALSE, null);
-                    assert(rc == 0);
-                }
-            }
-        };
-    };
+    }
 };
 
 const PosixParker = struct {