[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen master] x86/bitops: Introduce variable/constant pairs for __{set, clear, change}_bit()



commit 2b84016c59dbe9f6e42e857a5d8176fd4e52c95c
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Fri Dec 29 12:56:24 2017 +0000
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Fri Jan 12 11:35:24 2018 +0000

    x86/bitops: Introduce variable/constant pairs for __{set,clear,change}_bit()
    
    Just as with test_bit, the non-atomic set/clear/change helpers can be better
    optimised by the compiler in the case that the nr parameter is constant, and
    it often is.
    
    This results in a general replacement of `mov $imm, %reg; bt* %reg, mem` 
with
    the shorter and more simple `op $imm, mem`, also reducing register pressure.
    
    The net diffstat is:
      add/remove: 0/1 grow/shrink: 5/17 up/down: 90/-301 (-211)
    
    As a piece of minor cleanup, drop unnecessary brackets in the test_bit()
    macro, and fix the indentation.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Reviewed-by: Dario Faggioli <dfaggioli@xxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
---
 xen/include/asm-x86/bitops.h | 36 +++++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/xen/include/asm-x86/bitops.h b/xen/include/asm-x86/bitops.h
index 440abb7..e66d861 100644
--- a/xen/include/asm-x86/bitops.h
+++ b/xen/include/asm-x86/bitops.h
@@ -51,13 +51,19 @@ static inline void set_bit(int nr, volatile void *addr)
  * If it's called on the same region of memory simultaneously, the effect
  * may be that only one operation succeeds.
  */
-static inline void __set_bit(int nr, void *addr)
+static inline void variable_set_bit(int nr, void *addr)
 {
     asm volatile ( "btsl %1,%0" : "+m" (*(int *)addr) : "Ir" (nr) : "memory" );
 }
+static inline void constant_set_bit(int nr, void *addr)
+{
+    ((unsigned int *)addr)[nr >> 5] |= (1u << (nr & 31));
+}
 #define __set_bit(nr, addr) ({                          \
     if ( bitop_bad_size(addr) ) __bitop_bad_size();     \
-    __set_bit(nr, addr);                                \
+    __builtin_constant_p(nr) ?                          \
+        constant_set_bit(nr, addr) :                    \
+        variable_set_bit(nr, addr);                     \
 })
 
 /**
@@ -86,13 +92,19 @@ static inline void clear_bit(int nr, volatile void *addr)
  * If it's called on the same region of memory simultaneously, the effect
  * may be that only one operation succeeds.
  */
-static inline void __clear_bit(int nr, void *addr)
+static inline void variable_clear_bit(int nr, void *addr)
 {
     asm volatile ( "btrl %1,%0" : "+m" (*(int *)addr) : "Ir" (nr) : "memory" );
 }
+static inline void constant_clear_bit(int nr, void *addr)
+{
+    ((unsigned int *)addr)[nr >> 5] &= ~(1u << (nr & 31));
+}
 #define __clear_bit(nr, addr) ({                        \
     if ( bitop_bad_size(addr) ) __bitop_bad_size();     \
-    __clear_bit(nr, addr);                              \
+    __builtin_constant_p(nr) ?                          \
+        constant_clear_bit(nr, addr) :                  \
+        variable_clear_bit(nr, addr);                   \
 })
 
 /**
@@ -104,13 +116,19 @@ static inline void __clear_bit(int nr, void *addr)
  * If it's called on the same region of memory simultaneously, the effect
  * may be that only one operation succeeds.
  */
-static inline void __change_bit(int nr, void *addr)
+static inline void variable_change_bit(int nr, void *addr)
 {
     asm volatile ( "btcl %1,%0" : "+m" (*(int *)addr) : "Ir" (nr) : "memory" );
 }
+static inline void constant_change_bit(int nr, void *addr)
+{
+    ((unsigned int *)addr)[nr >> 5] ^= (1u << (nr & 31));
+}
 #define __change_bit(nr, addr) ({                       \
     if ( bitop_bad_size(addr) ) __bitop_bad_size();     \
-    __change_bit(nr, addr);                             \
+    __builtin_constant_p(nr) ?                          \
+        constant_change_bit(nr, addr) :                 \
+        variable_change_bit(nr, addr);                  \
 })
 
 /**
@@ -291,9 +309,9 @@ static inline int variable_test_bit(int nr, const volatile 
void *addr)
 
 #define test_bit(nr, addr) ({                           \
     if ( bitop_bad_size(addr) ) __bitop_bad_size();     \
-    (__builtin_constant_p(nr) ?                         \
-     constant_test_bit((nr),(addr)) :                   \
-     variable_test_bit((nr),(addr)));                   \
+    __builtin_constant_p(nr) ?                          \
+        constant_test_bit(nr, addr) :                   \
+        variable_test_bit(nr, addr);                    \
 })
 
 extern unsigned int __find_first_bit(
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.