From e12ea189927e5e7757f02a7de3e680905a568e60 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sat, 14 May 2011 19:29:42 +0000 Subject: [PATCH] [NTOSKRNL] Patch by Paolo Bonzini Fix implementation of ExInterlockedAddLargeStatistic The old version wasn't really atomic. See issue #6223 for more details. svn path=/trunk/; revision=51748 --- reactos/ntoskrnl/ex/i386/fastinterlck_asm.S | 61 ++++++++++++++++----- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/reactos/ntoskrnl/ex/i386/fastinterlck_asm.S b/reactos/ntoskrnl/ex/i386/fastinterlck_asm.S index 566f37f5a0c..3acb19b18a9 100644 --- a/reactos/ntoskrnl/ex/i386/fastinterlck_asm.S +++ b/reactos/ntoskrnl/ex/i386/fastinterlck_asm.S @@ -4,8 +4,9 @@ * FILE: ntoskrnl/ex/i386/fastinterlck_asm.S * PURPOSE: FASTCALL Interlocked Functions * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + * Paolo Bonzini */ - + /* INCLUDES ******************************************************************/ #include @@ -31,26 +32,56 @@ */ PUBLIC @ExInterlockedAddLargeStatistic@8 @ExInterlockedAddLargeStatistic@8: + push ebp + push ebx + mov ebp, ecx -#ifdef CONFIG_SMP - /* Do the addition */ - lock add [ecx], edx +Again: + /* Load comparand in eax for cmpxchg */ + mov eax, [ebp] - /* Check for carry bit and return */ - jb .l1 + /* Compute low word of the result in ebx */ + 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 -.l1: - /* Add carry */ - lock adc dword ptr [ecx+4], 0 -#else - /* Do the addition and add the carry */ - add dword ptr [ecx], edx - adc dword ptr [ecx+4], 0 -#endif - /* Return */ +Slow: + /* Save increment across cmpxchg8b */ + push edx + + /* Finish loading comparand in edx:eax */ + mov edx, [ebp+4] + + /* Result in ecx:ebx (we know there's carry) */ + 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 + /*ULONG *FASTCALL *ExfInterlockedAddUlong(IN PULONG Addend,