Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 4 +- dlls/ntoskrnl.exe/sync.c | 65 +++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index 33aa108cd7..3ee0e1f808 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -42,9 +42,9 @@ @ stdcall -norelay IofCallDriver(ptr ptr) @ stdcall -norelay IofCompleteRequest(ptr long) @ stdcall -norelay KeAcquireInStackQueuedSpinLock(ptr ptr) -@ stub KeAcquireInStackQueuedSpinLockAtDpcLevel +@ stdcall -norelay KeAcquireInStackQueuedSpinLockAtDpcLevel(ptr ptr) @ stdcall -norelay KeReleaseInStackQueuedSpinLock(ptr) -@ stub KeReleaseInStackQueuedSpinLockFromDpcLevel +@ stdcall -norelay KeReleaseInStackQueuedSpinLockFromDpcLevel(ptr) @ stub KeSetTimeUpdateNotifyRoutine @ stub KefAcquireSpinLockAtDpcLevel @ stub KefReleaseSpinLockFromDpcLevel diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c index 2a4685c5b3..4dc1fc3511 100644 --- a/dlls/ntoskrnl.exe/sync.c +++ b/dlls/ntoskrnl.exe/sync.c @@ -414,6 +414,71 @@ void WINAPI KeReleaseSpinLockFromDpcLevel( KSPIN_LOCK *lock ) InterlockedExchangePointer( (void **)lock, 0 ); }
+#define QUEUED_SPINLOCK_OWNED 0x2 + +/*********************************************************************** + * KeAcquireInStackQueuedSpinLockAtDpcLevel (NTOSKRNL.EXE.@) + */ +#ifdef DEFINE_FASTCALL2_ENTRYPOINT +DEFINE_FASTCALL2_ENTRYPOINT( KeAcquireInStackQueuedSpinLockAtDpcLevel ) +void WINAPI DECLSPEC_HIDDEN __regs_KeAcquireInStackQueuedSpinLockAtDpcLevel( KSPIN_LOCK *lock, KLOCK_QUEUE_HANDLE *queue ) +#else +void WINAPI KeAcquireInStackQueuedSpinLockAtDpcLevel( KSPIN_LOCK *lock, KLOCK_QUEUE_HANDLE *queue ) +#endif +{ + KSPIN_LOCK_QUEUE *tail; + + TRACE("lock %p, queue %p.\n", lock, queue); + + queue->LockQueue.Next = NULL; + + if (!(tail = InterlockedExchangePointer( (void **)lock, &queue->LockQueue ))) + queue->LockQueue.Lock = (KSPIN_LOCK *)((ULONG_PTR)lock | QUEUED_SPINLOCK_OWNED); + else + { + queue->LockQueue.Lock = lock; + InterlockedExchangePointer( (void **)&tail->Next, &queue->LockQueue ); + + while (!((ULONG_PTR)InterlockedCompareExchangePointer( (void **)&queue->LockQueue.Lock, 0, 0 ) + & QUEUED_SPINLOCK_OWNED)) + { + small_pause(); + } + } +} + +/*********************************************************************** + * KeReleaseInStackQueuedSpinLockFromDpcLevel (NTOSKRNL.EXE.@) + */ +#ifdef DEFINE_FASTCALL1_ENTRYPOINT +DEFINE_FASTCALL1_ENTRYPOINT( KeReleaseInStackQueuedSpinLockFromDpcLevel ) +void WINAPI DECLSPEC_HIDDEN __regs_KeReleaseInStackQueuedSpinLockFromDpcLevel( KLOCK_QUEUE_HANDLE *queue ) +#else +void WINAPI KeReleaseInStackQueuedSpinLockFromDpcLevel( KLOCK_QUEUE_HANDLE *queue ) +#endif +{ + KSPIN_LOCK *lock = (KSPIN_LOCK *)((ULONG_PTR)queue->LockQueue.Lock & ~QUEUED_SPINLOCK_OWNED); + KSPIN_LOCK_QUEUE *next; + + TRACE("lock %p, queue %p.\n", lock, queue); + + queue->LockQueue.Lock = NULL; + + if (!(next = queue->LockQueue.Next)) + { + /* If we are truly the last in the queue, the lock will point to us. */ + if (InterlockedCompareExchangePointer( (void **)lock, NULL, &queue->LockQueue ) == queue) + return; + + /* Otherwise, someone just queued themselves, but hasn't yet set + * themselves as successor. Spin waiting for them to do so. */ + while (!(next = queue->LockQueue.Next)) + small_pause(); + } + + InterlockedExchangePointer( (void **)&next->Lock, (KSPIN_LOCK *)((ULONG_PTR)lock | QUEUED_SPINLOCK_OWNED) ); +} + #ifndef __i386__ /*********************************************************************** * KeReleaseSpinLock (NTOSKRNL.EXE.@)
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntoskrnl.exe/ntoskrnl.c | 27 --------------------------- dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 4 ++-- dlls/ntoskrnl.exe/sync.c | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 29 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 5c2055ad25..20bd401489 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -3769,33 +3769,6 @@ NTSTATUS WINAPI IoCreateFile(HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUT return STATUS_NOT_IMPLEMENTED; }
-/*********************************************************************** - * KeAcquireInStackQueuedSpinLock (NTOSKRNL.EXE.@) - */ -#ifdef DEFINE_FASTCALL2_ENTRYPOINT -DEFINE_FASTCALL2_ENTRYPOINT( KeAcquireInStackQueuedSpinLock ) -void WINAPI DECLSPEC_HIDDEN __regs_KeAcquireInStackQueuedSpinLock( KSPIN_LOCK *spinlock, - KLOCK_QUEUE_HANDLE *handle ) -#else -void WINAPI KeAcquireInStackQueuedSpinLock( KSPIN_LOCK *spinlock, KLOCK_QUEUE_HANDLE *handle ) -#endif -{ - FIXME( "stub: %p %p\n", spinlock, handle ); -} - -/*********************************************************************** - * KeReleaseInStackQueuedSpinLock (NTOSKRNL.EXE.@) - */ -#ifdef DEFINE_FASTCALL1_ENTRYPOINT -DEFINE_FASTCALL1_ENTRYPOINT( KeReleaseInStackQueuedSpinLock ) -void WINAPI DECLSPEC_HIDDEN __regs_KeReleaseInStackQueuedSpinLock( KLOCK_QUEUE_HANDLE *handle ) -#else -void WINAPI KeReleaseInStackQueuedSpinLock( KLOCK_QUEUE_HANDLE *handle ) -#endif -{ - FIXME( "stub: %p\n", handle ); -} - /*********************************************************************** * IoCreateNotificationEvent (NTOSKRNL.EXE.@) */ diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index 3ee0e1f808..4b99755ae1 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -41,9 +41,9 @@ @ stub IoWritePartitionTable @ stdcall -norelay IofCallDriver(ptr ptr) @ stdcall -norelay IofCompleteRequest(ptr long) -@ stdcall -norelay KeAcquireInStackQueuedSpinLock(ptr ptr) +@ stdcall -arch=arm,arm64,x86_64 KeAcquireInStackQueuedSpinLock(ptr ptr) @ stdcall -norelay KeAcquireInStackQueuedSpinLockAtDpcLevel(ptr ptr) -@ stdcall -norelay KeReleaseInStackQueuedSpinLock(ptr) +@ stdcall -arch=arm,arm64,x86_64 KeReleaseInStackQueuedSpinLock(ptr) @ stdcall -norelay KeReleaseInStackQueuedSpinLockFromDpcLevel(ptr) @ stub KeSetTimeUpdateNotifyRoutine @ stub KefAcquireSpinLockAtDpcLevel diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c index 4dc1fc3511..46ffc581f0 100644 --- a/dlls/ntoskrnl.exe/sync.c +++ b/dlls/ntoskrnl.exe/sync.c @@ -498,6 +498,24 @@ KIRQL WINAPI KeAcquireSpinLockRaiseToDpc( KSPIN_LOCK *lock ) KeAcquireSpinLockAtDpcLevel( lock ); return 0; } + +/*********************************************************************** + * KeAcquireInStackQueuedSpinLock (NTOSKRNL.EXE.@) + */ +void WINAPI KeAcquireInStackQueuedSpinLock( KSPIN_LOCK *lock, KLOCK_QUEUE_HANDLE *queue ) +{ + TRACE("lock %p, queue %p.\n", lock, queue); + KeAcquireInStackQueuedSpinLockAtDpcLevel( lock, queue ); +} + +/*********************************************************************** + * KeReleaseInStackQueuedSpinLock (NTOSKRNL.EXE.@) + */ +void WINAPI KeReleaseInStackQueuedSpinLock( KLOCK_QUEUE_HANDLE *queue ) +{ + TRACE("queue %p.\n", queue); + KeReleaseInStackQueuedSpinLockFromDpcLevel( queue ); +} #endif
static KSPIN_LOCK cancel_lock;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/hal/hal.c | 31 +++++++++++++++++++++++++++++++ dlls/hal/hal.spec | 4 ++-- 2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/dlls/hal/hal.c b/dlls/hal/hal.c index 5b3ee44cff..6dd517d0df 100644 --- a/dlls/hal/hal.c +++ b/dlls/hal/hal.c @@ -49,6 +49,21 @@ WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl); "pushl %eax\n\t" \ "jmp " __ASM_NAME("__regs_") #name __ASM_STDCALL(8))
+extern void * WINAPI call_fastcall_func1( void *func, const void *a ); +__ASM_GLOBAL_FUNC( call_fastcall_func1, + "popl %ecx\n\t" + "popl %eax\n\t" + "xchgl (%esp),%ecx\n\t" + "jmp *%eax" ); + +extern void * WINAPI call_fastcall_func2( void *func, const void *a, const void *b ); +__ASM_GLOBAL_FUNC( call_fastcall_func2, + "popl %edx\n\t" + "popl %eax\n\t" + "popl %ecx\n\t" + "xchgl (%esp),%edx\n\t" + "jmp *%eax" ); + DEFINE_FASTCALL1_ENTRYPOINT( ExAcquireFastMutex ) VOID WINAPI DECLSPEC_HIDDEN __regs_ExAcquireFastMutex(PFAST_MUTEX FastMutex) { @@ -94,6 +109,22 @@ void WINAPI KeReleaseSpinLock( KSPIN_LOCK *lock, KIRQL irql ) TRACE("lock %p, irql %u.\n", lock, irql); KeReleaseSpinLockFromDpcLevel( lock ); } + +extern void WINAPI KeAcquireInStackQueuedSpinLockAtDpcLevel( KSPIN_LOCK *, KLOCK_QUEUE_HANDLE * ); + +DEFINE_FASTCALL2_ENTRYPOINT( KeAcquireInStackQueuedSpinLock ) +void WINAPI DECLSPEC_HIDDEN __regs_KeAcquireInStackQueuedSpinLock( KSPIN_LOCK *lock, KLOCK_QUEUE_HANDLE *queue ) +{ + call_fastcall_func2( KeAcquireInStackQueuedSpinLockAtDpcLevel, lock, queue ); +} + +extern void WINAPI KeReleaseInStackQueuedSpinLockFromDpcLevel( KLOCK_QUEUE_HANDLE * ); + +DEFINE_FASTCALL1_ENTRYPOINT( KeReleaseInStackQueuedSpinLock ) +void WINAPI DECLSPEC_HIDDEN __regs_KeReleaseInStackQueuedSpinLock( KLOCK_QUEUE_HANDLE *queue ) +{ + call_fastcall_func1( KeReleaseInStackQueuedSpinLockFromDpcLevel, queue ); +} #endif /* __i386__ */
#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) diff --git a/dlls/hal/hal.spec b/dlls/hal/hal.spec index b4ec5126e5..16822fcc9f 100644 --- a/dlls/hal/hal.spec +++ b/dlls/hal/hal.spec @@ -4,12 +4,12 @@ @ stub HalClearSoftwareInterrupt @ stub HalRequestSoftwareInterrupt @ stub HalSystemVectorDispatchEntry -@ stdcall -norelay KeAcquireInStackQueuedSpinLock(ptr ptr) ntoskrnl.exe.KeAcquireInStackQueuedSpinLock +@ stdcall -arch=i386 -norelay KeAcquireInStackQueuedSpinLock(ptr ptr) @ stub KeAcquireInStackQueuedSpinLockRaiseToSynch @ stub KeAcquireQueuedSpinLock @ stub KeAcquireQueuedSpinLockRaiseToSynch @ stub KeAcquireSpinLockRaiseToSynch -@ stdcall -norelay KeReleaseInStackQueuedSpinLock(ptr) ntoskrnl.exe.KeReleaseInStackQueuedSpinLock +@ stdcall -arch=i386 -norelay KeReleaseInStackQueuedSpinLock(ptr) @ stub KeReleaseQueuedSpinLock @ stub KeTryToAcquireQueuedSpinLock @ stub KeTryToAcquireQueuedSpinLockRaiseToSynch