From: Paul Gofman <pgofman(a)codeweavers.com> --- dlls/kernel32/kernel32.spec | 1 + dlls/kernel32/tests/sync.c | 40 +++++++++++++++++++++++++++++++++ dlls/kernelbase/kernelbase.spec | 6 ++--- dlls/kernelbase/sync.c | 35 +++++++++++++++++++++++++++++ include/synchapi.h | 12 ++++++++++ include/winnt.h | 8 +++++++ 6 files changed, 99 insertions(+), 3 deletions(-) diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 3bb49206c6b..31ed292a6c6 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -376,6 +376,7 @@ # @ stub DisableThreadProfiling @ stdcall DisassociateCurrentThreadFromCallback(ptr) NTDLL.TpDisassociateCallback @ stdcall DiscardVirtualMemory(ptr long) kernelbase.DiscardVirtualMemory +@ stdcall -import DeleteSynchronizationBarrier(ptr) @ stdcall DeleteTimerQueue(long) @ stdcall -import DeleteTimerQueueEx(long long) @ stdcall -import DeleteTimerQueueTimer(long long long) diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c index faaaa381623..9571567647a 100644 --- a/dlls/kernel32/tests/sync.c +++ b/dlls/kernel32/tests/sync.c @@ -69,6 +69,10 @@ static PSLIST_ENTRY (WINAPI *pRtlInterlockedPushListSListEx)(PSLIST_HEADER list, static NTSTATUS (WINAPI *pNtQueueApcThread)(HANDLE,PNTAPCFUNC,ULONG_PTR,ULONG_PTR,ULONG_PTR); static NTSTATUS (WINAPI *pNtTestAlert)(void); +BOOL (WINAPI *pInitializeSynchronizationBarrier)(SYNCHRONIZATION_BARRIER *,LONG, LONG); +BOOL (WINAPI *pDeleteSynchronizationBarrier)(SYNCHRONIZATION_BARRIER *); +BOOL (WINAPI *pEnterSynchronizationBarrier)(SYNCHRONIZATION_BARRIER*, DWORD); + #ifdef __i386__ #pragma pack(push,1) @@ -2992,6 +2996,38 @@ static void test_QueueUserAPC(void) } } +static void test_barrier(void) +{ + SYNCHRONIZATION_BARRIER barrier; + BOOL bval; + + if (!pInitializeSynchronizationBarrier) + { + win_skip("InitializeSynchronizationBarrier is not available.\n"); + return; + } + + SetLastError( 0xdeadbeef ); + bval = pInitializeSynchronizationBarrier( &barrier, 1, -1 ); + ok( bval == TRUE, "got %#x.\n", bval ); + ok( GetLastError() == 0xdeadbeef, "got %lu.\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + bval = pEnterSynchronizationBarrier( &barrier, 0 ); + ok( bval == TRUE, "got %#x.\n", bval ); + ok( GetLastError() == 0xdeadbeef, "got %lu.\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + bval = pEnterSynchronizationBarrier( &barrier, 0 ); + ok( bval == TRUE, "got %#x.\n", bval ); + ok( GetLastError() == 0xdeadbeef, "got %lu.\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + bval = pDeleteSynchronizationBarrier( &barrier ); + ok( bval == TRUE, "got %#x.\n", bval ); + ok( GetLastError() == 0xdeadbeef, "got %lu.\n", GetLastError() ); +} + START_TEST(sync) { char **argv; @@ -3017,6 +3053,9 @@ START_TEST(sync) pTryAcquireSRWLockExclusive = (void *)GetProcAddress(hdll, "TryAcquireSRWLockExclusive"); pTryAcquireSRWLockShared = (void *)GetProcAddress(hdll, "TryAcquireSRWLockShared"); pQueueUserAPC2 = (void *)GetProcAddress(hdll, "QueueUserAPC2"); + pInitializeSynchronizationBarrier = (void *)GetProcAddress(hdll, "InitializeSynchronizationBarrier"); + pDeleteSynchronizationBarrier = (void *)GetProcAddress(hdll, "DeleteSynchronizationBarrier"); + pEnterSynchronizationBarrier = (void *)GetProcAddress(hdll, "EnterSynchronizationBarrier"); pNtAllocateVirtualMemory = (void *)GetProcAddress(hntdll, "NtAllocateVirtualMemory"); pNtFreeVirtualMemory = (void *)GetProcAddress(hntdll, "NtFreeVirtualMemory"); pNtWaitForSingleObject = (void *)GetProcAddress(hntdll, "NtWaitForSingleObject"); @@ -3064,4 +3103,5 @@ START_TEST(sync) test_alertable_wait(); test_apc_deadlock(); test_crit_section(); + test_barrier(); } diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index d16e2e0e2d4..28c5376e4cd 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -264,7 +264,7 @@ # @ stub DeleteStateAtomValue # @ stub DeleteStateContainer # @ stub DeleteStateContainerValue -# @ stub DeleteSynchronizationBarrier +@ stdcall DeleteSynchronizationBarrier(ptr) @ stdcall DeleteTimerQueueEx(long long) @ stdcall DeleteTimerQueueTimer(long long long) @ stdcall DeleteVolumeMountPointW(wstr) @@ -297,7 +297,7 @@ @ stdcall EncodeSystemPointer(ptr) ntdll.RtlEncodeSystemPointer # @ stub EnterCriticalPolicySectionInternal @ stdcall EnterCriticalSection(ptr) ntdll.RtlEnterCriticalSection -# @ stub EnterSynchronizationBarrier +@ stdcall EnterSynchronizationBarrier(ptr long) @ stdcall EnumCalendarInfoExEx(ptr wstr long wstr long long) @ stdcall EnumCalendarInfoExW(ptr long long long) @ stdcall EnumCalendarInfoW(ptr long long long) @@ -851,7 +851,7 @@ @ stdcall InitializeSRWLock(ptr) ntdll.RtlInitializeSRWLock @ stdcall InitializeSecurityDescriptor(ptr long) @ stdcall InitializeSid(ptr ptr long) -# @ stub InitializeSynchronizationBarrier +@ stdcall InitializeSynchronizationBarrier(ptr long long) # @ stub InstallELAMCertificateInfo @ stdcall -arch=i386 InterlockedCompareExchange(ptr long long) @ stdcall -arch=i386 -ret64 InterlockedCompareExchange64(ptr int64 int64) ntdll.RtlInterlockedCompareExchange64 diff --git a/dlls/kernelbase/sync.c b/dlls/kernelbase/sync.c index 36e29a3cab0..99fa0516013 100644 --- a/dlls/kernelbase/sync.c +++ b/dlls/kernelbase/sync.c @@ -1824,3 +1824,38 @@ __ASM_STDCALL_FUNC(InterlockedDecrement, 4, "ret $4") #endif /* __i386__ */ + + +/*********************************************************************** + * Synchronization barrier functions + ***********************************************************************/ + + +/*********************************************************************** + * InitializeSynchronizationBarrier (kernelbase.@) + */ +BOOL WINAPI InitializeSynchronizationBarrier( SYNCHRONIZATION_BARRIER *barrier, LONG thread_count, LONG spin_count ) +{ + FIXME( "%p %ld %ld stub.\n", barrier, thread_count, spin_count ); + return TRUE; +} + + +/*********************************************************************** + * DeleteSynchronizationBarrier (kernelbase.@) + */ +BOOL WINAPI DeleteSynchronizationBarrier( SYNCHRONIZATION_BARRIER *barrier ) +{ + FIXME( "%p stub.\n", barrier ); + return TRUE; +} + + +/*********************************************************************** + * EnterSynchronizationBarrier (kernelbase.@) + */ +BOOL WINAPI EnterSynchronizationBarrier( SYNCHRONIZATION_BARRIER *barrier, DWORD flags ) +{ + FIXME( "%p %#lx stub.\n", barrier, flags ); + return TRUE; +} diff --git a/include/synchapi.h b/include/synchapi.h index 0b3dcb8ff74..aabb44c5a53 100644 --- a/include/synchapi.h +++ b/include/synchapi.h @@ -27,6 +27,18 @@ BOOL WINAPI WaitOnAddress(volatile void*, void*, SIZE_T, DWORD); void WINAPI WakeByAddressAll(void*); void WINAPI WakeByAddressSingle(void*); +typedef RTL_BARRIER SYNCHRONIZATION_BARRIER; +typedef PRTL_BARRIER PSYNCHRONIZATION_BARRIER; +typedef PRTL_BARRIER LPSYNCHRONIZATION_BARRIER; + +#define SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY 0x1 +#define SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY 0x2 +#define SYNCHRONIZATION_BARRIER_FLAGS_NO_DELETE 0x4 + +BOOL WINAPI InitializeSynchronizationBarrier(SYNCHRONIZATION_BARRIER *,LONG, LONG); +BOOL WINAPI DeleteSynchronizationBarrier(SYNCHRONIZATION_BARRIER *); +BOOL WINAPI EnterSynchronizationBarrier(SYNCHRONIZATION_BARRIER*, DWORD); + #ifdef __cplusplus } #endif diff --git a/include/winnt.h b/include/winnt.h index d360f5d0178..e112740e0e1 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -6237,6 +6237,14 @@ NTSYSAPI DWORD WINAPI RtlRunOnceBeginInitialize(PRTL_RUN_ONCE, DWORD, PVOID*); NTSYSAPI DWORD WINAPI RtlRunOnceComplete(PRTL_RUN_ONCE, DWORD, PVOID); NTSYSAPI WORD WINAPI RtlCaptureStackBackTrace(DWORD,DWORD,void**,DWORD*); +typedef struct _RTL_BARRIER { + DWORD Reserved1; + DWORD Reserved2; + ULONG_PTR Reserved3[2]; + DWORD Reserved4; + DWORD Reserved5; +} RTL_BARRIER, *PRTL_BARRIER; + #pragma pack(push,8) typedef struct _IO_COUNTERS { ULONGLONG ReadOperationCount; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9267