mirror of
https://github.com/reactos/reactos.git
synced 2024-10-06 01:13:38 +00:00
e1ef078741
The idea then would be to have the following behaviour (when specifying the following options in the kernel command line): /DEBUGPORT=COMi --> load KDCOM.DLL and use COMi port (i == 1,2,3,4) if possible. /DEBUGPORT=FOO --> load KDFOO.DLL (useful for KDUSB.DLL, KD1394.DLL, KDBAZIS.DLL for VirtualKD, etc...) /DEBUGPORT=ROSDBG:[COMi|SCREEN|FILE|GDB|...] --> load KDROSDBG.DLL which contains the ROS kernel debugger, and use COMi or SCREEN or... as output port. svn path=/branches/kd++/; revision=58883
109 lines
2.6 KiB
C
109 lines
2.6 KiB
C
/*
|
|
* PROJECT: ReactOS Kernel
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
* FILE: ntoskrnl/ke/sem.c
|
|
* PURPOSE: Implements the Semaphore Dispatcher Object
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
#include <ntoskrnl.h>
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
VOID
|
|
NTAPI
|
|
KeInitializeSemaphore(IN PKSEMAPHORE Semaphore,
|
|
IN LONG Count,
|
|
IN LONG Limit)
|
|
{
|
|
/* Simply Initialize the Header */
|
|
Semaphore->Header.Type = SemaphoreObject;
|
|
Semaphore->Header.Size = sizeof(KSEMAPHORE) / sizeof(ULONG);
|
|
Semaphore->Header.SignalState = Count;
|
|
InitializeListHead(&(Semaphore->Header.WaitListHead));
|
|
|
|
/* Set the Limit */
|
|
Semaphore->Limit = Limit;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
LONG
|
|
NTAPI
|
|
KeReadStateSemaphore(IN PKSEMAPHORE Semaphore)
|
|
{
|
|
ASSERT_SEMAPHORE(Semaphore);
|
|
|
|
/* Just return the Signal State */
|
|
return Semaphore->Header.SignalState;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
LONG
|
|
NTAPI
|
|
KeReleaseSemaphore(IN PKSEMAPHORE Semaphore,
|
|
IN KPRIORITY Increment,
|
|
IN LONG Adjustment,
|
|
IN BOOLEAN Wait)
|
|
{
|
|
LONG InitialState, State;
|
|
KIRQL OldIrql;
|
|
PKTHREAD CurrentThread;
|
|
ASSERT_SEMAPHORE(Semaphore);
|
|
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
|
|
|
/* Lock the Dispatcher Database */
|
|
OldIrql = KiAcquireDispatcherLock();
|
|
|
|
/* Save the Old State and get new one */
|
|
InitialState = Semaphore->Header.SignalState;
|
|
State = InitialState + Adjustment;
|
|
|
|
/* Check if the Limit was exceeded */
|
|
if ((Semaphore->Limit < State) || (InitialState > State))
|
|
{
|
|
/* Raise an error if it was exceeded */
|
|
KiReleaseDispatcherLock(OldIrql);
|
|
ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
|
|
}
|
|
|
|
/* Now set the new state */
|
|
Semaphore->Header.SignalState = State;
|
|
|
|
/* Check if we should wake it */
|
|
if (!(InitialState) && !(IsListEmpty(&Semaphore->Header.WaitListHead)))
|
|
{
|
|
/* Wake the Semaphore */
|
|
KiWaitTest(&Semaphore->Header, Increment);
|
|
}
|
|
|
|
/* Check if the caller wants to wait after this release */
|
|
if (Wait == FALSE)
|
|
{
|
|
/* Release the Lock */
|
|
KiReleaseDispatcherLock(OldIrql);
|
|
}
|
|
else
|
|
{
|
|
/* Set a wait */
|
|
CurrentThread = KeGetCurrentThread();
|
|
CurrentThread->WaitNext = TRUE;
|
|
CurrentThread->WaitIrql = OldIrql;
|
|
}
|
|
|
|
/* Return the previous state */
|
|
return InitialState;
|
|
}
|
|
|
|
/* EOF */
|