Zebediah Figura : ntoskrnl.exe: Implement KeReleaseSemaphore() and waiting on semaphores.

Alexandre Julliard julliard at winehq.org
Tue Nov 27 14:26:10 CST 2018


Module: wine
Branch: master
Commit: 4824d7217b61111da499ea003b01649eeb169710
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=4824d7217b61111da499ea003b01649eeb169710

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Mon Nov 26 19:39:17 2018 -0600

ntoskrnl.exe: Implement KeReleaseSemaphore() and waiting on semaphores.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntoskrnl.exe/ntoskrnl.c     | 11 -------
 dlls/ntoskrnl.exe/sync.c         | 31 +++++++++++++++++++
 dlls/ntoskrnl.exe/tests/driver.c | 64 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 95 insertions(+), 11 deletions(-)

diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 07e9104..d0e77c5 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -2401,17 +2401,6 @@ void WINAPI KeQueryTickCount( LARGE_INTEGER *count )
 
 
 /***********************************************************************
- *           KeReleaseSemaphore   (NTOSKRNL.EXE.@)
- */
-LONG WINAPI KeReleaseSemaphore( PRKSEMAPHORE Semaphore, KPRIORITY Increment,
-                                LONG Adjustment, BOOLEAN Wait )
-{
-    FIXME("(%p %d %d %d) stub\n", Semaphore, Increment, Adjustment, Wait );
-    return 0;
-}
-
-
-/***********************************************************************
  *           KeQueryTimeIncrement   (NTOSKRNL.EXE.@)
  */
 ULONG WINAPI KeQueryTimeIncrement(void)
diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c
index 2190faa..7717846 100644
--- a/dlls/ntoskrnl.exe/sync.c
+++ b/dlls/ntoskrnl.exe/sync.c
@@ -81,6 +81,13 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[],
             case TYPE_AUTO_EVENT:
                 objs[i]->WaitListHead.Blink = CreateEventW( NULL, FALSE, objs[i]->SignalState, NULL );
                 break;
+            case TYPE_SEMAPHORE:
+            {
+                KSEMAPHORE *semaphore = CONTAINING_RECORD(objs[i], KSEMAPHORE, Header);
+                objs[i]->WaitListHead.Blink = CreateSemaphoreW( NULL,
+                    semaphore->Header.SignalState, semaphore->Limit, NULL );
+                break;
+            }
             }
         }
 
@@ -100,6 +107,9 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[],
             case TYPE_AUTO_EVENT:
                 objs[i]->SignalState = FALSE;
                 break;
+            case TYPE_SEMAPHORE:
+                --objs[i]->SignalState;
+                break;
             }
         }
 
@@ -187,3 +197,24 @@ void WINAPI KeInitializeSemaphore( PRKSEMAPHORE semaphore, LONG count, LONG limi
     semaphore->Header.WaitListHead.Flink = NULL;
     semaphore->Limit = limit;
 }
+
+/***********************************************************************
+ *           KeReleaseSemaphore   (NTOSKRNL.EXE.@)
+ */
+LONG WINAPI KeReleaseSemaphore( PRKSEMAPHORE semaphore, KPRIORITY increment,
+                                LONG count, BOOLEAN wait )
+{
+    HANDLE handle = semaphore->Header.WaitListHead.Blink;
+    LONG ret;
+
+    TRACE("semaphore %p, increment %d, count %d, wait %u.\n",
+        semaphore, increment, count, wait);
+
+    EnterCriticalSection( &sync_cs );
+    ret = InterlockedExchangeAdd( &semaphore->Header.SignalState, count );
+    if (handle)
+        ReleaseSemaphore( handle, count, NULL );
+    LeaveCriticalSection( &sync_cs );
+
+    return ret;
+}
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c
index 07a0adb..852a726 100644
--- a/dlls/ntoskrnl.exe/tests/driver.c
+++ b/dlls/ntoskrnl.exe/tests/driver.c
@@ -228,9 +228,11 @@ static NTSTATUS wait_multiple(ULONG count, void *objs[], WAIT_TYPE wait_type, UL
 
 static void test_sync(void)
 {
+    KSEMAPHORE semaphore, semaphore2;
     KEVENT manual_event, auto_event;
     void *objs[2];
     NTSTATUS ret;
+    int i;
 
     KeInitializeEvent(&manual_event, NotificationEvent, FALSE);
 
@@ -323,6 +325,68 @@ static void test_sync(void)
 
     ret = wait_multiple(2, objs, WaitAny, 0);
     ok(ret == 1, "got %#x\n", ret);
+
+    /* test semaphores */
+    KeInitializeSemaphore(&semaphore, 0, 5);
+
+    ret = wait_single(&semaphore, 0);
+    ok(ret == STATUS_TIMEOUT, "got %u\n", ret);
+
+    ret = KeReleaseSemaphore(&semaphore, 0, 1, FALSE);
+    ok(ret == 0, "got prev %d\n", ret);
+
+    ret = KeReleaseSemaphore(&semaphore, 0, 2, FALSE);
+    ok(ret == 1, "got prev %d\n", ret);
+
+    ret = KeReleaseSemaphore(&semaphore, 0, 1, FALSE);
+    ok(ret == 3, "got prev %d\n", ret);
+
+    for (i = 0; i < 4; i++)
+    {
+        ret = wait_single(&semaphore, 0);
+        ok(ret == 0, "got %#x\n", ret);
+    }
+
+    ret = wait_single(&semaphore, 0);
+    ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
+
+    KeInitializeSemaphore(&semaphore2, 3, 5);
+
+    ret = KeReleaseSemaphore(&semaphore2, 0, 1, FALSE);
+    ok(ret == 3, "got prev %d\n", ret);
+
+    for (i = 0; i < 4; i++)
+    {
+        ret = wait_single(&semaphore2, 0);
+        ok(ret == 0, "got %#x\n", ret);
+    }
+
+    objs[0] = &semaphore;
+    objs[1] = &semaphore2;
+
+    ret = wait_multiple(2, objs, WaitAny, 0);
+    ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
+
+    KeReleaseSemaphore(&semaphore, 0, 1, FALSE);
+    KeReleaseSemaphore(&semaphore2, 0, 1, FALSE);
+
+    ret = wait_multiple(2, objs, WaitAny, 0);
+    ok(ret == 0, "got %#x\n", ret);
+
+    ret = wait_multiple(2, objs, WaitAny, 0);
+    ok(ret == 1, "got %#x\n", ret);
+
+    ret = wait_multiple(2, objs, WaitAny, 0);
+    ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
+
+    KeReleaseSemaphore(&semaphore, 0, 1, FALSE);
+    KeReleaseSemaphore(&semaphore2, 0, 1, FALSE);
+
+    ret = wait_multiple(2, objs, WaitAll, 0);
+    ok(ret == 0, "got %#x\n", ret);
+
+    ret = wait_multiple(2, objs, WaitAny, 0);
+    ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
 }
 
 static NTSTATUS main_test(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)




More information about the wine-cvs mailing list