Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencontrol.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS NDIS library 00004 * FILE: ndis/control.c 00005 * PURPOSE: Program control routines 00006 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) 00007 * Vizzini (vizzini@plasmic.com) 00008 * REVISIONS: 00009 * CSH 01/08-2000 Created 00010 * 3 Oct 2003 Vizzini - Formatting and minor bugfixes 00011 */ 00012 00013 #include "ndissys.h" 00014 00015 00016 /* 00017 * @implemented 00018 */ 00019 VOID 00020 EXPORT 00021 NdisInitializeReadWriteLock( 00022 IN PNDIS_RW_LOCK Lock) 00023 /* 00024 * FUNCTION: Initialize a NDIS_RW_LOCK 00025 * ARGUMENTS: 00026 * Lock: pointer to the lock to initialize 00027 * NOTES: 00028 * NDIS 5.0 00029 */ 00030 { 00031 RtlZeroMemory(Lock, sizeof(NDIS_RW_LOCK)); 00032 00033 KeInitializeSpinLock(&Lock->SpinLock); 00034 } 00035 00036 00037 /* 00038 * @implemented 00039 */ 00040 VOID 00041 EXPORT 00042 NdisAcquireReadWriteLock( 00043 IN PNDIS_RW_LOCK Lock, 00044 IN BOOLEAN fWrite, 00045 IN PLOCK_STATE LockState) 00046 /* 00047 * FUNCTION: 00048 * ARGUMENTS: 00049 * NOTES: 00050 * NDIS 5.0 00051 */ 00052 { 00053 ULONG RefCount; 00054 UCHAR ProcessorNumber; 00055 volatile UCHAR BusyLoop; 00056 00057 ASSERT_IRQL(DISPATCH_LEVEL); 00058 00059 if (fWrite) { 00060 if (Lock->Context == PsGetCurrentThread()) { 00061 LockState->LockState = 2; 00062 } else { 00063 KeAcquireSpinLock(&Lock->SpinLock, &LockState->OldIrql); 00064 /* Check if any other processor helds a shared lock. */ 00065 for (ProcessorNumber = KeNumberProcessors; ProcessorNumber--; ) { 00066 if (ProcessorNumber != KeGetCurrentProcessorNumber()) { 00067 /* Wait till the shared lock is released. */ 00068 while (Lock->RefCount[ProcessorNumber].RefCount != 0) { 00069 for (BusyLoop = 32; BusyLoop--; ) 00070 ; 00071 } 00072 } 00073 } 00074 Lock->Context = PsGetCurrentThread(); 00075 LockState->LockState = 4; 00076 } 00077 } else { 00078 KeRaiseIrql(DISPATCH_LEVEL, &LockState->OldIrql); 00079 RefCount = InterlockedIncrement((PLONG)&Lock->RefCount[KeGetCurrentProcessorNumber()].RefCount); 00080 /* Racing with a exclusive write lock case. */ 00081 if (Lock->SpinLock != 0) { 00082 if (RefCount == 1) { 00083 if (Lock->Context != PsGetCurrentThread()) { 00084 /* Wait for the exclusive lock to be released. */ 00085 Lock->RefCount[KeGetCurrentProcessorNumber()].RefCount--; 00086 KeAcquireSpinLockAtDpcLevel(&Lock->SpinLock); 00087 Lock->RefCount[KeGetCurrentProcessorNumber()].RefCount++; 00088 KeReleaseSpinLockFromDpcLevel(&Lock->SpinLock); 00089 } 00090 } 00091 } 00092 Lock->Context = PsGetCurrentThread(); 00093 LockState->LockState = 3; 00094 } 00095 } 00096 00097 00098 /* 00099 * @implemented 00100 */ 00101 VOID 00102 EXPORT 00103 NdisReleaseReadWriteLock( 00104 IN PNDIS_RW_LOCK Lock, 00105 IN PLOCK_STATE LockState) 00106 /* 00107 * FUNCTION: 00108 * ARGUMENTS: 00109 * NOTES: 00110 * NDIS 5.0 00111 */ 00112 { 00113 switch (LockState->LockState) { 00114 case 2: /* Exclusive write lock, recursive */ 00115 return; 00116 00117 case 3: /* Shared read lock */ 00118 Lock->RefCount[KeGetCurrentProcessorNumber()].RefCount--; 00119 LockState->LockState = -1; 00120 if (LockState->OldIrql < DISPATCH_LEVEL) 00121 KeLowerIrql(LockState->OldIrql); 00122 return; 00123 00124 case 4: /* Exclusive write lock */ 00125 Lock->Context = NULL; 00126 LockState->LockState = -1; 00127 KeReleaseSpinLock(&Lock->SpinLock, LockState->OldIrql); 00128 return; 00129 } 00130 } 00131 00132 00133 /* 00134 * @implemented 00135 */ 00136 #undef NdisAcquireSpinLock 00137 VOID 00138 EXPORT 00139 NdisAcquireSpinLock( 00140 IN PNDIS_SPIN_LOCK SpinLock) 00141 /* 00142 * FUNCTION: Acquires a spin lock for exclusive access to a resource 00143 * ARGUMENTS: 00144 * SpinLock = Pointer to the initialized NDIS spin lock to be acquired 00145 */ 00146 { 00147 KeAcquireSpinLock(&SpinLock->SpinLock, &SpinLock->OldIrql); 00148 } 00149 00150 00151 /* 00152 * @implemented 00153 */ 00154 #undef NdisAllocateSpinLock 00155 VOID 00156 EXPORT 00157 NdisAllocateSpinLock( 00158 IN PNDIS_SPIN_LOCK SpinLock) 00159 /* 00160 * FUNCTION: Initializes for an NDIS spin lock 00161 * ARGUMENTS: 00162 * SpinLock = Pointer to an NDIS spin lock structure 00163 */ 00164 { 00165 KeInitializeSpinLock(&SpinLock->SpinLock); 00166 } 00167 00168 00169 /* 00170 * @implemented 00171 */ 00172 #undef NdisDprAcquireSpinLock 00173 VOID 00174 EXPORT 00175 NdisDprAcquireSpinLock( 00176 IN PNDIS_SPIN_LOCK SpinLock) 00177 /* 00178 * FUNCTION: Acquires a spin lock from IRQL DISPATCH_LEVEL 00179 * ARGUMENTS: 00180 * SpinLock = Pointer to the initialized NDIS spin lock to be acquired 00181 */ 00182 { 00183 KeAcquireSpinLockAtDpcLevel(&SpinLock->SpinLock); 00184 SpinLock->OldIrql = DISPATCH_LEVEL; 00185 } 00186 00187 00188 /* 00189 * @implemented 00190 */ 00191 #undef NdisDprReleaseSpinLock 00192 VOID 00193 EXPORT 00194 NdisDprReleaseSpinLock( 00195 IN PNDIS_SPIN_LOCK SpinLock) 00196 /* 00197 * FUNCTION: Releases an acquired spin lock from IRQL DISPATCH_LEVEL 00198 * ARGUMENTS: 00199 * SpinLock = Pointer to the acquired NDIS spin lock to be released 00200 */ 00201 { 00202 KeReleaseSpinLockFromDpcLevel(&SpinLock->SpinLock); 00203 } 00204 00205 00206 /* 00207 * @implemented 00208 */ 00209 #undef NdisFreeSpinLock 00210 VOID 00211 EXPORT 00212 NdisFreeSpinLock( 00213 IN PNDIS_SPIN_LOCK SpinLock) 00214 /* 00215 * FUNCTION: Releases a spin lock initialized with NdisAllocateSpinLock 00216 * ARGUMENTS: 00217 * SpinLock = Pointer to an initialized NDIS spin lock 00218 */ 00219 { 00220 /* Nothing to do here! */ 00221 } 00222 00223 00224 /* 00225 * @implemented 00226 */ 00227 VOID 00228 EXPORT 00229 NdisInitializeEvent( 00230 IN PNDIS_EVENT Event) 00231 /* 00232 * FUNCTION: Initializes an event to be used for synchronization 00233 * ARGUMENTS: 00234 * Event = Pointer to an NDIS event structure to be initialized 00235 */ 00236 { 00237 KeInitializeEvent(&Event->Event, NotificationEvent, FALSE); 00238 } 00239 00240 00241 /* 00242 * @implemented 00243 */ 00244 #undef NdisReleaseSpinLock 00245 VOID 00246 EXPORT 00247 NdisReleaseSpinLock( 00248 IN PNDIS_SPIN_LOCK SpinLock) 00249 /* 00250 * FUNCTION: Releases a spin lock previously acquired with NdisAcquireSpinLock 00251 * ARGUMENTS: 00252 * SpinLock = Pointer to the acquired NDIS spin lock to be released 00253 */ 00254 { 00255 KeReleaseSpinLock(&SpinLock->SpinLock, SpinLock->OldIrql); 00256 } 00257 00258 00259 /* 00260 * @implemented 00261 */ 00262 VOID 00263 EXPORT 00264 NdisResetEvent( 00265 IN PNDIS_EVENT Event) 00266 /* 00267 * FUNCTION: Clears the signaled state of an event 00268 * ARGUMENTS: 00269 * Event = Pointer to the initialized event object to be reset 00270 */ 00271 { 00272 KeResetEvent(&Event->Event); 00273 } 00274 00275 00276 /* 00277 * @implemented 00278 */ 00279 VOID 00280 EXPORT 00281 NdisSetEvent( 00282 IN PNDIS_EVENT Event) 00283 /* 00284 * FUNCTION: Sets an event to a signaled state if not already signaled 00285 * ARGUMENTS: 00286 * Event = Pointer to the initialized event object to be set 00287 */ 00288 { 00289 KeSetEvent(&Event->Event, IO_NO_INCREMENT, FALSE); 00290 } 00291 00292 00293 /* 00294 * @implemented 00295 */ 00296 BOOLEAN 00297 EXPORT 00298 NdisWaitEvent( 00299 IN PNDIS_EVENT Event, 00300 IN UINT MsToWait) 00301 /* 00302 * FUNCTION: Waits for an event to become signaled 00303 * ARGUMENTS: 00304 * Event = Pointer to the initialized event object to wait for 00305 * MsToWait = Maximum milliseconds to wait for the event to become signaled 00306 * RETURNS: 00307 * TRUE if the event is in the signaled state 00308 */ 00309 { 00310 LARGE_INTEGER Timeout; 00311 NTSTATUS Status; 00312 00313 Timeout.QuadPart = Int32x32To64(MsToWait, -10000); 00314 00315 Status = KeWaitForSingleObject(&Event->Event, Executive, KernelMode, TRUE, &Timeout); 00316 00317 return (Status == STATUS_SUCCESS); 00318 } 00319 00320 /* EOF */ 00321 Generated on Mon May 28 2012 04:16:36 for ReactOS by
1.7.6.1
|