From: quininer quininer@live.com
--- dlls/kernelbase/sync.c | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-)
diff --git a/dlls/kernelbase/sync.c b/dlls/kernelbase/sync.c index 04609769f79..6181006802f 100644 --- a/dlls/kernelbase/sync.c +++ b/dlls/kernelbase/sync.c @@ -1684,24 +1684,59 @@ BOOL WINAPI DECLSPEC_HOTPATCH InitOnceExecuteOnce( INIT_ONCE *once, PINIT_ONCE_F return !RtlRunOnceExecuteOnce( once, (PRTL_RUN_ONCE_INIT_FN)func, param, context ); }
+typedef struct { + SRWLOCK lock; + CONDITION_VARIABLE cond; + LONG count; +} barrier_t; + /*********************************************************************** * InitializeSynchronizationBarrier (kernelbase.@) */ BOOL WINAPI DECLSPEC_HOTPATCH InitializeSynchronizationBarrier( LPSYNCHRONIZATION_BARRIER lpBarrier, LONG lTotalThreads, LONG lSpinCount ) { - return 0; + barrier_t *barrier = lpBarrier; + + RtlInitializeSRWLock(&barrier->lock); + RtlInitializeConditionVariable(&barrier->cond); + barrier->count = lTotalThreads; + + return TRUE; }
BOOL WINAPI DECLSPEC_HOTPATCH EnterSynchronizationBarrier( LPSYNCHRONIZATION_BARRIER lpBarrier, DWORD dwFlags ) { - return 0; + barrier_t *barrier = lpBarrier; + BOOL wait = TRUE; + BOOL hint = FALSE; + + RtlAcquireSRWLockExclusive(&barrier->lock); + + if (barrier->count > 0) { + barrier->count -= 1; + } + + if (barrier->count == 0) { + RtlWakeAllConditionVariable(&barrier->cond); + wait = FALSE; + hint = TRUE; + } + + while (wait) { + SleepConditionVariableSRW(&barrier->cond, &barrier->lock, INFINITE, 0); + wait = barrier->count > 0; + } + + RtlReleaseSRWLockExclusive(&barrier->lock); + + return hint; }
BOOL WINAPI DECLSPEC_HOTPATCH DeleteSynchronizationBarrier( LPSYNCHRONIZATION_BARRIER lpBarrier ) { - return 0; + return TRUE; }