3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ke/sem.c
6 * PURPOSE: Implements kernel semaphores
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
11 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
17 /* FUNCTIONS *****************************************************************/
23 KeInitializeSemaphore (PKSEMAPHORE Semaphore
,
27 KeInitializeDispatcherHeader(&Semaphore
->Header
,
28 InternalSemaphoreType
,
29 sizeof(KSEMAPHORE
)/sizeof(ULONG
),
31 Semaphore
->Limit
=Limit
;
38 KeReadStateSemaphore (PKSEMAPHORE Semaphore
)
40 return(Semaphore
->Header
.SignalState
);
47 KeReleaseSemaphore (PKSEMAPHORE Semaphore
,
52 * FUNCTION: KeReleaseSemaphore releases a given semaphore object. This
53 * routine supplies a runtime priority boost for waiting threads. If this
54 * call sets the semaphore to the Signaled state, the semaphore count is
55 * augmented by the given value. The caller can also specify whether it
56 * will call one of the KeWaitXXX routines as soon as KeReleaseSemaphore
59 * Semaphore = Points to an initialized semaphore object for which the
60 * caller provides the storage.
61 * Increment = Specifies the priority increment to be applied if
62 * releasing the semaphore causes a wait to be
64 * Adjustment = Specifies a value to be added to the current semaphore
65 * count. This value must be positive
66 * Wait = Specifies whether the call to KeReleaseSemaphore is to be
67 * followed immediately by a call to one of the KeWaitXXX.
68 * RETURNS: If the return value is zero, the previous state of the semaphore
69 * object is Not-Signaled.
75 DPRINT("KeReleaseSemaphore(Semaphore %x, Increment %d, Adjustment %d, "
76 "Wait %d)\n", Semaphore
, Increment
, Adjustment
, Wait
);
78 OldIrql
= KeAcquireDispatcherDatabaseLock();
80 InitialState
= Semaphore
->Header
.SignalState
;
81 if (Semaphore
->Limit
< (LONG
) InitialState
+ Adjustment
||
82 InitialState
> InitialState
+ Adjustment
)
84 ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED
);
87 Semaphore
->Header
.SignalState
+= Adjustment
;
88 if (InitialState
== 0)
90 KiDispatcherObjectWake(&Semaphore
->Header
, SEMAPHORE_INCREMENT
);
95 KeReleaseDispatcherDatabaseLock(OldIrql
);
99 KTHREAD
*Thread
= KeGetCurrentThread();
100 Thread
->WaitNext
= TRUE
;
101 Thread
->WaitIrql
= OldIrql
;
104 return(InitialState
);