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 This program and the accompanying materials 8 are licensed and made available under the terms and conditions of the BSD License 9 which accompanies this distribution. The full text of the license may be found at 10 http://opensource.org/licenses/bsd-license.php 11 12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 14 15**/ 16 17#include <Base.h> 18#include <Library/SynchronizationLib.h> 19 20INT32 21EFIAPI 22TestAndClearBit ( 23 IN INT32 Bit, 24 IN VOID *Address 25 ) 26{ 27 UINT16 Word, Read; 28 UINT16 Mask; 29 30 // 31 // Calculate the effective address relative to 'Address' based on the 32 // higher order bits of 'Bit'. Use signed shift instead of division to 33 // ensure we round towards -Inf, and end up with a positive shift in 34 // 'Bit', even if 'Bit' itself is negative. 35 // 36 Address = (VOID*)((UINT8*) Address + ((Bit >> 4) * sizeof(UINT16))); 37 Mask = 1U << (Bit & 15); 38 39 for (Word = *(UINT16 *) Address; Word & Mask; Word = Read) { 40 Read = InterlockedCompareExchange16 (Address, Word, Word & ~Mask); 41 if (Read == Word) { 42 return 1; 43 } 44 } 45 return 0; 46} 47