Map PTEs for MAP_SHARED | MAP_LOCKED files on fork
[akaros.git] / kern / arch / x86 / bitops.h
index 6dfd019..86b12ac 100644 (file)
@@ -1,5 +1,4 @@
-#ifndef _ASM_X86_BITOPS_H
-#define _ASM_X86_BITOPS_H
+#pragma once
 
 /*
  * Copyright 1992, Linus Torvalds.
@@ -8,15 +7,9 @@
  * __always_inline to avoid problems with older gcc's inlining heuristics.
  */
 
-#ifndef _LINUX_BITOPS_H
-#error only <linux/bitops.h> can be included directly
-#endif
-
-#include <linux/compiler.h>
-#include <asm/alternative.h>
-
 #define BIT_64(n)                      (U64_C(1) << (n))
-
+#define DECLARE_BITMAP(name,bits) \
+       unsigned long name[(bits+sizeof(unsigned long)*8 - 1)/(sizeof(unsigned long)*8)/*BITS_TO_LONGS(bits)*/]
 /*
  * These have to be done with inline assembly: that way the bit-setting
  * is guaranteed to be atomic. All bit operations return 0 if the bit
  */
 
 #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)
-/* Technically wrong, but this avoids compilation errors on some gcc
-   versions. */
-#define BITOP_ADDR(x) "=m" (*(volatile long *) (x))
+#error "Get a gcc newer than 4.4.0"
 #else
 #define BITOP_ADDR(x) "+m" (*(volatile long *) (x))
 #endif
 
 #define ADDR                           BITOP_ADDR(addr)
 
+#define LOCK_PREFIX "lock "
 /*
  * We do the locked ops that don't return the old value as
  * a mask operation on a byte.
@@ -64,7 +56,7 @@ set_bit(unsigned int nr, volatile unsigned long *addr)
        if (IS_IMMEDIATE(nr)) {
                asm volatile(LOCK_PREFIX "orb %1,%0"
                        : CONST_MASK_ADDR(nr, addr)
-                       : "iq" ((u8)CONST_MASK(nr))
+                       : "iq" ((uint8_t)CONST_MASK(nr))
                        : "memory");
        } else {
                asm volatile(LOCK_PREFIX "bts %1,%0"
@@ -95,14 +87,21 @@ static inline void __set_bit(int nr, volatile unsigned long *addr)
  * not contain a memory barrier, so if it is used for locking purposes,
  * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
  * in order to ensure changes are visible on other processors.
- */
+ * 
+ * Note from brho: I think the use of LOCK_PREFIX (assuming it is "lock")
+ * provides a memory barrier against hardware reordering accesses around the
+ * LOCK ("lock" serializes).  This lacks a cmb() (called a barrier() in Linux),
+ * which would prevent the compiler from reordering the instructions.  The
+ * above-mentioned smp_mb__before_clear_bit appears to be this cmb(), so it's
+ * not clear what the usage of "memory barrier" means exactly here and
+ * elsewhere in this file. */
 static __always_inline void
 clear_bit(int nr, volatile unsigned long *addr)
 {
        if (IS_IMMEDIATE(nr)) {
                asm volatile(LOCK_PREFIX "andb %1,%0"
                        : CONST_MASK_ADDR(nr, addr)
-                       : "iq" ((u8)~CONST_MASK(nr)));
+                       : "iq" ((uint8_t)~CONST_MASK(nr)));
        } else {
                asm volatile(LOCK_PREFIX "btr %1,%0"
                        : BITOP_ADDR(addr)
@@ -120,7 +119,7 @@ clear_bit(int nr, volatile unsigned long *addr)
  */
 static inline void clear_bit_unlock(unsigned nr, volatile unsigned long *addr)
 {
-       barrier();
+       cmb();
        clear_bit(nr, addr);
 }
 
@@ -143,12 +142,12 @@ static inline void __clear_bit(int nr, volatile unsigned long *addr)
  */
 static inline void __clear_bit_unlock(unsigned nr, volatile unsigned long *addr)
 {
-       barrier();
+       cmb();
        __clear_bit(nr, addr);
 }
 
-#define smp_mb__before_clear_bit()     barrier()
-#define smp_mb__after_clear_bit()      barrier()
+#define smp_mb__before_clear_bit()     cmb()
+#define smp_mb__after_clear_bit()      cmb()
 
 /**
  * __change_bit - Toggle a bit in memory
@@ -178,7 +177,7 @@ static inline void change_bit(int nr, volatile unsigned long *addr)
        if (IS_IMMEDIATE(nr)) {
                asm volatile(LOCK_PREFIX "xorb %1,%0"
                        : CONST_MASK_ADDR(nr, addr)
-                       : "iq" ((u8)CONST_MASK(nr)));
+                       : "iq" ((uint8_t)CONST_MASK(nr)));
        } else {
                asm volatile(LOCK_PREFIX "btc %1,%0"
                        : BITOP_ADDR(addr)
@@ -333,20 +332,10 @@ static inline int variable_test_bit(int nr, volatile const unsigned long *addr)
        return oldbit;
 }
 
-#if 0 /* Fool kernel-doc since it doesn't do macros yet */
-/**
- * test_bit - Determine whether a bit is set
- * @nr: bit number to test
- * @addr: Address to start counting from
- */
-static int test_bit(int nr, const volatile unsigned long *addr);
-#endif
-
-#define test_bit(nr, addr)                     \
-       (__builtin_constant_p((nr))             \
-        ? constant_test_bit((nr), (addr))      \
-        : variable_test_bit((nr), (addr)))
-
+#define test_bit(nr, addr)                      \
+        (__builtin_constant_p((nr))             \
+         ? constant_test_bit((nr), (addr))      \
+         : variable_test_bit((nr), (addr)))
 /**
  * __ffs - find first set bit in word
  * @word: The word to search
@@ -391,7 +380,6 @@ static inline unsigned long __fls(unsigned long word)
 
 #undef ADDR
 
-#ifdef __KERNEL__
 /**
  * ffs - find first set bit in word
  * @x: the word to search
@@ -407,7 +395,6 @@ static inline int ffs(int x)
 {
        int r;
 
-#ifdef CONFIG_X86_64
        /*
         * AMD64 says BSFL won't clobber the dest reg if x==0; Intel64 says the
         * dest reg is undefined if x==0, but their CPU architect says its
@@ -420,16 +407,6 @@ static inline int ffs(int x)
        asm("bsfl %1,%0"
            : "=r" (r)
            : "rm" (x), "0" (-1));
-#elif defined(CONFIG_X86_CMOV)
-       asm("bsfl %1,%0\n\t"
-           "cmovzl %2,%0"
-           : "=&r" (r) : "rm" (x), "r" (-1));
-#else
-       asm("bsfl %1,%0\n\t"
-           "jnz 1f\n\t"
-           "movl $-1,%0\n"
-           "1:" : "=r" (r) : "rm" (x));
-#endif
        return r + 1;
 }
 
@@ -448,7 +425,6 @@ static inline int fls(int x)
 {
        int r;
 
-#ifdef CONFIG_X86_64
        /*
         * AMD64 says BSRL won't clobber the dest reg if x==0; Intel64 says the
         * dest reg is undefined if x==0, but their CPU architect says its
@@ -461,16 +437,6 @@ static inline int fls(int x)
        asm("bsrl %1,%0"
            : "=r" (r)
            : "rm" (x), "0" (-1));
-#elif defined(CONFIG_X86_CMOV)
-       asm("bsrl %1,%0\n\t"
-           "cmovzl %2,%0"
-           : "=&r" (r) : "rm" (x), "rm" (-1));
-#else
-       asm("bsrl %1,%0\n\t"
-           "jnz 1f\n\t"
-           "movl $-1,%0\n"
-           "1:" : "=r" (r) : "rm" (x));
-#endif
        return r + 1;
 }
 
@@ -485,8 +451,7 @@ static inline int fls(int x)
  * set bit if value is nonzero. The last (most significant) bit is
  * at position 64.
  */
-#ifdef CONFIG_X86_64
-static __always_inline int fls64(__u64 x)
+static __always_inline int fls64(uint64_t x)
 {
        int bitpos = -1;
        /*
@@ -499,23 +464,3 @@ static __always_inline int fls64(__u64 x)
            : "rm" (x));
        return bitpos + 1;
 }
-#else
-#include <asm-generic/bitops/fls64.h>
-#endif
-
-#include <asm-generic/bitops/find.h>
-
-#include <asm-generic/bitops/sched.h>
-
-#define ARCH_HAS_FAST_MULTIPLIER 1
-
-#include <asm/arch_hweight.h>
-
-#include <asm-generic/bitops/const_hweight.h>
-
-#include <asm-generic/bitops/le.h>
-
-#include <asm-generic/bitops/ext2-atomic-setbit.h>
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_X86_BITOPS_H */