[ros-diffs] [tkreuzer] 51748: [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 ...

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Sat May 14 19:29:45 UTC 2011


Author: tkreuzer
Date: Sat May 14 19:29:42 2011
New Revision: 51748

URL: http://svn.reactos.org/svn/reactos?rev=51748&view=rev
Log:
[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.

Modified:
    trunk/reactos/ntoskrnl/ex/i386/fastinterlck_asm.S

Modified: trunk/reactos/ntoskrnl/ex/i386/fastinterlck_asm.S
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/i386/fastinterlck_asm.S?rev=51748&r1=51747&r2=51748&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ex/i386/fastinterlck_asm.S [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ex/i386/fastinterlck_asm.S [iso-8859-1] Sat May 14 19:29:42 2011
@@ -4,8 +4,9 @@
  * FILE:            ntoskrnl/ex/i386/fastinterlck_asm.S
  * PURPOSE:         FASTCALL Interlocked Functions
  * PROGRAMMERS:     Alex Ionescu (alex at relsoft.net)
- */
- 
+ *                  Paolo Bonzini <bonzini [at] gnu [dot] org>
+ */
+
 /* INCLUDES ******************************************************************/
 
 #include <asm.inc>
@@ -31,25 +32,55 @@
  */
 PUBLIC @ExInterlockedAddLargeStatistic at 8
 @ExInterlockedAddLargeStatistic at 8:
-
-#ifdef CONFIG_SMP
-    /* Do the addition */
-    lock add [ecx], edx
-
-    /* Check for carry bit and return */
-    jb .l1
-    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 */
-    ret
+    push ebp
+    push ebx
+    mov  ebp, ecx
+
+Again:
+    /* Load comparand in eax for cmpxchg */
+    mov  eax, [ebp]
+
+    /* 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
+
+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




More information about the Ros-diffs mailing list