1 /** @file 2 Implementation of TestAndClearBit using compare-exchange primitive 3 4 Copyright (C) 2015, Linaro Ltd. 5 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> 6 7 SPDX-License-Identifier: BSD-2-Clause-Patent 8 9 **/ 10 11 #include <Base.h> 12 #include <Library/SynchronizationLib.h> 13 14 INT32 15 EFIAPI TestAndClearBit(IN INT32 Bit,IN VOID * Address)16TestAndClearBit ( 17 IN INT32 Bit, 18 IN VOID *Address 19 ) 20 { 21 UINT16 Word, Read; 22 UINT16 Mask; 23 24 // 25 // Calculate the effective address relative to 'Address' based on the 26 // higher order bits of 'Bit'. Use signed shift instead of division to 27 // ensure we round towards -Inf, and end up with a positive shift in 28 // 'Bit', even if 'Bit' itself is negative. 29 // 30 Address = (VOID*)((UINT8*) Address + ((Bit >> 4) * sizeof(UINT16))); 31 Mask = 1U << (Bit & 15); 32 33 for (Word = *(UINT16 *) Address; Word & Mask; Word = Read) { 34 Read = InterlockedCompareExchange16 (Address, Word, Word & ~Mask); 35 if (Read == Word) { 36 return 1; 37 } 38 } 39 return 0; 40 } 41