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.@)
|
* KeQueryTimeIncrement (NTOSKRNL.EXE.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -81,6 +81,13 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[],
|
||||||
case TYPE_AUTO_EVENT:
|
case TYPE_AUTO_EVENT:
|
||||||
objs[i]->WaitListHead.Blink = CreateEventW( NULL, FALSE, objs[i]->SignalState, NULL );
|
objs[i]->WaitListHead.Blink = CreateEventW( NULL, FALSE, objs[i]->SignalState, NULL );
|
||||||
break;
|
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:
|
case TYPE_AUTO_EVENT:
|
||||||
objs[i]->SignalState = FALSE;
|
objs[i]->SignalState = FALSE;
|
||||||
break;
|
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->Header.WaitListHead.Flink = NULL;
|
||||||
semaphore->Limit = limit;
|
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)
|
static void test_sync(void)
|
||||||
{
|
{
|
||||||
|
KSEMAPHORE semaphore, semaphore2;
|
||||||
KEVENT manual_event, auto_event;
|
KEVENT manual_event, auto_event;
|
||||||
void *objs[2];
|
void *objs[2];
|
||||||
NTSTATUS ret;
|
NTSTATUS ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
KeInitializeEvent(&manual_event, NotificationEvent, FALSE);
|
KeInitializeEvent(&manual_event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
@ -323,6 +325,68 @@ static void test_sync(void)
|
||||||
|
|
||||||
ret = wait_multiple(2, objs, WaitAny, 0);
|
ret = wait_multiple(2, objs, WaitAny, 0);
|
||||||
ok(ret == 1, "got %#x\n", ret);
|
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)
|
static NTSTATUS main_test(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
|
||||||
|
|
Loading…
Reference in New Issue