3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/ke/sem.c
23 * PURPOSE: Implements kernel semaphores
24 * PROGRAMMER: David Welch (welch@mcmail.com)
29 /* INCLUDES *****************************************************************/
31 #include <ddk/ntddk.h>
32 #include <internal/ke.h>
33 #include <internal/id.h>
36 #include <internal/debug.h>
38 /* FUNCTIONS *****************************************************************/
41 KeInitializeSemaphore (PKSEMAPHORE Semaphore,
45 KeInitializeDispatcherHeader(&Semaphore->Header,
46 InternalSemaphoreType,
47 sizeof(KSEMAPHORE)/sizeof(ULONG),
49 Semaphore->Limit=Limit;
53 KeReadStateSemaphore (PKSEMAPHORE Semaphore)
55 return(Semaphore->Header.SignalState);
59 KeReleaseSemaphore (PKSEMAPHORE Semaphore,
64 * FUNCTION: KeReleaseSemaphore releases a given semaphore object. This
65 * routine supplies a runtime priority boost for waiting threads. If this
66 * call sets the semaphore to the Signaled state, the semaphore count is
67 * augmented by the given value. The caller can also specify whether it
68 * will call one of the KeWaitXXX routines as soon as KeReleaseSemaphore
71 * Semaphore = Points to an initialized semaphore object for which the
72 * caller provides the storage.
73 * Increment = Specifies the priority increment to be applied if
74 * releasing the semaphore causes a wait to be
76 * Adjustment = Specifies a value to be added to the current semaphore
77 * count. This value must be positive
78 * Wait = Specifies whether the call to KeReleaseSemaphore is to be
79 * followed immediately by a call to one of the KeWaitXXX.
80 * RETURNS: If the return value is zero, the previous state of the semaphore
81 * object is Not-Signaled.
86 DPRINT("KeReleaseSemaphore(Semaphore %x, Increment %d, Adjustment %d, "
87 "Wait %d)\n", Semaphore, Increment, Adjustment, Wait);
89 KeAcquireDispatcherDatabaseLock(Wait);
91 InitialState = Semaphore->Header.SignalState;
92 if (Semaphore->Limit < InitialState + Adjustment ||
93 InitialState > InitialState + Adjustment)
95 ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
98 Semaphore->Header.SignalState += Adjustment;
99 if (InitialState == 0)
101 KeDispatcherObjectWake(&Semaphore->Header);
104 KeReleaseDispatcherDatabaseLock(Wait);
105 return(InitialState);