ReactOS  r75907
semphobj.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/ke/semphobj.c
5  * PURPOSE: Implements the Semaphore Dispatcher Object
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 /* FUNCTIONS *****************************************************************/
16 
17 /*
18  * @implemented
19  */
20 VOID
21 NTAPI
23  IN LONG Count,
24  IN LONG Limit)
25 {
26  /* Simply Initialize the Header */
27  Semaphore->Header.Type = SemaphoreObject;
28  Semaphore->Header.Size = sizeof(KSEMAPHORE) / sizeof(ULONG);
29  Semaphore->Header.SignalState = Count;
30  InitializeListHead(&(Semaphore->Header.WaitListHead));
31 
32  /* Set the Limit */
33  Semaphore->Limit = Limit;
34 }
35 
36 /*
37  * @implemented
38  */
39 LONG
40 NTAPI
42 {
43  ASSERT_SEMAPHORE(Semaphore);
44 
45  /* Just return the Signal State */
46  return Semaphore->Header.SignalState;
47 }
48 
49 /*
50  * @implemented
51  */
52 LONG
53 NTAPI
57  IN BOOLEAN Wait)
58 {
60  KIRQL OldIrql;
61  PKTHREAD CurrentThread;
62  ASSERT_SEMAPHORE(Semaphore);
64 
65  /* Lock the Dispatcher Database */
66  OldIrql = KiAcquireDispatcherLock();
67 
68  /* Save the Old State and get new one */
69  InitialState = Semaphore->Header.SignalState;
70  State = InitialState + Adjustment;
71 
72  /* Check if the Limit was exceeded */
73  if ((Semaphore->Limit < State) || (InitialState > State))
74  {
75  /* Raise an error if it was exceeded */
76  KiReleaseDispatcherLock(OldIrql);
78  }
79 
80  /* Now set the new state */
81  Semaphore->Header.SignalState = State;
82 
83  /* Check if we should wake it */
84  if (!(InitialState) && !(IsListEmpty(&Semaphore->Header.WaitListHead)))
85  {
86  /* Wake the Semaphore */
87  KiWaitTest(&Semaphore->Header, Increment);
88  }
89 
90  /* Check if the caller wants to wait after this release */
91  if (Wait == FALSE)
92  {
93  /* Release the Lock */
94  KiReleaseDispatcherLock(OldIrql);
95  }
96  else
97  {
98  /* Set a wait */
99  CurrentThread = KeGetCurrentThread();
100  CurrentThread->WaitNext = TRUE;
101  CurrentThread->WaitIrql = OldIrql;
102  }
103 
104  /* Return the previous state */
105  return InitialState;
106 }
107 
108 /* EOF */
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:250
#define IN
Definition: typedefs.h:39
#define TRUE
Definition: types.h:120
#define STATUS_SEMAPHORE_LIMIT_EXCEEDED
Definition: ntstatus.h:293
#define ExRaiseStatus
Definition: ntoskrnl.h:94
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
VOID FASTCALL KiWaitTest(PVOID Object, KPRIORITY Increment)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
LONG KPRIORITY
Definition: compat.h:454
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
_In_ KPRIORITY _In_ LONG Adjustment
Definition: kefuncs.h:451
long LONG
Definition: pedump.c:60
#define ASSERT_SEMAPHORE(Object)
ULONG WaitNext
Definition: ketypes.h:952
unsigned char BOOLEAN
VOID NTAPI KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit)
Definition: semphobj.c:22
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ EVENT_TYPE _In_ BOOLEAN InitialState
Definition: exfuncs.h:165
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
struct _KSEMAPHORE KSEMAPHORE
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
enum State_ State
Definition: pofuncs.h:54
FORCEINLINE VOID KiReleaseDispatcherLock(IN KIRQL OldIrql)
Definition: ke_x.h:152
FORCEINLINE KIRQL KiAcquireDispatcherLock(VOID)
Definition: ke_x.h:144
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
LONG NTAPI KeReadStateSemaphore(IN PKSEMAPHORE Semaphore)
Definition: semphobj.c:41
_In_ BOOLEAN Wait
Definition: cctypes.h:23
unsigned int ULONG
Definition: retypes.h:1
#define KeGetCurrentThread
Definition: hal.h:44
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG Increment
Definition: CrNtStubs.h:42
_In_ LONG _In_ LONG Limit
Definition: kefuncs.h:328
KIRQL WaitIrql
Definition: ketypes.h:999