ReactOS Fundraising Campaign 2012
 
€ 4,060 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

interlocked.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.