1) Corrected bugs in ERESOURCE code
[reactos.git] / reactos / ntoskrnl / ke / sem.c
1 /*
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)
7 * UPDATE HISTORY:
8 * Created 22/05/98
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include <internal/ke.h>
15
16 #define NDEBUG
17 #include <internal/debug.h>
18
19 /* FUNCTIONS *****************************************************************/
20
21 VOID KeInitializeSemaphore(PKSEMAPHORE Semaphore,
22 LONG Count,
23 LONG Limit)
24 {
25 KeInitializeDispatcherHeader(&Semaphore->Header,
26 InternalSemaphoreType,
27 sizeof(KSEMAPHORE)/sizeof(ULONG),
28 Count);
29 Semaphore->Limit=Limit;
30 }
31
32 LONG KeReadStateSemaphore(PKSEMAPHORE Semaphore)
33 {
34 return(Semaphore->Header.SignalState);
35 }
36
37 LONG KeReleaseSemaphore(PKSEMAPHORE Semaphore,
38 KPRIORITY Increment,
39 LONG Adjustment,
40 BOOLEAN Wait)
41 /*
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
47 * returns control.
48 * ARGUMENTS:
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
53 * satisfied.
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.
60 */
61 {
62 ULONG initState = Semaphore->Header.SignalState;
63
64 DPRINT("KeReleaseSemaphore(Semaphore %x, Increment %d, Adjustment %d, "
65 "Wait %d)\n", Semaphore, Increment, Adjustment, Wait);
66
67 KeAcquireDispatcherDatabaseLock(Wait);
68
69 if (Semaphore->Limit < initState+Adjustment
70 || initState > initState+Adjustment)
71 {
72 ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
73 }
74
75 Semaphore->Header.SignalState+=Adjustment;
76 DPRINT("initState %d\n", initState);
77 if(initState == 0)
78 {
79 // wake up SignalState waiters
80 DPRINT("Waking waiters\n");
81 KeDispatcherObjectWake(&Semaphore->Header);
82 }
83
84 KeReleaseDispatcherDatabaseLock(Wait);
85 return initState;
86 }
87