]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: introduce power 2 macros for block alignment and rounding
authorxie xingguo <xie.xingguo@zte.com.cn>
Tue, 5 Jul 2016 02:31:52 +0000 (10:31 +0800)
committerxie xingguo <xie.xingguo@zte.com.cn>
Tue, 5 Jul 2016 02:38:24 +0000 (10:38 +0800)
Macros for various sorts of alignment and rounding.
So we can get rid of the annoying division and mod operation and simplify
the blob/space access logic.

Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
src/include/intarith.h
src/test/test_intarith.cc

index 5602b9c632b5ca66125f8f24784fcd27ff9db33a..f46a1eb2fe288b70e37c24aad0f45f0912f27073 100644 (file)
 #define CEPH_INTARITH_H
 
 #ifndef MIN
-# define MIN(a,b) ((a) < (b) ? (a):(b))
+#define MIN(a,b) ((a) < (b) ? (a):(b))
 #endif
 
 #ifndef MAX
-# define MAX(a,b) ((a) > (b) ? (a):(b))
+#define MAX(a,b) ((a) > (b) ? (a):(b))
 #endif
 
 #ifndef DIV_ROUND_UP
-# define DIV_ROUND_UP(n, d)  (((n) + (d) - 1) / (d))
+#define DIV_ROUND_UP(n, d)  (((n) + (d) - 1) / (d))
 #endif
 
 #ifndef ROUND_UP_TO
-# define ROUND_UP_TO(n, d) ((n)%(d) ? ((n)+(d)-(n)%(d)) : (n))
+#define ROUND_UP_TO(n, d) ((n)%(d) ? ((n)+(d)-(n)%(d)) : (n))
 #endif
 
 #ifndef SHIFT_ROUND_UP
-# define SHIFT_ROUND_UP(x,y) (((x)+(1<<(y))-1) >> (y))
+#define SHIFT_ROUND_UP(x,y) (((x)+(1<<(y))-1) >> (y))
 #endif
 
+/*
+ * Macro to determine if value is a power of 2
+ */
+#define ISP2(x)                (((x) & ((x) - 1)) == 0)
+
+/*
+ * Macros for various sorts of alignment and rounding.  The "align" must
+ * be a power of 2.  Often times it is a block, sector, or page.
+ */
+
+/*
+ * return x rounded down to an align boundary
+ * eg, P2ALIGN(1200, 1024) == 1024 (1*align)
+ * eg, P2ALIGN(1024, 1024) == 1024 (1*align)
+ * eg, P2ALIGN(0x1234, 0x100) == 0x1200 (0x12*align)
+ * eg, P2ALIGN(0x5600, 0x100) == 0x5600 (0x56*align)
+ */
+#define P2ALIGN(x, align)              ((x) & -(align))
+
+/*
+ * return x % (mod) align
+ * eg, P2PHASE(0x1234, 0x100) == 0x34 (x-0x12*align)
+ * eg, P2PHASE(0x5600, 0x100) == 0x00 (x-0x56*align)
+ */
+#define P2PHASE(x, align)              ((x) & ((align) - 1))
+
+/*
+ * return how much space is left in this block (but if it's perfectly
+ * aligned, return 0).
+ * eg, P2NPHASE(0x1234, 0x100) == 0xcc (0x13*align-x)
+ * eg, P2NPHASE(0x5600, 0x100) == 0x00 (0x56*align-x)
+ */
+#define P2NPHASE(x, align)             (-(x) & ((align) - 1))
+
+/*
+ * return x rounded up to an align boundary
+ * eg, P2ROUNDUP(0x1234, 0x100) == 0x1300 (0x13*align)
+ * eg, P2ROUNDUP(0x5600, 0x100) == 0x5600 (0x56*align)
+ */
+#define P2ROUNDUP(x, align)            (-(-(x) & -(align)))
+
 // count trailing zeros.
 // NOTE: the builtin is nondeterministic on 0 input
 static inline unsigned ctz(unsigned v) {
index 0843469bdb92b97b131bf43e849e1f3228a572a5..ad4487a870a638c9af9f58be190f0a0446c28b79 100644 (file)
@@ -61,3 +61,22 @@ TEST(intarith, ctz) {
   ASSERT_EQ(20u, ctzll(0xffffffff00000));
   ASSERT_EQ(48u, ctzll(0xff000000000000ull));
 }
+
+TEST(intarith, p2family) {
+  ASSERT_TRUE(ISP2(0x100));
+  ASSERT_FALSE(ISP2(0x1234));
+
+  ASSERT_EQ(1024, P2ALIGN(1200, 1024));
+  ASSERT_EQ(1024, P2ALIGN(1024, 1024));
+  ASSERT_EQ(0x1200, P2ALIGN(0x1234, 0x100));
+  ASSERT_EQ(0x5600, P2ALIGN(0x5600, 0x100));
+
+  ASSERT_EQ(0x34, P2PHASE(0x1234, 0x100));
+  ASSERT_EQ(0x00, P2PHASE(0x5600, 0x100));
+
+  ASSERT_EQ(0xcc, P2NPHASE(0x1234, 0x100));
+  ASSERT_EQ(0x00, P2NPHASE(0x5600, 0x100));
+
+  ASSERT_EQ(0x1300, P2ROUNDUP(0x1234, 0x100));
+  ASSERT_EQ(0x5600, P2ROUNDUP(0x5600, 0x100));
+}