[PATCH] kernel32: add basic conditional variables support (try 2)
Marcus Meissner
marcus at jet.franken.de
Sun Aug 19 15:43:58 CDT 2012
Hi,
Started with patch from Austin, brought up to a point
where Adobe Lightroom 4.1 starts up.
The synchronisation is probably not 100% correct and
not sufficiently atomic.
resubmit: fixed timed waitloop now using 100ms steps not full
wait, removed superflous comment.
Ciao, Marcus
---
dlls/kernel32/kernel32.spec | 4 +++
dlls/kernel32/sync.c | 64 +++++++++++++++++++++++++++++++++++++++++++
include/winbase.h | 4 +++
include/winnt.h | 6 ++++
4 files changed, 78 insertions(+), 0 deletions(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index 736fbde..da1d83d 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -743,6 +743,7 @@
@ stdcall IdnToUnicode(long wstr long ptr long)
@ stdcall InitAtomTable(long)
@ stdcall InitializeSRWLock(ptr)
+@ stdcall InitializeConditionVariable(ptr)
@ stdcall InitializeCriticalSection(ptr)
@ stdcall InitializeCriticalSectionAndSpinCount(ptr long)
@ stdcall InitializeCriticalSectionEx(ptr long long)
@@ -1184,6 +1185,7 @@
@ stdcall SignalObjectAndWait(long long long long)
@ stdcall SizeofResource(long long)
@ stdcall Sleep(long)
+@ stdcall SleepConditionVariableCS(ptr ptr long)
@ stdcall SleepEx(long long)
@ stdcall SuspendThread(long)
@ stdcall SwitchToFiber(ptr)
@@ -1253,6 +1255,8 @@
@ stdcall WaitForSingleObjectEx(long long long)
@ stdcall WaitNamedPipeA (str long)
@ stdcall WaitNamedPipeW (wstr long)
+@ stdcall WakeAllConditionVariable (ptr)
+@ stdcall WakeConditionVariable (ptr)
@ stdcall WerRegisterFile(wstr long long)
@ stdcall WerRegisterMemoryBlock(ptr long)
@ stdcall WerRegisterRuntimeExceptionModule(wstr ptr)
diff --git a/dlls/kernel32/sync.c b/dlls/kernel32/sync.c
index f8c951b..787a72d 100644
--- a/dlls/kernel32/sync.c
+++ b/dlls/kernel32/sync.c
@@ -2299,3 +2299,67 @@ __ASM_STDCALL_FUNC(InterlockedDecrement, 4,
"ret $4")
#endif /* __i386__ */
+
+/**********************************************************************
+ * InitializeConditionVariable (KERNEL32.@)
+ */
+VOID WINAPI InitializeConditionVariable(PCONDITION_VARIABLE variable)
+{
+ variable->Ptr = 0;
+ FIXME("(%p) semi-correct stub\n", variable);
+}
+
+/**********************************************************************
+ * WakeConditionVariable (KERNEL32.@)
+ */
+VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE variable)
+{
+ LONG ret;
+ FIXME("(%p) semi-correct stub\n", variable);
+ ret = InterlockedDecrement((PLONG)&variable->Ptr);
+ /* don't go below 0 */
+ if (!ret) InterlockedExchange((PLONG)&variable->Ptr, 0);
+}
+
+/**********************************************************************
+ * WakeConditionVariable (KERNEL32.@)
+ */
+VOID WINAPI WakeAllConditionVariable(PCONDITION_VARIABLE variable)
+{
+ FIXME("(%p) semi-correct stub\n", variable);
+ InterlockedExchange((PLONG)&variable->Ptr, 0);
+}
+
+/**********************************************************************
+ * SleepConditionVariableCS (KERNEL32.@)
+ */
+BOOL WINAPI SleepConditionVariableCS(PCONDITION_VARIABLE variable,
+ LPCRITICAL_SECTION crit, DWORD milliseconds
+)
+{
+ static int cnt = 0;
+ LONG val;
+ BOOL ret;
+
+ if (cnt++ < 10)
+ FIXME("(%p, %p, %d): semi-correct stub.\n", variable, crit, milliseconds);
+ RtlLeaveCriticalSection(crit);
+ val = InterlockedIncrement((PLONG)&variable->Ptr);
+ if (milliseconds == INFINITE) {
+ while (val < *((PLONG)&variable->Ptr))
+ SleepEx(100,TRUE);
+ } else {
+ while ((milliseconds > 0) && (val < *((PLONG)&variable->Ptr))) {
+ DWORD ms = 100;
+
+ if (ms>milliseconds)
+ ms = milliseconds;
+ SleepEx(ms,TRUE);
+ milliseconds -= ms;
+ }
+ }
+ /* FIXME: make atomic? */
+ ret = val >= *((PLONG)&variable->Ptr);
+ RtlEnterCriticalSection(crit);
+ return ret;
+}
diff --git a/include/winbase.h b/include/winbase.h
index 2b384f6..4ed87bf 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -63,6 +63,10 @@ typedef PRTL_SRWLOCK PSRWLOCK;
typedef WAITORTIMERCALLBACKFUNC WAITORTIMERCALLBACK;
+#define CONDITION_VARIABLE_INIT RTL_CONDITION_VARIABLE_INIT
+#define CONDITION_VARIABLE_LOCKMODE_SHARED RTL_CONDITION_VARIABLE_LOCKMODE_SHARED
+typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE;
+
#define EXCEPTION_DEBUG_EVENT 1
#define CREATE_THREAD_DEBUG_EVENT 2
#define CREATE_PROCESS_DEBUG_EVENT 3
diff --git a/include/winnt.h b/include/winnt.h
index 5625e37..5106701 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -5082,6 +5082,12 @@ typedef struct _RTL_SRWLOCK {
#define RTL_SRWLOCK_INIT {0}
+typedef struct _RTL_CONDITION_VARIABLE {
+ PVOID Ptr;
+} RTL_CONDITION_VARIABLE, *PRTL_CONDITION_VARIABLE;
+#define RTL_CONDITION_VARIABLE_INIT {0}
+#define RTL_CONDITION_VARIABLE_LOCKMODE_SHARED 0x1
+
typedef VOID (NTAPI * WAITORTIMERCALLBACKFUNC) (PVOID, BOOLEAN );
typedef VOID (NTAPI * PFLS_CALLBACK_FUNCTION) ( PVOID );
--
1.7.3.4
More information about the wine-patches
mailing list