Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninterlocked.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: ntoskrnl/ex/interlocked.c 00005 * PURPOSE: Interlocked functions 00006 * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org) 00007 */ 00008 00009 /* INCLUDES *****************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 #undef ExInterlockedAddUlong 00017 #undef ExInterlockedInsertHeadList 00018 #undef ExInterlockedInsertTailList 00019 #undef ExInterlockedRemoveHeadList 00020 #undef ExInterlockedPopEntryList 00021 #undef ExInterlockedPushEntryList 00022 #undef ExInterlockedIncrementLong 00023 #undef ExInterlockedDecrementLong 00024 #undef ExInterlockedExchangeUlong 00025 #undef ExInterlockedCompareExchange64 00026 00027 00028 /* FUNCTIONS ****************************************************************/ 00029 00030 FORCEINLINE 00031 BOOLEAN 00032 _ExiDisableInteruptsAndAcquireSpinlock( 00033 IN OUT PKSPIN_LOCK Lock) 00034 { 00035 BOOLEAN Enabled; 00036 00037 /* Disable interrupts */ 00038 Enabled = KeDisableInterrupts(); 00039 00040 /* Acquire the spinlock (inline) */ 00041 KxAcquireSpinLock(Lock); 00042 00043 return Enabled; 00044 } 00045 00046 FORCEINLINE 00047 VOID 00048 _ExiReleaseSpinLockAndRestoreInterupts( 00049 IN OUT PKSPIN_LOCK Lock, 00050 BOOLEAN Enable) 00051 { 00052 /* Release the spinlock */ 00053 KxReleaseSpinLock(Lock); 00054 00055 /* Restore interrupts */ 00056 KeRestoreInterrupts(Enable); 00057 } 00058 00059 00060 LARGE_INTEGER 00061 NTAPI 00062 ExInterlockedAddLargeInteger( 00063 IN OUT PLARGE_INTEGER Addend, 00064 IN LARGE_INTEGER Increment, 00065 IN OUT PKSPIN_LOCK Lock) 00066 { 00067 LARGE_INTEGER OldValue; 00068 BOOLEAN Enable; 00069 00070 /* Disable interrupts and acquire the spinlock */ 00071 Enable = _ExiDisableInteruptsAndAcquireSpinlock(Lock); 00072 00073 /* Save the old value */ 00074 OldValue.QuadPart = Addend->QuadPart; 00075 00076 /* Do the operation */ 00077 Addend->QuadPart += Increment.QuadPart; 00078 00079 /* Release the spinlock and restore interrupts */ 00080 _ExiReleaseSpinLockAndRestoreInterupts(Lock, Enable); 00081 00082 /* Return the old value */ 00083 return OldValue; 00084 } 00085 00086 ULONG 00087 NTAPI 00088 ExInterlockedAddUlong( 00089 IN OUT PULONG Addend, 00090 IN ULONG Increment, 00091 IN OUT PKSPIN_LOCK Lock) 00092 { 00093 BOOLEAN Enable; 00094 ULONG OldValue; 00095 00096 /* Disable interrupts and acquire the spinlock */ 00097 Enable = _ExiDisableInteruptsAndAcquireSpinlock(Lock); 00098 00099 /* Save the old value */ 00100 OldValue = *Addend; 00101 00102 /* Do the operation */ 00103 *Addend += Increment; 00104 00105 /* Release the spinlock and restore interrupts */ 00106 _ExiReleaseSpinLockAndRestoreInterupts(Lock, Enable); 00107 00108 /* Return the old value */ 00109 return OldValue; 00110 } 00111 00112 PLIST_ENTRY 00113 NTAPI 00114 ExInterlockedInsertHeadList( 00115 IN OUT PLIST_ENTRY ListHead, 00116 IN OUT PLIST_ENTRY ListEntry, 00117 IN OUT PKSPIN_LOCK Lock) 00118 { 00119 BOOLEAN Enable; 00120 PLIST_ENTRY FirstEntry; 00121 00122 /* Disable interrupts and acquire the spinlock */ 00123 Enable = _ExiDisableInteruptsAndAcquireSpinlock(Lock); 00124 00125 /* Save the first entry */ 00126 FirstEntry = ListHead->Flink; 00127 00128 /* Insert the new entry */ 00129 InsertHeadList(ListHead, ListEntry); 00130 00131 /* Release the spinlock and restore interrupts */ 00132 _ExiReleaseSpinLockAndRestoreInterupts(Lock, Enable); 00133 00134 /* Return the old first entry or NULL for empty list */ 00135 return (FirstEntry == ListHead) ? NULL : FirstEntry; 00136 } 00137 00138 PLIST_ENTRY 00139 NTAPI 00140 ExInterlockedInsertTailList( 00141 IN OUT PLIST_ENTRY ListHead, 00142 IN OUT PLIST_ENTRY ListEntry, 00143 IN OUT PKSPIN_LOCK Lock) 00144 { 00145 BOOLEAN Enable; 00146 PLIST_ENTRY LastEntry; 00147 00148 /* Disable interrupts and acquire the spinlock */ 00149 Enable = _ExiDisableInteruptsAndAcquireSpinlock(Lock); 00150 00151 /* Save the last entry */ 00152 LastEntry = ListHead->Blink; 00153 00154 /* Insert the new entry */ 00155 InsertTailList(ListHead, ListEntry); 00156 00157 /* Release the spinlock and restore interrupts */ 00158 _ExiReleaseSpinLockAndRestoreInterupts(Lock, Enable); 00159 00160 /* Return the old last entry or NULL for empty list */ 00161 return (LastEntry == ListHead) ? NULL : LastEntry; 00162 } 00163 00164 PLIST_ENTRY 00165 NTAPI 00166 ExInterlockedRemoveHeadList( 00167 IN OUT PLIST_ENTRY ListHead, 00168 IN OUT PKSPIN_LOCK Lock) 00169 { 00170 BOOLEAN Enable; 00171 PLIST_ENTRY ListEntry; 00172 00173 /* Disable interrupts and acquire the spinlock */ 00174 Enable = _ExiDisableInteruptsAndAcquireSpinlock(Lock); 00175 00176 /* Check if the list is empty */ 00177 if (IsListEmpty(ListHead)) 00178 { 00179 /* Return NULL */ 00180 ListEntry = NULL; 00181 } 00182 else 00183 { 00184 /* Remove the first entry from the list head */ 00185 ListEntry = RemoveHeadList(ListHead); 00186 #if DBG 00187 ListEntry->Flink = (PLIST_ENTRY)0xBADDD0FF; 00188 ListEntry->Blink = (PLIST_ENTRY)0xBADDD0FF; 00189 #endif 00190 } 00191 00192 /* Release the spinlock and restore interrupts */ 00193 _ExiReleaseSpinLockAndRestoreInterupts(Lock, Enable); 00194 00195 /* Return the entry */ 00196 return ListEntry; 00197 } 00198 00199 PSINGLE_LIST_ENTRY 00200 NTAPI 00201 ExInterlockedPopEntryList( 00202 IN OUT PSINGLE_LIST_ENTRY ListHead, 00203 IN OUT PKSPIN_LOCK Lock) 00204 { 00205 BOOLEAN Enable; 00206 PSINGLE_LIST_ENTRY ListEntry; 00207 00208 /* Disable interrupts and acquire the spinlock */ 00209 Enable = _ExiDisableInteruptsAndAcquireSpinlock(Lock); 00210 00211 /* Pop the first entry from the list */ 00212 ListEntry = PopEntryList(ListHead); 00213 #if DBG 00214 if (ListEntry) 00215 ListEntry->Next = (PSINGLE_LIST_ENTRY)0xBADDD0FF; 00216 #endif 00217 00218 /* Release the spinlock and restore interrupts */ 00219 _ExiReleaseSpinLockAndRestoreInterupts(Lock, Enable); 00220 00221 /* Return the entry */ 00222 return ListEntry; 00223 } 00224 00225 PSINGLE_LIST_ENTRY 00226 NTAPI 00227 ExInterlockedPushEntryList( 00228 IN OUT PSINGLE_LIST_ENTRY ListHead, 00229 IN OUT PSINGLE_LIST_ENTRY ListEntry, 00230 IN OUT PKSPIN_LOCK Lock) 00231 { 00232 BOOLEAN Enable; 00233 PSINGLE_LIST_ENTRY OldListEntry; 00234 00235 /* Disable interrupts and acquire the spinlock */ 00236 Enable = _ExiDisableInteruptsAndAcquireSpinlock(Lock); 00237 00238 /* Save the old top entry */ 00239 OldListEntry = ListHead->Next; 00240 00241 /* Push a new entry on the list */ 00242 PushEntryList(ListHead, ListEntry); 00243 00244 /* Release the spinlock and restore interrupts */ 00245 _ExiReleaseSpinLockAndRestoreInterupts(Lock, Enable); 00246 00247 /* Return the entry */ 00248 return OldListEntry; 00249 } 00250 00251 INTERLOCKED_RESULT 00252 NTAPI 00253 ExInterlockedIncrementLong( 00254 IN PLONG Addend, 00255 IN PKSPIN_LOCK Lock) 00256 { 00257 LONG Result; 00258 00259 Result = _InterlockedIncrement(Addend); 00260 return (Result < 0) ? ResultNegative : 00261 (Result > 0) ? ResultPositive : 00262 ResultZero; 00263 } 00264 00265 INTERLOCKED_RESULT 00266 NTAPI 00267 ExInterlockedDecrementLong( 00268 IN PLONG Addend, 00269 IN PKSPIN_LOCK Lock) 00270 { 00271 LONG Result; 00272 00273 Result = _InterlockedDecrement(Addend); 00274 return (Result < 0) ? ResultNegative : 00275 (Result > 0) ? ResultPositive : 00276 ResultZero; 00277 } 00278 00279 ULONG 00280 NTAPI 00281 ExInterlockedExchangeUlong( 00282 IN PULONG Target, 00283 IN ULONG Value, 00284 IN PKSPIN_LOCK Lock) 00285 { 00286 return (ULONG)_InterlockedExchange((PLONG)Target, (LONG)Value); 00287 } 00288 00289 #ifdef _M_IX86 00290 00291 ULONG 00292 FASTCALL 00293 ExfInterlockedAddUlong( 00294 IN OUT PULONG Addend, 00295 IN ULONG Increment, 00296 IN OUT PKSPIN_LOCK Lock) 00297 { 00298 BOOLEAN Enable; 00299 ULONG OldValue; 00300 00301 /* Disable interrupts and acquire the spinlock */ 00302 Enable = _ExiDisableInteruptsAndAcquireSpinlock(Lock); 00303 00304 /* Save the old value */ 00305 OldValue = *Addend; 00306 00307 /* Do the operation */ 00308 *Addend += Increment; 00309 00310 /* Release the spinlock and restore interrupts */ 00311 _ExiReleaseSpinLockAndRestoreInterupts(Lock, Enable); 00312 00313 /* Return the old value */ 00314 return OldValue; 00315 } 00316 00317 PLIST_ENTRY 00318 FASTCALL 00319 ExfInterlockedInsertHeadList( 00320 IN OUT PLIST_ENTRY ListHead, 00321 IN PLIST_ENTRY ListEntry, 00322 IN OUT PKSPIN_LOCK Lock) 00323 { 00324 BOOLEAN Enable; 00325 PLIST_ENTRY FirstEntry; 00326 00327 /* Disable interrupts and acquire the spinlock */ 00328 Enable = _ExiDisableInteruptsAndAcquireSpinlock(Lock); 00329 00330 /* Save the first entry */ 00331 FirstEntry = ListHead->Flink; 00332 00333 /* Insert the new entry */ 00334 InsertHeadList(ListHead, ListEntry); 00335 00336 /* Release the spinlock and restore interrupts */ 00337 _ExiReleaseSpinLockAndRestoreInterupts(Lock, Enable); 00338 00339 /* Return the old first entry or NULL for empty list */ 00340 return (FirstEntry == ListHead) ? NULL : FirstEntry; 00341 } 00342 00343 PLIST_ENTRY 00344 FASTCALL 00345 ExfInterlockedInsertTailList( 00346 IN OUT PLIST_ENTRY ListHead, 00347 IN PLIST_ENTRY ListEntry, 00348 IN OUT PKSPIN_LOCK Lock) 00349 { 00350 BOOLEAN Enable; 00351 PLIST_ENTRY LastEntry; 00352 00353 /* Disable interrupts and acquire the spinlock */ 00354 Enable = _ExiDisableInteruptsAndAcquireSpinlock(Lock); 00355 00356 /* Save the last entry */ 00357 LastEntry = ListHead->Blink; 00358 00359 /* Insert the new entry */ 00360 InsertTailList(ListHead, ListEntry); 00361 00362 /* Release the spinlock and restore interrupts */ 00363 _ExiReleaseSpinLockAndRestoreInterupts(Lock, Enable); 00364 00365 /* Return the old last entry or NULL for empty list */ 00366 return (LastEntry == ListHead) ? NULL : LastEntry; 00367 } 00368 00369 00370 PLIST_ENTRY 00371 FASTCALL 00372 ExfInterlockedRemoveHeadList( 00373 IN OUT PLIST_ENTRY ListHead, 00374 IN OUT PKSPIN_LOCK Lock) 00375 { 00376 BOOLEAN Enable; 00377 PLIST_ENTRY ListEntry; 00378 00379 /* Disable interrupts and acquire the spinlock */ 00380 Enable = _ExiDisableInteruptsAndAcquireSpinlock(Lock); 00381 00382 /* Check if the list is empty */ 00383 if (IsListEmpty(ListHead)) 00384 { 00385 /* Return NULL */ 00386 ListEntry = NULL; 00387 } 00388 else 00389 { 00390 /* Remove the first entry from the list head */ 00391 ListEntry = RemoveHeadList(ListHead); 00392 #if DBG 00393 ListEntry->Flink = (PLIST_ENTRY)0x0BADD0FF; 00394 ListEntry->Blink = (PLIST_ENTRY)0x0BADD0FF; 00395 #endif 00396 } 00397 00398 /* Release the spinlock and restore interrupts */ 00399 _ExiReleaseSpinLockAndRestoreInterupts(Lock, Enable); 00400 00401 /* return the entry */ 00402 return ListEntry; 00403 } 00404 00405 PSINGLE_LIST_ENTRY 00406 FASTCALL 00407 ExfInterlockedPopEntryList( 00408 IN OUT PSINGLE_LIST_ENTRY ListHead, 00409 IN OUT PKSPIN_LOCK Lock) 00410 { 00411 BOOLEAN Enable; 00412 PSINGLE_LIST_ENTRY ListEntry; 00413 00414 /* Disable interrupts and acquire the spinlock */ 00415 Enable = _ExiDisableInteruptsAndAcquireSpinlock(Lock); 00416 00417 /* Pop the first entry from the list */ 00418 ListEntry = PopEntryList(ListHead); 00419 #if DBG 00420 if (ListEntry) 00421 ListEntry->Next = (PSINGLE_LIST_ENTRY)0xBADDD0FF; 00422 #endif 00423 00424 /* Release the spinlock and restore interrupts */ 00425 _ExiReleaseSpinLockAndRestoreInterupts(Lock, Enable); 00426 00427 /* return the entry */ 00428 return ListEntry; 00429 } 00430 00431 PSINGLE_LIST_ENTRY 00432 FASTCALL 00433 ExfInterlockedPushEntryList( 00434 IN OUT PSINGLE_LIST_ENTRY ListHead, 00435 IN PSINGLE_LIST_ENTRY ListEntry, 00436 IN OUT PKSPIN_LOCK Lock) 00437 { 00438 BOOLEAN Enable; 00439 PSINGLE_LIST_ENTRY OldListEntry; 00440 00441 /* Disable interrupts and acquire the spinlock */ 00442 Enable = _ExiDisableInteruptsAndAcquireSpinlock(Lock); 00443 00444 /* Save the old top entry */ 00445 OldListEntry = ListHead->Next; 00446 00447 /* Push a new entry on the list */ 00448 PushEntryList(ListHead, ListEntry); 00449 00450 /* Release the spinlock and restore interrupts */ 00451 _ExiReleaseSpinLockAndRestoreInterupts(Lock, Enable); 00452 00453 /* return the entry */ 00454 return OldListEntry; 00455 } 00456 00457 INTERLOCKED_RESULT 00458 NTAPI 00459 Exi386InterlockedIncrementLong( 00460 IN PLONG Addend) 00461 { 00462 LONG Result; 00463 00464 Result = _InterlockedIncrement(Addend); 00465 return (Result < 0) ? ResultNegative : 00466 (Result > 0) ? ResultPositive : 00467 ResultZero; 00468 } 00469 00470 INTERLOCKED_RESULT 00471 FASTCALL 00472 Exfi386InterlockedIncrementLong( 00473 IN OUT LONG volatile *Addend) 00474 { 00475 LONG Result; 00476 00477 Result = _InterlockedIncrement(Addend); 00478 return (Result < 0) ? ResultNegative : 00479 (Result > 0) ? ResultPositive : 00480 ResultZero; 00481 } 00482 00483 INTERLOCKED_RESULT 00484 NTAPI 00485 Exi386InterlockedDecrementLong( 00486 IN PLONG Addend) 00487 { 00488 LONG Result; 00489 00490 Result = _InterlockedDecrement(Addend); 00491 return (Result < 0) ? ResultNegative : 00492 (Result > 0) ? ResultPositive : 00493 ResultZero; 00494 } 00495 00496 INTERLOCKED_RESULT 00497 FASTCALL 00498 Exfi386InterlockedDecrementLong( 00499 IN OUT PLONG Addend) 00500 { 00501 LONG Result; 00502 00503 Result = _InterlockedDecrement(Addend); 00504 return (Result < 0) ? ResultNegative : 00505 (Result > 0) ? ResultPositive : 00506 ResultZero; 00507 } 00508 00509 LONG 00510 NTAPI 00511 Exi386InterlockedExchangeUlong( 00512 PLONG Target, 00513 LONG Exchange) 00514 { 00515 return _InterlockedExchange(Target, Exchange); 00516 } 00517 00518 ULONG 00519 FASTCALL 00520 Exfi386InterlockedExchangeUlong( 00521 IN OUT PULONG Target, 00522 IN ULONG Exchange) 00523 { 00524 return _InterlockedExchange((PLONG)Target, Exchange); 00525 } 00526 00527 LONGLONG 00528 FASTCALL 00529 ExInterlockedCompareExchange64( 00530 IN OUT LONGLONG volatile *Destination, 00531 IN PLONGLONG Exchange, 00532 IN PLONGLONG Comparand, 00533 IN PKSPIN_LOCK Lock) 00534 { 00535 return _InterlockedCompareExchange64(Destination, *Exchange, *Comparand); 00536 } 00537 00538 LONGLONG 00539 FASTCALL 00540 ExfInterlockedCompareExchange64( 00541 IN OUT LONGLONG volatile *Destination, 00542 IN PLONGLONG Exchange, 00543 IN PLONGLONG Comparand) 00544 { 00545 return _InterlockedCompareExchange64(Destination, *Exchange, *Comparand); 00546 } 00547 #endif 00548 00549 #if 0 00550 00551 VOID 00552 FASTCALL 00553 ExInterlockedAddLargeStatistic( 00554 IN OUT PLARGE_INTEGER Addend, 00555 IN ULONG Increment) 00556 { 00557 } 00558 00559 00560 #endif 00561 Generated on Tue May 22 2012 04:40:37 for ReactOS by
1.7.6.1
|