mirror of
https://github.com/reactos/reactos.git
synced 2025-07-04 02:31:22 +00:00
[NTOSKRNL]
Patch by Paolo Bonzini <bonzini [at] gnu [dot] org> Fix implementation of ExInterlockedAddLargeStatistic The old version wasn't really atomic. See issue #6223 for more details. svn path=/trunk/; revision=51748
This commit is contained in:
parent
c016e5d41e
commit
e12ea18992
1 changed files with 46 additions and 15 deletions
|
@ -4,6 +4,7 @@
|
||||||
* FILE: ntoskrnl/ex/i386/fastinterlck_asm.S
|
* FILE: ntoskrnl/ex/i386/fastinterlck_asm.S
|
||||||
* PURPOSE: FASTCALL Interlocked Functions
|
* PURPOSE: FASTCALL Interlocked Functions
|
||||||
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
|
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
|
||||||
|
* Paolo Bonzini <bonzini [at] gnu [dot] org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
@ -31,26 +32,56 @@
|
||||||
*/
|
*/
|
||||||
PUBLIC @ExInterlockedAddLargeStatistic@8
|
PUBLIC @ExInterlockedAddLargeStatistic@8
|
||||||
@ExInterlockedAddLargeStatistic@8:
|
@ExInterlockedAddLargeStatistic@8:
|
||||||
|
push ebp
|
||||||
|
push ebx
|
||||||
|
mov ebp, ecx
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
Again:
|
||||||
/* Do the addition */
|
/* Load comparand in eax for cmpxchg */
|
||||||
lock add [ecx], edx
|
mov eax, [ebp]
|
||||||
|
|
||||||
/* Check for carry bit and return */
|
/* Compute low word of the result in ebx */
|
||||||
jb .l1
|
mov ebx, edx
|
||||||
|
add ebx, eax
|
||||||
|
|
||||||
|
/* Carry needs cmpxchg8b */
|
||||||
|
jc Slow
|
||||||
|
|
||||||
|
/* Fast path still needs to be atomic, so use cmpxchg and retry if it fails
|
||||||
|
* Hopefully it will still get through this path :) */
|
||||||
|
LOCK cmpxchg [ecx], ebx
|
||||||
|
jnz Again
|
||||||
|
|
||||||
|
/* Thats it */
|
||||||
|
pop ebx
|
||||||
|
pop ebp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.l1:
|
Slow:
|
||||||
/* Add carry */
|
/* Save increment across cmpxchg8b */
|
||||||
lock adc dword ptr [ecx+4], 0
|
push edx
|
||||||
#else
|
|
||||||
/* Do the addition and add the carry */
|
/* Finish loading comparand in edx:eax */
|
||||||
add dword ptr [ecx], edx
|
mov edx, [ebp+4]
|
||||||
adc dword ptr [ecx+4], 0
|
|
||||||
#endif
|
/* Result in ecx:ebx (we know there's carry) */
|
||||||
/* Return */
|
lea ecx, [edx+1]
|
||||||
|
|
||||||
|
/* Do a full exchange */
|
||||||
|
LOCK cmpxchg8b [ebp]
|
||||||
|
|
||||||
|
/* restore increment */
|
||||||
|
pop edx
|
||||||
|
|
||||||
|
/* Need to retry */
|
||||||
|
jnz Again
|
||||||
|
|
||||||
|
/* Thats it */
|
||||||
|
pop ebx
|
||||||
|
pop ebp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
/*ULONG
|
/*ULONG
|
||||||
*FASTCALL
|
*FASTCALL
|
||||||
*ExfInterlockedAddUlong(IN PULONG Addend,
|
*ExfInterlockedAddUlong(IN PULONG Addend,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue