MdePkg/BaseSynchronizationLib: Add InterlockedCompareExchange16
This implements the function InterlockedCompareExchange16 () for all architectures, using architecture and toolchain specific intrinsics or primitive assembler instructions. Contributed-under: TianoCore Contribution Agreement 1.0 Reviewed-by: Olivier Martin <olivier.martin@arm.com> Acked-by: Jordan Justen <jordan.l.justen@intel.com> Reviewed-by: Michael Kinney <michael.d.kinney@intel.com> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Laszlo Ersek <lersek@redhat.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16966 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -183,6 +183,32 @@ InterlockedDecrement (
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs an atomic compare exchange operation on a 16-bit unsigned integer.
|
||||||
|
|
||||||
|
Performs an atomic compare exchange operation on the 16-bit unsigned integer
|
||||||
|
specified by Value. If Value is equal to CompareValue, then Value is set to
|
||||||
|
ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
|
||||||
|
then Value is returned. The compare exchange operation must be performed using
|
||||||
|
MP safe mechanisms.
|
||||||
|
|
||||||
|
If Value is NULL, then ASSERT().
|
||||||
|
|
||||||
|
@param Value A pointer to the 16-bit value for the compare exchange
|
||||||
|
operation.
|
||||||
|
@param CompareValue 16-bit value used in compare operation.
|
||||||
|
@param ExchangeValue 16-bit value used in exchange operation.
|
||||||
|
|
||||||
|
@return The original *Value before exchange.
|
||||||
|
**/
|
||||||
|
UINT16
|
||||||
|
EFIAPI
|
||||||
|
InterlockedCompareExchange16 (
|
||||||
|
IN OUT UINT16 *Value,
|
||||||
|
IN UINT16 CompareValue,
|
||||||
|
IN UINT16 ExchangeValue
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
||||||
|
|
||||||
|
@@ -16,11 +16,55 @@
|
|||||||
.text
|
.text
|
||||||
.align 3
|
.align 3
|
||||||
|
|
||||||
|
GCC_ASM_EXPORT(InternalSyncCompareExchange16)
|
||||||
GCC_ASM_EXPORT(InternalSyncCompareExchange32)
|
GCC_ASM_EXPORT(InternalSyncCompareExchange32)
|
||||||
GCC_ASM_EXPORT(InternalSyncCompareExchange64)
|
GCC_ASM_EXPORT(InternalSyncCompareExchange64)
|
||||||
GCC_ASM_EXPORT(InternalSyncIncrement)
|
GCC_ASM_EXPORT(InternalSyncIncrement)
|
||||||
GCC_ASM_EXPORT(InternalSyncDecrement)
|
GCC_ASM_EXPORT(InternalSyncDecrement)
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs an atomic compare exchange operation on a 16-bit unsigned integer.
|
||||||
|
|
||||||
|
Performs an atomic compare exchange operation on the 16-bit unsigned integer
|
||||||
|
specified by Value. If Value is equal to CompareValue, then Value is set to
|
||||||
|
ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
|
||||||
|
then Value is returned. The compare exchange operation must be performed using
|
||||||
|
MP safe mechanisms.
|
||||||
|
|
||||||
|
@param Value A pointer to the 16-bit value for the compare exchange
|
||||||
|
operation.
|
||||||
|
@param CompareValue 16-bit value used in compare operation.
|
||||||
|
@param ExchangeValue 16-bit value used in exchange operation.
|
||||||
|
|
||||||
|
@return The original *Value before exchange.
|
||||||
|
|
||||||
|
**/
|
||||||
|
//UINT16
|
||||||
|
//EFIAPI
|
||||||
|
//InternalSyncCompareExchange16 (
|
||||||
|
// IN volatile UINT16 *Value,
|
||||||
|
// IN UINT16 CompareValue,
|
||||||
|
// IN UINT16 ExchangeValue
|
||||||
|
// )
|
||||||
|
ASM_PFX(InternalSyncCompareExchange16):
|
||||||
|
uxth w1, w1
|
||||||
|
uxth w2, w2
|
||||||
|
dmb sy
|
||||||
|
|
||||||
|
InternalSyncCompareExchange16Again:
|
||||||
|
ldxrh w3, [x0]
|
||||||
|
cmp w3, w1
|
||||||
|
bne InternalSyncCompareExchange16Fail
|
||||||
|
|
||||||
|
InternalSyncCompareExchange16Exchange:
|
||||||
|
stxrh w4, w2, [x0]
|
||||||
|
cbnz w4, InternalSyncCompareExchange16Again
|
||||||
|
|
||||||
|
InternalSyncCompareExchange16Fail:
|
||||||
|
dmb sy
|
||||||
|
mov w0, w3
|
||||||
|
ret
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
// Implementation of synchronization functions for ARM architecture
|
// Implementation of synchronization functions for ARM architecture
|
||||||
//
|
//
|
||||||
// Copyright (c) 2012-2015, ARM Limited. All rights reserved.
|
// Copyright (c) 2012-2015, ARM Limited. All rights reserved.
|
||||||
|
// Copyright (c) 2015, Linaro Limited. All rights reserved.
|
||||||
//
|
//
|
||||||
// This program and the accompanying materials
|
// This program and the accompanying materials
|
||||||
// are licensed and made available under the terms and conditions of the BSD License
|
// are licensed and made available under the terms and conditions of the BSD License
|
||||||
@@ -15,11 +16,54 @@
|
|||||||
.text
|
.text
|
||||||
.align 3
|
.align 3
|
||||||
|
|
||||||
|
GCC_ASM_EXPORT(InternalSyncCompareExchange16)
|
||||||
GCC_ASM_EXPORT(InternalSyncCompareExchange32)
|
GCC_ASM_EXPORT(InternalSyncCompareExchange32)
|
||||||
GCC_ASM_EXPORT(InternalSyncCompareExchange64)
|
GCC_ASM_EXPORT(InternalSyncCompareExchange64)
|
||||||
GCC_ASM_EXPORT(InternalSyncIncrement)
|
GCC_ASM_EXPORT(InternalSyncIncrement)
|
||||||
GCC_ASM_EXPORT(InternalSyncDecrement)
|
GCC_ASM_EXPORT(InternalSyncDecrement)
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs an atomic compare exchange operation on a 16-bit unsigned integer.
|
||||||
|
|
||||||
|
Performs an atomic compare exchange operation on the 16-bit unsigned integer
|
||||||
|
specified by Value. If Value is equal to CompareValue, then Value is set to
|
||||||
|
ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
|
||||||
|
then Value is returned. The compare exchange operation must be performed using
|
||||||
|
MP safe mechanisms.
|
||||||
|
|
||||||
|
@param Value A pointer to the 16-bit value for the compare exchange
|
||||||
|
operation.
|
||||||
|
@param CompareValue 16-bit value used in compare operation.
|
||||||
|
@param ExchangeValue 16-bit value used in exchange operation.
|
||||||
|
|
||||||
|
@return The original *Value before exchange.
|
||||||
|
|
||||||
|
**/
|
||||||
|
//UINT16
|
||||||
|
//EFIAPI
|
||||||
|
//InternalSyncCompareExchange16 (
|
||||||
|
// IN volatile UINT16 *Value,
|
||||||
|
// IN UINT16 CompareValue,
|
||||||
|
// IN UINT16 ExchangeValue
|
||||||
|
// )
|
||||||
|
ASM_PFX(InternalSyncCompareExchange16):
|
||||||
|
dmb
|
||||||
|
|
||||||
|
InternalSyncCompareExchange16Again:
|
||||||
|
ldrexh r3, [r0]
|
||||||
|
cmp r3, r1
|
||||||
|
bne InternalSyncCompareExchange16Fail
|
||||||
|
|
||||||
|
InternalSyncCompareExchange16Exchange:
|
||||||
|
strexh ip, r2, [r0]
|
||||||
|
cmp ip, #0
|
||||||
|
bne InternalSyncCompareExchange16Again
|
||||||
|
|
||||||
|
InternalSyncCompareExchange16Fail:
|
||||||
|
dmb
|
||||||
|
mov r0, r3
|
||||||
|
bx lr
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
// Implementation of synchronization functions for ARM architecture
|
// Implementation of synchronization functions for ARM architecture
|
||||||
//
|
//
|
||||||
// Copyright (c) 2012-2015, ARM Limited. All rights reserved.
|
// Copyright (c) 2012-2015, ARM Limited. All rights reserved.
|
||||||
|
// Copyright (c) 2015, Linaro Limited. All rights reserved.
|
||||||
//
|
//
|
||||||
// This program and the accompanying materials
|
// This program and the accompanying materials
|
||||||
// are licensed and made available under the terms and conditions of the BSD License
|
// are licensed and made available under the terms and conditions of the BSD License
|
||||||
@@ -12,6 +13,7 @@
|
|||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
|
EXPORT InternalSyncCompareExchange16
|
||||||
EXPORT InternalSyncCompareExchange32
|
EXPORT InternalSyncCompareExchange32
|
||||||
EXPORT InternalSyncCompareExchange64
|
EXPORT InternalSyncCompareExchange64
|
||||||
EXPORT InternalSyncIncrement
|
EXPORT InternalSyncIncrement
|
||||||
@@ -19,6 +21,48 @@
|
|||||||
|
|
||||||
AREA ArmSynchronization, CODE, READONLY
|
AREA ArmSynchronization, CODE, READONLY
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs an atomic compare exchange operation on a 16-bit unsigned integer.
|
||||||
|
|
||||||
|
Performs an atomic compare exchange operation on the 16-bit unsigned integer
|
||||||
|
specified by Value. If Value is equal to CompareValue, then Value is set to
|
||||||
|
ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
|
||||||
|
then Value is returned. The compare exchange operation must be performed using
|
||||||
|
MP safe mechanisms.
|
||||||
|
|
||||||
|
@param Value A pointer to the 16-bit value for the compare exchange
|
||||||
|
operation.
|
||||||
|
@param CompareValue 16-bit value used in compare operation.
|
||||||
|
@param ExchangeValue 16-bit value used in exchange operation.
|
||||||
|
|
||||||
|
@return The original *Value before exchange.
|
||||||
|
|
||||||
|
**/
|
||||||
|
//UINT16
|
||||||
|
//EFIAPI
|
||||||
|
//InternalSyncCompareExchange16 (
|
||||||
|
// IN volatile UINT16 *Value,
|
||||||
|
// IN UINT16 CompareValue,
|
||||||
|
// IN UINT16 ExchangeValue
|
||||||
|
// )
|
||||||
|
InternalSyncCompareExchange16
|
||||||
|
dmb
|
||||||
|
|
||||||
|
InternalSyncCompareExchange16Again
|
||||||
|
ldrexh r3, [r0]
|
||||||
|
cmp r3, r1
|
||||||
|
bne InternalSyncCompareExchange16Fail
|
||||||
|
|
||||||
|
InternalSyncCompareExchange16Exchange
|
||||||
|
strexh ip, r2, [r0]
|
||||||
|
cmp ip, #0
|
||||||
|
bne InternalSyncCompareExchange16Again
|
||||||
|
|
||||||
|
InternalSyncCompareExchange16Fail
|
||||||
|
dmb
|
||||||
|
mov r0, r3
|
||||||
|
bx lr
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
||||||
|
|
||||||
|
@@ -32,12 +32,14 @@
|
|||||||
[Sources.IA32]
|
[Sources.IA32]
|
||||||
Ia32/InterlockedCompareExchange64.c | MSFT
|
Ia32/InterlockedCompareExchange64.c | MSFT
|
||||||
Ia32/InterlockedCompareExchange32.c | MSFT
|
Ia32/InterlockedCompareExchange32.c | MSFT
|
||||||
|
Ia32/InterlockedCompareExchange16.c | MSFT
|
||||||
Ia32/InterlockedDecrement.c | MSFT
|
Ia32/InterlockedDecrement.c | MSFT
|
||||||
Ia32/InterlockedIncrement.c | MSFT
|
Ia32/InterlockedIncrement.c | MSFT
|
||||||
SynchronizationMsc.c | MSFT
|
SynchronizationMsc.c | MSFT
|
||||||
|
|
||||||
Ia32/InterlockedCompareExchange64.asm | INTEL
|
Ia32/InterlockedCompareExchange64.asm | INTEL
|
||||||
Ia32/InterlockedCompareExchange32.asm | INTEL
|
Ia32/InterlockedCompareExchange32.asm | INTEL
|
||||||
|
Ia32/InterlockedCompareExchange16.asm | INTEL
|
||||||
Ia32/InterlockedDecrement.asm | INTEL
|
Ia32/InterlockedDecrement.asm | INTEL
|
||||||
Ia32/InterlockedIncrement.asm | INTEL
|
Ia32/InterlockedIncrement.asm | INTEL
|
||||||
Synchronization.c | INTEL
|
Synchronization.c | INTEL
|
||||||
@@ -48,9 +50,11 @@
|
|||||||
[Sources.X64]
|
[Sources.X64]
|
||||||
X64/InterlockedCompareExchange64.c | MSFT
|
X64/InterlockedCompareExchange64.c | MSFT
|
||||||
X64/InterlockedCompareExchange32.c | MSFT
|
X64/InterlockedCompareExchange32.c | MSFT
|
||||||
|
X64/InterlockedCompareExchange16.c | MSFT
|
||||||
|
|
||||||
X64/InterlockedCompareExchange64.asm | INTEL
|
X64/InterlockedCompareExchange64.asm | INTEL
|
||||||
X64/InterlockedCompareExchange32.asm | INTEL
|
X64/InterlockedCompareExchange32.asm | INTEL
|
||||||
|
X64/InterlockedCompareExchange16.asm | INTEL
|
||||||
|
|
||||||
X64/InterlockedDecrement.c | MSFT
|
X64/InterlockedDecrement.c | MSFT
|
||||||
X64/InterlockedIncrement.c | MSFT
|
X64/InterlockedIncrement.c | MSFT
|
||||||
@@ -67,6 +71,7 @@
|
|||||||
Ipf/Synchronization.c
|
Ipf/Synchronization.c
|
||||||
Ipf/InterlockedCompareExchange64.s
|
Ipf/InterlockedCompareExchange64.s
|
||||||
Ipf/InterlockedCompareExchange32.s
|
Ipf/InterlockedCompareExchange32.s
|
||||||
|
Ipf/InterlockedCompareExchange16.s
|
||||||
|
|
||||||
Synchronization.c | INTEL
|
Synchronization.c | INTEL
|
||||||
SynchronizationMsc.c | MSFT
|
SynchronizationMsc.c | MSFT
|
||||||
|
@@ -62,6 +62,32 @@ InternalSyncDecrement (
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs an atomic compare exchange operation on a 16-bit unsigned integer.
|
||||||
|
|
||||||
|
Performs an atomic compare exchange operation on the 16-bit unsigned integer
|
||||||
|
specified by Value. If Value is equal to CompareValue, then Value is set to
|
||||||
|
ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
|
||||||
|
then Value is returned. The compare exchange operation must be performed using
|
||||||
|
MP safe mechanisms.
|
||||||
|
|
||||||
|
@param Value A pointer to the 16-bit value for the compare exchange
|
||||||
|
operation.
|
||||||
|
@param CompareValue A 16-bit value used in compare operation.
|
||||||
|
@param ExchangeValue A 16-bit value used in exchange operation.
|
||||||
|
|
||||||
|
@return The original *Value before exchange.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT16
|
||||||
|
EFIAPI
|
||||||
|
InternalSyncCompareExchange16 (
|
||||||
|
IN volatile UINT16 *Value,
|
||||||
|
IN UINT16 CompareValue,
|
||||||
|
IN UINT16 ExchangeValue
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
||||||
|
|
||||||
|
@@ -12,6 +12,37 @@
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs an atomic compare exchange operation on a 16-bit
|
||||||
|
unsigned integer.
|
||||||
|
|
||||||
|
Performs an atomic compare exchange operation on the 16-bit
|
||||||
|
unsigned integer specified by Value. If Value is equal to
|
||||||
|
CompareValue, then Value is set to ExchangeValue and
|
||||||
|
CompareValue is returned. If Value is not equal to
|
||||||
|
CompareValue, then Value is returned. The compare exchange
|
||||||
|
operation must be performed using MP safe mechanisms.
|
||||||
|
|
||||||
|
@param Value A pointer to the 16-bit value for the
|
||||||
|
compare exchange operation.
|
||||||
|
@param CompareValue 16-bit value used in compare operation.
|
||||||
|
@param ExchangeValue 16-bit value used in exchange operation.
|
||||||
|
|
||||||
|
@return The original *Value before exchange.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT16
|
||||||
|
EFIAPI
|
||||||
|
InternalSyncCompareExchange16 (
|
||||||
|
IN volatile UINT16 *Value,
|
||||||
|
IN UINT16 CompareValue,
|
||||||
|
IN UINT16 ExchangeValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return *Value != CompareValue ? *Value :
|
||||||
|
((*Value = ExchangeValue), CompareValue);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Performs an atomic compare exchange operation on a 32-bit
|
Performs an atomic compare exchange operation on a 32-bit
|
||||||
unsigned integer.
|
unsigned integer.
|
||||||
|
@@ -87,6 +87,48 @@ InternalSyncDecrement (
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs an atomic compare exchange operation on a 16-bit unsigned integer.
|
||||||
|
|
||||||
|
Performs an atomic compare exchange operation on the 16-bit unsigned integer
|
||||||
|
specified by Value. If Value is equal to CompareValue, then Value is set to
|
||||||
|
ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
|
||||||
|
then Value is returned. The compare exchange operation must be performed using
|
||||||
|
MP safe mechanisms.
|
||||||
|
|
||||||
|
|
||||||
|
@param Value A pointer to the 16-bit value for the compare exchange
|
||||||
|
operation.
|
||||||
|
@param CompareValue 16-bit value used in compare operation.
|
||||||
|
@param ExchangeValue 16-bit value used in exchange operation.
|
||||||
|
|
||||||
|
@return The original *Value before exchange.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT16
|
||||||
|
EFIAPI
|
||||||
|
InternalSyncCompareExchange16 (
|
||||||
|
IN OUT volatile UINT16 *Value,
|
||||||
|
IN UINT16 CompareValue,
|
||||||
|
IN UINT16 ExchangeValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
" \n\t"
|
||||||
|
"lock \n\t"
|
||||||
|
"cmpxchgw %1, %2 \n\t"
|
||||||
|
: "=a" (CompareValue)
|
||||||
|
: "q" (ExchangeValue),
|
||||||
|
"m" (*Value),
|
||||||
|
"0" (CompareValue)
|
||||||
|
: "memory",
|
||||||
|
"cc"
|
||||||
|
);
|
||||||
|
|
||||||
|
return CompareValue;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
||||||
|
|
||||||
|
@@ -0,0 +1,46 @@
|
|||||||
|
;------------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
|
||||||
|
; Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
|
||||||
|
; This program and the accompanying materials
|
||||||
|
; are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
; which accompanies this distribution. The full text of the license may be found at
|
||||||
|
; http://opensource.org/licenses/bsd-license.php.
|
||||||
|
;
|
||||||
|
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
;
|
||||||
|
; Module Name:
|
||||||
|
;
|
||||||
|
; InterlockedCompareExchange16.Asm
|
||||||
|
;
|
||||||
|
; Abstract:
|
||||||
|
;
|
||||||
|
; InterlockedCompareExchange16 function
|
||||||
|
;
|
||||||
|
; Notes:
|
||||||
|
;
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
.486
|
||||||
|
.model flat,C
|
||||||
|
.code
|
||||||
|
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
; UINT16
|
||||||
|
; EFIAPI
|
||||||
|
; InternalSyncCompareExchange16 (
|
||||||
|
; IN UINT16 *Value,
|
||||||
|
; IN UINT16 CompareValue,
|
||||||
|
; IN UINT16 ExchangeValue
|
||||||
|
; );
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
InternalSyncCompareExchange16 PROC
|
||||||
|
mov ecx, [esp + 4]
|
||||||
|
mov ax, [esp + 8]
|
||||||
|
mov dx, [esp + 12]
|
||||||
|
lock cmpxchg [ecx], dx
|
||||||
|
ret
|
||||||
|
InternalSyncCompareExchange16 ENDP
|
||||||
|
|
||||||
|
END
|
@@ -0,0 +1,51 @@
|
|||||||
|
/** @file
|
||||||
|
InterlockedCompareExchange16 function
|
||||||
|
|
||||||
|
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||||
|
Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
|
||||||
|
This program and the accompanying materials
|
||||||
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
http://opensource.org/licenses/bsd-license.php.
|
||||||
|
|
||||||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs an atomic compare exchange operation on a 16-bit unsigned integer.
|
||||||
|
|
||||||
|
Performs an atomic compare exchange operation on the 16-bit unsigned integer
|
||||||
|
specified by Value. If Value is equal to CompareValue, then Value is set to
|
||||||
|
ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
|
||||||
|
then Value is returned. The compare exchange operation must be performed using
|
||||||
|
MP safe mechanisms.
|
||||||
|
|
||||||
|
@param Value A pointer to the 16-bit value for the compare exchange
|
||||||
|
operation.
|
||||||
|
@param CompareValue 16-bit value used in compare operation.
|
||||||
|
@param ExchangeValue 16-bit value used in exchange operation.
|
||||||
|
|
||||||
|
@return The original *Value before exchange.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT16
|
||||||
|
EFIAPI
|
||||||
|
InternalSyncCompareExchange16 (
|
||||||
|
IN UINT16 *Value,
|
||||||
|
IN UINT16 CompareValue,
|
||||||
|
IN UINT16 ExchangeValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_asm {
|
||||||
|
mov ecx, Value
|
||||||
|
mov ax, CompareValue
|
||||||
|
mov dx, ExchangeValue
|
||||||
|
lock cmpxchg [ecx], dx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -0,0 +1,30 @@
|
|||||||
|
/// @file
|
||||||
|
/// Contains an implementation of InterlockedCompareExchange16 on Itanium-
|
||||||
|
/// based architecture.
|
||||||
|
///
|
||||||
|
/// Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
|
||||||
|
/// Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
|
||||||
|
/// This program and the accompanying materials
|
||||||
|
/// are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
/// which accompanies this distribution. The full text of the license may be found at
|
||||||
|
/// http://opensource.org/licenses/bsd-license.php.
|
||||||
|
///
|
||||||
|
/// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
/// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
///
|
||||||
|
/// Module Name: InterlockedCompareExchange16.s
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
|
.auto
|
||||||
|
.text
|
||||||
|
|
||||||
|
.proc InternalSyncCompareExchange16
|
||||||
|
.type InternalSyncCompareExchange16, @function
|
||||||
|
InternalSyncCompareExchange16::
|
||||||
|
zxt2 r33 = r33
|
||||||
|
mov ar.ccv = r33
|
||||||
|
cmpxchg2.rel r8 = [r32], r34
|
||||||
|
mf
|
||||||
|
br.ret.sptk.many b0
|
||||||
|
.endp InternalSyncCompareExchange16
|
@@ -276,6 +276,37 @@ InterlockedDecrement (
|
|||||||
return InternalSyncDecrement (Value);
|
return InternalSyncDecrement (Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs an atomic compare exchange operation on a 16-bit unsigned integer.
|
||||||
|
|
||||||
|
Performs an atomic compare exchange operation on the 16-bit unsigned integer
|
||||||
|
specified by Value. If Value is equal to CompareValue, then Value is set to
|
||||||
|
ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
|
||||||
|
then Value is returned. The compare exchange operation must be performed using
|
||||||
|
MP safe mechanisms.
|
||||||
|
|
||||||
|
If Value is NULL, then ASSERT().
|
||||||
|
|
||||||
|
@param Value A pointer to the 16-bit value for the compare exchange
|
||||||
|
operation.
|
||||||
|
@param CompareValue 16-bit value used in compare operation.
|
||||||
|
@param ExchangeValue 16-bit value used in exchange operation.
|
||||||
|
|
||||||
|
@return The original *Value before exchange.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT16
|
||||||
|
EFIAPI
|
||||||
|
InterlockedCompareExchange16 (
|
||||||
|
IN OUT UINT16 *Value,
|
||||||
|
IN UINT16 CompareValue,
|
||||||
|
IN UINT16 ExchangeValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (Value != NULL);
|
||||||
|
return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
||||||
|
|
||||||
|
@@ -292,6 +292,37 @@ InterlockedDecrement (
|
|||||||
return InternalSyncDecrement (Value);
|
return InternalSyncDecrement (Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs an atomic compare exchange operation on a 16-bit unsigned integer.
|
||||||
|
|
||||||
|
Performs an atomic compare exchange operation on the 16-bit unsigned integer
|
||||||
|
specified by Value. If Value is equal to CompareValue, then Value is set to
|
||||||
|
ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
|
||||||
|
then Value is returned. The compare exchange operation must be performed using
|
||||||
|
MP safe mechanisms.
|
||||||
|
|
||||||
|
If Value is NULL, then ASSERT().
|
||||||
|
|
||||||
|
@param Value A pointer to the 16-bit value for the compare exchange
|
||||||
|
operation.
|
||||||
|
@param CompareValue A 16-bit value used in compare operation.
|
||||||
|
@param ExchangeValue A 16-bit value used in exchange operation.
|
||||||
|
|
||||||
|
@return The original *Value before exchange.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT16
|
||||||
|
EFIAPI
|
||||||
|
InterlockedCompareExchange16 (
|
||||||
|
IN OUT UINT16 *Value,
|
||||||
|
IN UINT16 CompareValue,
|
||||||
|
IN UINT16 ExchangeValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (Value != NULL);
|
||||||
|
return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
||||||
|
|
||||||
|
@@ -294,6 +294,37 @@ InterlockedDecrement (
|
|||||||
return InternalSyncDecrement (Value);
|
return InternalSyncDecrement (Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs an atomic compare exchange operation on a 16-bit unsigned integer.
|
||||||
|
|
||||||
|
Performs an atomic compare exchange operation on the 16-bit unsigned integer
|
||||||
|
specified by Value. If Value is equal to CompareValue, then Value is set to
|
||||||
|
ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
|
||||||
|
then Value is returned. The compare exchange operation must be performed using
|
||||||
|
MP safe mechanisms.
|
||||||
|
|
||||||
|
If Value is NULL, then ASSERT().
|
||||||
|
|
||||||
|
@param Value A pointer to the 16-bit value for the compare exchange
|
||||||
|
operation.
|
||||||
|
@param CompareValue A 16-bit value used in a compare operation.
|
||||||
|
@param ExchangeValue A 16-bit value used in an exchange operation.
|
||||||
|
|
||||||
|
@return The original *Value before exchange.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT16
|
||||||
|
EFIAPI
|
||||||
|
InterlockedCompareExchange16 (
|
||||||
|
IN OUT UINT16 *Value,
|
||||||
|
IN UINT16 CompareValue,
|
||||||
|
IN UINT16 ExchangeValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ASSERT (Value != NULL);
|
||||||
|
return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
||||||
|
|
||||||
|
@@ -88,6 +88,50 @@ InternalSyncDecrement (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs an atomic compare exchange operation on a 16-bit unsigned integer.
|
||||||
|
|
||||||
|
Performs an atomic compare exchange operation on the 16-bit unsigned integer
|
||||||
|
specified by Value. If Value is equal to CompareValue, then Value is set to
|
||||||
|
ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
|
||||||
|
then Value is returned. The compare exchange operation must be performed using
|
||||||
|
MP safe mechanisms.
|
||||||
|
|
||||||
|
|
||||||
|
@param Value A pointer to the 16-bit value for the compare exchange
|
||||||
|
operation.
|
||||||
|
@param CompareValue 16-bit value used in compare operation.
|
||||||
|
@param ExchangeValue 16-bit value used in exchange operation.
|
||||||
|
|
||||||
|
@return The original *Value before exchange.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT16
|
||||||
|
EFIAPI
|
||||||
|
InternalSyncCompareExchange16 (
|
||||||
|
IN OUT volatile UINT16 *Value,
|
||||||
|
IN UINT16 CompareValue,
|
||||||
|
IN UINT16 ExchangeValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"lock \n\t"
|
||||||
|
"cmpxchgw %3, %1 "
|
||||||
|
: "=a" (CompareValue),
|
||||||
|
"=m" (*Value)
|
||||||
|
: "a" (CompareValue),
|
||||||
|
"r" (ExchangeValue),
|
||||||
|
"m" (*Value)
|
||||||
|
: "memory",
|
||||||
|
"cc"
|
||||||
|
);
|
||||||
|
|
||||||
|
return CompareValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
Performs an atomic compare exchange operation on a 32-bit unsigned integer.
|
||||||
|
|
||||||
|
@@ -0,0 +1,42 @@
|
|||||||
|
;------------------------------------------------------------------------------
|
||||||
|
;
|
||||||
|
; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
|
||||||
|
; Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
|
||||||
|
; This program and the accompanying materials
|
||||||
|
; are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
; which accompanies this distribution. The full text of the license may be found at
|
||||||
|
; http://opensource.org/licenses/bsd-license.php.
|
||||||
|
;
|
||||||
|
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
;
|
||||||
|
; Module Name:
|
||||||
|
;
|
||||||
|
; InterlockedCompareExchange16.Asm
|
||||||
|
;
|
||||||
|
; Abstract:
|
||||||
|
;
|
||||||
|
; InterlockedCompareExchange16 function
|
||||||
|
;
|
||||||
|
; Notes:
|
||||||
|
;
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
; UINT16
|
||||||
|
; EFIAPI
|
||||||
|
; InterlockedCompareExchange16 (
|
||||||
|
; IN UINT16 *Value,
|
||||||
|
; IN UINT16 CompareValue,
|
||||||
|
; IN UINT16 ExchangeValue
|
||||||
|
; );
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
InternalSyncCompareExchange16 PROC
|
||||||
|
mov ax, dx
|
||||||
|
lock cmpxchg [rcx], r8w
|
||||||
|
ret
|
||||||
|
InternalSyncCompareExchange16 ENDP
|
||||||
|
|
||||||
|
END
|
@@ -0,0 +1,54 @@
|
|||||||
|
/** @file
|
||||||
|
InterlockedCompareExchange16 function
|
||||||
|
|
||||||
|
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||||
|
Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
|
||||||
|
This program and the accompanying materials
|
||||||
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
http://opensource.org/licenses/bsd-license.php.
|
||||||
|
|
||||||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.
|
||||||
|
**/
|
||||||
|
|
||||||
|
__int16 _InterlockedCompareExchange16(
|
||||||
|
__int16 volatile * Destination,
|
||||||
|
__int16 Exchange,
|
||||||
|
__int16 Comperand
|
||||||
|
);
|
||||||
|
|
||||||
|
#pragma intrinsic(_InterlockedCompareExchange16)
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs an atomic compare exchange operation on a 16-bit unsigned integer.
|
||||||
|
|
||||||
|
Performs an atomic compare exchange operation on the 16-bit unsigned integer specified
|
||||||
|
by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and
|
||||||
|
CompareValue is returned. If Value is not equal to CompareValue, then Value is returned.
|
||||||
|
The compare exchange operation must be performed using MP safe mechanisms.
|
||||||
|
|
||||||
|
@param Value A pointer to the 16-bit value for the compare exchange
|
||||||
|
operation.
|
||||||
|
@param CompareValue 16-bit value used in compare operation.
|
||||||
|
@param ExchangeValue 16-bit value used in exchange operation.
|
||||||
|
|
||||||
|
@return The original *Value before exchange.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT16
|
||||||
|
EFIAPI
|
||||||
|
InternalSyncCompareExchange16 (
|
||||||
|
IN UINT16 *Value,
|
||||||
|
IN UINT16 CompareValue,
|
||||||
|
IN UINT16 ExchangeValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return _InterlockedCompareExchange16 (Value, ExchangeValue, CompareValue);
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user