ntoskrnl.exe: Implement KeReleaseSemaphore() and waiting on semaphores.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
8589d094ff
commit
4824d7217b
|
@ -2400,17 +2400,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.@)
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue