2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ke/sem.c
5 * PURPOSE: Implements kernel semaphores
6 * PROGRAMMER: David Welch (welch@mcmail.com)
11 /* INCLUDES *****************************************************************/
13 #include <ddk/ntddk.h>
14 #include <internal/ke.h>
17 #include <internal/debug.h>
19 /* FUNCTIONS *****************************************************************/
21 VOID
KeInitializeSemaphore(PKSEMAPHORE Semaphore
,
25 KeInitializeDispatcherHeader(&Semaphore
->Header
,
26 InternalSemaphoreType
,
27 sizeof(KSEMAPHORE
)/sizeof(ULONG
),
29 Semaphore
->Limit
=Limit
;
32 LONG
KeReadStateSemaphore(PKSEMAPHORE Semaphore
)
34 return(Semaphore
->Header
.SignalState
);
37 LONG
KeReleaseSemaphore(PKSEMAPHORE Semaphore
,
42 * FUNCTION: KeReleaseSemaphore releases a given semaphore object. This
43 * routine supplies a runtime priority boost for waiting threads. If this
44 * call sets the semaphore to the Signaled state, the semaphore count is
45 * augmented by the given value. The caller can also specify whether it
46 * will call one of the KeWaitXXX routines as soon as KeReleaseSemaphore
49 * Semaphore = Points to an initialized semaphore object for which the
50 * caller provides the storage.
51 * Increment = Specifies the priority increment to be applied if
52 * releasing the semaphore causes a wait to be
54 * Adjustment = Specifies a value to be added to the current semaphore
55 * count. This value must be positive
56 * Wait = Specifies whether the call to KeReleaseSemaphore is to be
57 * followed immediately by a call to one of the KeWaitXXX.
58 * RETURNS: If the return value is zero, the previous state of the semaphore
59 * object is Not-Signaled.
62 ULONG initState
= Semaphore
->Header
.SignalState
;
64 DPRINT("KeReleaseSemaphore(Semaphore %x, Increment %d, Adjustment %d, "
65 "Wait %d)\n", Semaphore
, Increment
, Adjustment
, Wait
);
67 KeAcquireDispatcherDatabaseLock(Wait
);
69 if (Semaphore
->Limit
< initState
+Adjustment
70 || initState
> initState
+Adjustment
)
72 ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED
);
75 Semaphore
->Header
.SignalState
+=Adjustment
;
76 DPRINT("initState %d\n", initState
);
79 // wake up SignalState waiters
80 DPRINT("Waking waiters\n");
81 KeDispatcherObjectWake(&Semaphore
->Header
);
84 KeReleaseDispatcherDatabaseLock(Wait
);