TestAndClearBit.c 1021 B

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