13eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/*++ 23eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 32c7e5c2febd407ed1849c06da50734dd6f751956hhtianCopyright (c) 2004 - 2006, Intel Corporation. All rights reserved.<BR> 42c7e5c2febd407ed1849c06da50734dd6f751956hhtianThis program and the accompanying materials 53eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangare licensed and made available under the terms and conditions of the BSD License 63eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangwhich accompanies this distribution. The full text of the license may be found at 73eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwanghttp://opensource.org/licenses/bsd-license.php 83eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 93eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangModule Name: 143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Synchronization.c 163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAbstract: 183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Implementation of synchronization functions. 203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang--*/ 223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 23c7f33ca42470dc87bc41a8583f427883123d67a1qwang#include "BaseLibInternals.h" 243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 25c7f33ca42470dc87bc41a8583f427883123d67a1qwang#define SPIN_LOCK_RELEASED ((UINTN) 1) 26c7f33ca42470dc87bc41a8583f427883123d67a1qwang#define SPIN_LOCK_ACQUIRED ((UINTN) 2) 273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/** 293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Retrieves the architecture specific spin lock alignment requirements for 303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang optimal spin lock performance. 313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang This function retrieves the spin lock alignment requirements for optimal 333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang performance on a given CPU architecture. The spin lock alignment must be a 343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang power of two and is returned by this function. If there are no alignment 353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang requirements, then 1 must be returned. The spin lock synchronization 363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang functions must function correctly if the spin lock size and alignment values 373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang returned by this function are not used at all. These values are hints to the 383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang consumers of the spin lock synchronization functions to obtain optimal spin 393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang lock performance. 403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @return The architecture specific spin lock alignment. 423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/ 443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangUINTN 453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI 463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangGetSpinLockProperties ( 473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang VOID 483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang // @bug May use a PCD entry to determine this alignment. 513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return 32; 523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/** 553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Initializes a spin lock to the released state and returns the spin lock. 563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang This function initializes the spin lock specified by SpinLock to the released 583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang state, and returns SpinLock. Optimal performance can be achieved by calling 593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang GetSpinLockProperties() to determine the size and alignment requirements for 603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang SpinLock. 613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang If SpinLock is NULL, then ASSERT(). 633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @param SpinLock A pointer to the spin lock to initialize to the released 653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang state. 663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @return SpinLock 683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/ 703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangSPIN_LOCK * 713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI 723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangInitializeSpinLock ( 733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang OUT SPIN_LOCK *SpinLock 743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ASSERT (SpinLock != NULL); 773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang *SpinLock = SPIN_LOCK_RELEASED; 783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return SpinLock; 793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/** 823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Waits until a spin lock can be placed in the acquired state. 833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang This function checks the state of the spin lock specified by SpinLock. If 853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang SpinLock is in the released state, then this function places SpinLock in the 863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang acquired state and returns SpinLock. Otherwise, this function waits 873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang indefinitely for the spin lock to be released, and then places it in the 883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang acquired state and returns SpinLock. All state transitions of SpinLock must 893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang be performed using MP safe mechanisms. 903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang If SpinLock is NULL, then ASSERT(). 923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). 933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang If PcdSpinLockTimeout is not zero, and SpinLock is can not be acquired in 943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang PcdSpinLockTimeout microseconds, then ASSERT(). 953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @param SpinLock A pointer to the spin lock to place in the acquired state. 973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @return SpinLock 993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/ 1013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangSPIN_LOCK * 1023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI 1033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAcquireSpinLock ( 1043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN OUT SPIN_LOCK *SpinLock 1053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 1063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 1073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang UINT64 Tick; 1083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang UINT64 Start, End; 1093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang UINT64 Timeout; 1103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Tick = 0; 1123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Start = 0; 1133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang End = 0; 1143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (PcdGet32 (PcdSpinLockTimeout) > 0) { 1153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Tick = GetPerformanceCounter (); 1163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Timeout = DivU64x32 ( 1173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang MultU64x32 ( 1183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang GetPerformanceCounterProperties (&Start, &End), 1193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang PcdGet32 (PcdSpinLockTimeout) 1203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ), 1213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1000000 1223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ); 1233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang if (Start < End) { 1243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Tick += Timeout; 1253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } else { 1263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Tick -= Timeout; 1273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 1283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 1293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang while (!AcquireSpinLockOrFail (SpinLock)) { 1313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang CpuPause (); 1323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ASSERT ((Start < End) ^ (Tick <= GetPerformanceCounter ())); 1333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 1343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return SpinLock; 1353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 1363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/** 1383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Attempts to place a spin lock in the acquired state. 1393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang This function checks the state of the spin lock specified by SpinLock. If 1413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang SpinLock is in the released state, then this function places SpinLock in the 1423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang acquired state and returns TRUE. Otherwise, FALSE is returned. All state 1433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang transitions of SpinLock must be performed using MP safe mechanisms. 1443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang If SpinLock is NULL, then ASSERT(). 1463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). 1473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @param SpinLock A pointer to the spin lock to place in the acquired state. 1493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @retval TRUE SpinLock was placed in the acquired state. 1513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @retval FALSE SpinLock could not be acquired. 1523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/ 1543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangBOOLEAN 1553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI 1563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAcquireSpinLockOrFail ( 1573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN OUT SPIN_LOCK *SpinLock 1583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 1593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 160c7f33ca42470dc87bc41a8583f427883123d67a1qwang SPIN_LOCK LockValue; 1613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ASSERT (SpinLock != NULL); 1633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang LockValue = *SpinLock; 1653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED); 1663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return (BOOLEAN)( 1683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang InterlockedCompareExchangePointer ( 1693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang (VOID**)SpinLock, 1703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang (VOID*)SPIN_LOCK_RELEASED, 1713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang (VOID*)SPIN_LOCK_ACQUIRED 1723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) == (VOID*)SPIN_LOCK_RELEASED 1733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ); 1743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 1753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/** 1773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Releases a spin lock. 1783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang This function places the spin lock specified by SpinLock in the release state 1803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang and returns SpinLock. 1813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang If SpinLock is NULL, then ASSERT(). 1833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). 1843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @param SpinLock A pointer to the spin lock to release. 1863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @return SpinLock 1883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/ 1903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangSPIN_LOCK * 1913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI 1923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangReleaseSpinLock ( 1933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN OUT SPIN_LOCK *SpinLock 1943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 1953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 196c7f33ca42470dc87bc41a8583f427883123d67a1qwang SPIN_LOCK LockValue; 1973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 1983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ASSERT (SpinLock != NULL); 1993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang LockValue = *SpinLock; 2013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED); 2023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang *SpinLock = SPIN_LOCK_RELEASED; 2043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return SpinLock; 2053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 2063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/** 2083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Performs an atomic increment of an 32-bit unsigned integer. 2093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Performs an atomic increment of the 32-bit unsigned integer specified by 2113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Value and returns the incremented value. The increment operation must be 2123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang performed using MP safe mechanisms. The state of the return value is not 2133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang guaranteed to be MP safe. 2143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang If Value is NULL, then ASSERT(). 2163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @param Value A pointer to the 32-bit value to increment. 2183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @return The incremented value. 2203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/ 2223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangUINT32 2233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI 2243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangInterlockedIncrement ( 2253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN UINT32 *Value 2263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 2273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 2283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ASSERT (Value != NULL); 2293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return InternalSyncIncrement (Value); 2303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 2313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/** 2333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Performs an atomic decrement of an 32-bit unsigned integer. 2343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Performs an atomic decrement of the 32-bit unsigned integer specified by 2363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Value and returns the decremented value. The decrement operation must be 2373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang performed using MP safe mechanisms. The state of the return value is not 2383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang guaranteed to be MP safe. 2393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang If Value is NULL, then ASSERT(). 2413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @param Value A pointer to the 32-bit value to decrement. 2433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @return The decremented value. 2453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/ 2473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangUINT32 2483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI 2493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangInterlockedDecrement ( 2503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN UINT32 *Value 2513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 2523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 2533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ASSERT (Value != NULL); 2543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return InternalSyncDecrement (Value); 2553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 2563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/** 2583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Performs an atomic compare exchange operation on a 32-bit unsigned integer. 2593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Performs an atomic compare exchange operation on the 32-bit unsigned integer 2613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang specified by Value. If Value is equal to CompareValue, then Value is set to 2623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue, 2633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang then Value is returned. The compare exchange operation must be performed using 2643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang MP safe mechanisms. 2653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang If Value is NULL, then ASSERT(). 2673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @param Value A pointer to the 32-bit value for the compare exchange 2693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang operation. 2703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @param CompareValue 32-bit value used in compare operation. 2713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @param ExchangeValue 32-bit value used in exchange operation. 2723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @return The original *Value before exchange. 2743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/ 2763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangUINT32 2773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI 2783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangInterlockedCompareExchange32 ( 2793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN OUT UINT32 *Value, 2803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN UINT32 CompareValue, 2813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN UINT32 ExchangeValue 2823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 2833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 2843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ASSERT (Value != NULL); 2853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return InternalSyncCompareExchange32 (Value, CompareValue, ExchangeValue); 2863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 2873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/** 2893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Performs an atomic compare exchange operation on a 64-bit unsigned integer. 2903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Performs an atomic compare exchange operation on the 64-bit unsigned integer specified 2923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and 2933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang CompareValue is returned. If Value is not equal to CompareValue, then Value is returned. 2943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang The compare exchange operation must be performed using MP safe mechanisms. 2953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang If Value is NULL, then ASSERT(). 2973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 2983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @param Value A pointer to the 64-bit value for the compare exchange 2993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang operation. 3003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @param CompareValue 64-bit value used in compare operation. 3013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @param ExchangeValue 64-bit value used in exchange operation. 3023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @return The original *Value before exchange. 3043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/ 3063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangUINT64 3073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI 3083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangInterlockedCompareExchange64 ( 3093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN OUT UINT64 *Value, 3103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN UINT64 CompareValue, 3113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN UINT64 ExchangeValue 3123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 3133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 3143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ASSERT (Value != NULL); 3153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return InternalSyncCompareExchange64 (Value, CompareValue, ExchangeValue); 3163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 3173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/** 3193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Performs an atomic compare exchange operation on a pointer value. 3203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang Performs an atomic compare exchange operation on the pointer value specified 3223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang by Value. If Value is equal to CompareValue, then Value is set to 3233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ExchangeValue and CompareValue is returned. If Value is not equal to 3243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang CompareValue, then Value is returned. The compare exchange operation must be 3253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang performed using MP safe mechanisms. 3263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang If Value is NULL, then ASSERT(). 3283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @param Value A pointer to the pointer value for the compare exchange 3303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang operation. 3313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @param CompareValue Pointer value used in compare operation. 3323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang @param ExchangeValue Pointer value used in exchange operation. 3333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/ 3353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID * 3363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI 3373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangInterlockedCompareExchangePointer ( 3383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN OUT VOID **Value, 3393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN VOID *CompareValue, 3403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang IN VOID *ExchangeValue 3413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ) 3423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{ 3433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang UINT8 SizeOfValue; 3443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang SizeOfValue = sizeof (*Value); 3463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang 3473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang switch (SizeOfValue) { 3483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang case sizeof (UINT32): 3493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return (VOID*)(UINTN)InterlockedCompareExchange32 ( 3503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang (UINT32*)Value, 3513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang (UINT32)(UINTN)CompareValue, 3523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang (UINT32)(UINTN)ExchangeValue 3533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ); 3543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang case sizeof (UINT64): 3553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return (VOID*)(UINTN)InterlockedCompareExchange64 ( 3563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang (UINT64*)Value, 3573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang (UINT64)(UINTN)CompareValue, 3583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang (UINT64)(UINTN)ExchangeValue 3593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ); 3603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang default: 3613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang ASSERT (FALSE); 3623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang return NULL; 3633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang } 3643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang} 365