ReactOS 0.4.16-dev-122-g325d74c
control.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NDIS library
4 * FILE: ndis/control.c
5 * PURPOSE: Program control routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Vizzini (vizzini@plasmic.com)
8 * REVISIONS:
9 * CSH 01/08-2000 Created
10 * 3 Oct 2003 Vizzini - Formatting and minor bugfixes
11 */
12
13#include "ndissys.h"
14
15/*
16 * @implemented
17 */
18VOID
22/*
23 * FUNCTION: Initialize a NDIS_RW_LOCK
24 * ARGUMENTS:
25 * Lock: pointer to the lock to initialize
26 * NOTES:
27 * NDIS 5.0
28 */
29{
31
32 KeInitializeSpinLock(&Lock->SpinLock);
33}
34
35/*
36 * @implemented
37 */
38VOID
44/*
45 * FUNCTION:
46 * ARGUMENTS:
47 * NOTES:
48 * NDIS 5.0
49 */
50{
51 ULONG RefCount;
52 UCHAR ProcessorNumber;
53 volatile UCHAR BusyLoop;
54
56
57 if (fWrite) {
58 if (Lock->Context == PsGetCurrentThread()) {
59 LockState->LockState = 2;
60 } else {
61 KeAcquireSpinLock(&Lock->SpinLock, &LockState->OldIrql);
62 /* Check if any other processor helds a shared lock. */
63 for (ProcessorNumber = KeNumberProcessors; ProcessorNumber--; ) {
64 if (ProcessorNumber != KeGetCurrentProcessorNumber()) {
65 /* Wait till the shared lock is released. */
66 while (Lock->RefCount[ProcessorNumber].RefCount != 0) {
67 for (BusyLoop = 32; BusyLoop--; )
68 ;
69 }
70 }
71 }
72 Lock->Context = PsGetCurrentThread();
73 LockState->LockState = 4;
74 }
75 } else {
77 RefCount = InterlockedIncrement((PLONG)&Lock->RefCount[KeGetCurrentProcessorNumber()].RefCount);
78 /* Racing with a exclusive write lock case. */
79 if (Lock->SpinLock != 0) {
80 if (RefCount == 1) {
81 if (Lock->Context != PsGetCurrentThread()) {
82 /* Wait for the exclusive lock to be released. */
83 Lock->RefCount[KeGetCurrentProcessorNumber()].RefCount--;
85 Lock->RefCount[KeGetCurrentProcessorNumber()].RefCount++;
87 }
88 }
89 }
90 Lock->Context = PsGetCurrentThread();
91 LockState->LockState = 3;
92 }
93}
94
95/*
96 * @implemented
97 */
98VOID
103/*
104 * FUNCTION:
105 * ARGUMENTS:
106 * NOTES:
107 * NDIS 5.0
108 */
109{
110 switch (LockState->LockState) {
111 case 2: /* Exclusive write lock, recursive */
112 return;
113
114 case 3: /* Shared read lock */
116 LockState->LockState = -1;
117 if (LockState->OldIrql < DISPATCH_LEVEL)
118 KeLowerIrql(LockState->OldIrql);
119 return;
120
121 case 4: /* Exclusive write lock */
122 Lock->Context = NULL;
123 LockState->LockState = -1;
124 KeReleaseSpinLock(&Lock->SpinLock, LockState->OldIrql);
125 return;
126 }
127}
128
129/*
130 * @implemented
131 */
132#undef NdisAcquireSpinLock
133VOID
134EXPORT
137/*
138 * FUNCTION: Acquires a spin lock for exclusive access to a resource
139 * ARGUMENTS:
140 * SpinLock = Pointer to the initialized NDIS spin lock to be acquired
141 */
142{
143 KeAcquireSpinLock(&SpinLock->SpinLock, &SpinLock->OldIrql);
144}
145
146/*
147 * @implemented
148 */
149#undef NdisAllocateSpinLock
150VOID
151EXPORT
154/*
155 * FUNCTION: Initializes for an NDIS spin lock
156 * ARGUMENTS:
157 * SpinLock = Pointer to an NDIS spin lock structure
158 */
159{
160 KeInitializeSpinLock(&SpinLock->SpinLock);
161}
162
163/*
164 * @implemented
165 */
166#undef NdisDprAcquireSpinLock
167VOID
168EXPORT
171/*
172 * FUNCTION: Acquires a spin lock from IRQL DISPATCH_LEVEL
173 * ARGUMENTS:
174 * SpinLock = Pointer to the initialized NDIS spin lock to be acquired
175 */
176{
178 SpinLock->OldIrql = DISPATCH_LEVEL;
179}
180
181/*
182 * @implemented
183 */
184#undef NdisDprReleaseSpinLock
185VOID
186EXPORT
189/*
190 * FUNCTION: Releases an acquired spin lock from IRQL DISPATCH_LEVEL
191 * ARGUMENTS:
192 * SpinLock = Pointer to the acquired NDIS spin lock to be released
193 */
194{
196}
197
198/*
199 * @implemented
200 */
201#undef NdisFreeSpinLock
202VOID
203EXPORT
206/*
207 * FUNCTION: Releases a spin lock initialized with NdisAllocateSpinLock
208 * ARGUMENTS:
209 * SpinLock = Pointer to an initialized NDIS spin lock
210 */
211{
212 /* Nothing to do here! */
213}
214
215
216/*
217 * @implemented
218 */
219VOID
220EXPORT
223/*
224 * FUNCTION: Initializes an event to be used for synchronization
225 * ARGUMENTS:
226 * Event = Pointer to an NDIS event structure to be initialized
227 */
228{
230}
231
232
233/*
234 * @implemented
235 */
236#undef NdisReleaseSpinLock
237VOID
238EXPORT
241/*
242 * FUNCTION: Releases a spin lock previously acquired with NdisAcquireSpinLock
243 * ARGUMENTS:
244 * SpinLock = Pointer to the acquired NDIS spin lock to be released
245 */
246{
247 KeReleaseSpinLock(&SpinLock->SpinLock, SpinLock->OldIrql);
248}
249
250
251/*
252 * @implemented
253 */
254VOID
255EXPORT
258/*
259 * FUNCTION: Clears the signaled state of an event
260 * ARGUMENTS:
261 * Event = Pointer to the initialized event object to be reset
262 */
263{
264 KeClearEvent(&Event->Event);
265}
266
267
268/*
269 * @implemented
270 */
271VOID
272EXPORT
275/*
276 * FUNCTION: Sets an event to a signaled state if not already signaled
277 * ARGUMENTS:
278 * Event = Pointer to the initialized event object to be set
279 */
280{
282}
283
284
285/*
286 * @implemented
287 */
289EXPORT
293/*
294 * FUNCTION: Waits for an event to become signaled
295 * ARGUMENTS:
296 * Event = Pointer to the initialized event object to wait for
297 * MsToWait = Maximum milliseconds to wait for the event to become signaled
298 * RETURNS:
299 * TRUE if the event is in the signaled state
300 */
301{
304
305 Timeout.QuadPart = Int32x32To64(MsToWait, -10000);
306
308
309 return (Status == STATUS_SUCCESS);
310}
311
312/* EOF */
unsigned char BOOLEAN
#define InterlockedIncrement
Definition: armddk.h:53
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ASSERT_IRQL(x)
Definition: debug.h:42
BOOLEAN EXPORT NdisWaitEvent(IN PNDIS_EVENT Event, IN UINT MsToWait)
Definition: control.c:290
VOID EXPORT NdisAcquireReadWriteLock(IN PNDIS_RW_LOCK Lock, IN BOOLEAN fWrite, IN PLOCK_STATE LockState)
Definition: control.c:40
VOID EXPORT NdisResetEvent(IN PNDIS_EVENT Event)
Definition: control.c:256
VOID EXPORT NdisSetEvent(IN PNDIS_EVENT Event)
Definition: control.c:273
VOID EXPORT NdisInitializeEvent(IN PNDIS_EVENT Event)
Definition: control.c:221
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment NdisInitializeReadWriteLock
Definition: CrNtStubs.h:77
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock IN PNDIS_RW_LOCK IN PLOCK_STATE LockState
Definition: CrNtStubs.h:104
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock NdisReleaseReadWriteLock
Definition: CrNtStubs.h:101
Status
Definition: gdiplustypes.h:25
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
#define NdisReleaseSpinLock(_SpinLock)
Definition: ndis.h:4115
unsigned int UINT
Definition: ndis.h:50
#define NdisDprReleaseSpinLock(_SpinLock)
Definition: ndis.h:4133
#define NdisAllocateSpinLock(_SpinLock)
Definition: ndis.h:4088
_In_ UINT MsToWait
Definition: ndis.h:5881
#define NdisDprAcquireSpinLock(_SpinLock)
Definition: ndis.h:4124
_Acquires_exclusive_lock_ Lock _In_ BOOLEAN fWrite
Definition: ndis.h:4586
#define NdisFreeSpinLock(_SpinLock)
Definition: ndis.h:4097
#define NdisAcquireSpinLock(_SpinLock)
Definition: ndis.h:4106
#define KernelMode
Definition: asm.h:34
#define Int32x32To64(a, b)
@ NotificationEvent
static ULONG Timeout
Definition: ping.c:61
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:341
#define KeAcquireSpinLockAtDpcLevel(SpinLock)
Definition: ke.h:125
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
Definition: ke.h:135
#define STATUS_SUCCESS
Definition: shellext.h:65
NDIS_RW_LOCK_REFCOUNT RefCount[MAXIMUM_PROCESSORS]
Definition: rwlock.h:22
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
unsigned int RefCount
Definition: rwlock.h:9
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFSPINLOCK * SpinLock
Definition: wdfsync.h:228
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
#define IO_NO_INCREMENT
Definition: iotypes.h:598
@ Executive
Definition: ketypes.h:415
unsigned char UCHAR
Definition: xmlstorage.h:181