OSDN Git Service

libext2fs: Add 64-bit bitops
authorValerie Aurora Henson <vaurora@redhat.com>
Mon, 1 Jun 2009 20:15:40 +0000 (16:15 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 1 Jun 2009 20:15:40 +0000 (16:15 -0400)
Signed-off-by: Valerie Aurora Henson <vaurora@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
lib/ext2fs/bitops.c
lib/ext2fs/bitops.h
lib/ext2fs/tst_bitops.c

index 485e997..36901b2 100644 (file)
@@ -76,3 +76,42 @@ void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
                com_err(0, errcode, "#%lu", arg);
 #endif
 }
+
+/*
+ * C-only 64 bit ops.
+ */
+
+int ext2fs_set_bit64(__u64 nr, void * addr)
+{
+       int             mask, retval;
+       unsigned char   *ADDR = (unsigned char *) addr;
+
+       ADDR += nr >> 3;
+       mask = 1 << (nr & 0x07);
+       retval = mask & *ADDR;
+       *ADDR |= mask;
+       return retval;
+}
+
+int ext2fs_clear_bit64(__u64 nr, void * addr)
+{
+       int             mask, retval;
+       unsigned char   *ADDR = (unsigned char *) addr;
+
+       ADDR += nr >> 3;
+       mask = 1 << (nr & 0x07);
+       retval = mask & *ADDR;
+       *ADDR &= ~mask;
+       return retval;
+}
+
+int ext2fs_test_bit64(__u64 nr, const void * addr)
+{
+       int                     mask;
+       const unsigned char     *ADDR = (const unsigned char *) addr;
+
+       ADDR += nr >> 3;
+       mask = 1 << (nr & 0x07);
+       return (mask & *ADDR);
+}
+
index 32111ba..7c3f056 100644 (file)
@@ -19,6 +19,11 @@ extern int ext2fs_clear_bit(unsigned int nr, void * addr);
 extern int ext2fs_test_bit(unsigned int nr, const void * addr);
 extern void ext2fs_fast_set_bit(unsigned int nr,void * addr);
 extern void ext2fs_fast_clear_bit(unsigned int nr, void * addr);
+extern int ext2fs_set_bit64(__u64 nr,void * addr);
+extern int ext2fs_clear_bit64(__u64 nr, void * addr);
+extern int ext2fs_test_bit64(__u64 nr, const void * addr);
+extern void ext2fs_fast_set_bit64(__u64 nr,void * addr);
+extern void ext2fs_fast_clear_bit64(__u64 nr, void * addr);
 extern __u16 ext2fs_swab16(__u16 val);
 extern __u32 ext2fs_swab32(__u32 val);
 extern __u64 ext2fs_swab64(__u64 val);
@@ -167,6 +172,23 @@ _INLINE_ void ext2fs_fast_clear_bit(unsigned int nr, void * addr)
 }
 
 
+_INLINE_ void ext2fs_fast_set_bit64(__u64 nr, void * addr)
+{
+       unsigned char   *ADDR = (unsigned char *) addr;
+
+       ADDR += nr >> 3;
+       *ADDR |= (1 << (nr & 0x07));
+}
+
+_INLINE_ void ext2fs_fast_clear_bit64(__u64 nr, void * addr)
+{
+       unsigned char   *ADDR = (unsigned char *) addr;
+
+       ADDR += nr >> 3;
+       *ADDR &= ~(1 << (nr & 0x07));
+}
+
+
 #if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
      (defined(__i386__) || defined(__i486__) || defined(__i586__)))
 
index 6febe68..0f0a425 100644 (file)
@@ -169,5 +169,125 @@ int main(int argc, char **argv)
 
        printf("ext2fs_fast_set_bit big_test successful\n");
 
+       /* Repeat foregoing tests for 64-bit bitops */
+
+       /* Test test_bit */
+       for (i=0,j=0; i < size; i++) {
+               if (ext2fs_test_bit64(i, bitarray)) {
+                       if (bits_list[j] == i) {
+                               j++;
+                       } else {
+                               printf("64-bit: Bit %d set, not expected\n",
+                                      i);
+                               exit(1);
+                       }
+               } else {
+                       if (bits_list[j] == i) {
+                               printf("64-bit: "
+                                      "Expected bit %d to be clear.\n", i);
+                               exit(1);
+                       }
+               }
+       }
+       printf("64-bit: ext2fs_test_bit appears to be correct\n");
+
+       /* Test ext2fs_set_bit */
+       memset(testarray, 0, sizeof(testarray));
+       for (i=0; bits_list[i] > 0; i++) {
+               ext2fs_set_bit64(bits_list[i], testarray);
+       }
+       if (memcmp(testarray, bitarray, sizeof(testarray)) == 0) {
+               printf("64-bit: ext2fs_set_bit test succeeded.\n");
+       } else {
+               printf("64-bit: ext2fs_set_bit test failed.\n");
+               for (i=0; i < sizeof(testarray); i++) {
+                       printf("%02x ", testarray[i]);
+               }
+               printf("\n");
+               exit(1);
+       }
+       for (i=0; bits_list[i] > 0; i++) {
+               ext2fs_clear_bit64(bits_list[i], testarray);
+       }
+       for (i=0; i < sizeof(testarray); i++) {
+               if (testarray[i]) {
+                       printf("64-bit: ext2fs_clear_bit failed, "
+                              "testarray[%d] is %d\n", i, testarray[i]);
+                       exit(1);
+               }
+       }
+       printf("64-bit: ext2fs_clear_bit test succeed.\n");
+
+       /* Do bigarray test */
+       bigarray = malloc(1 << 29);
+       if (!bigarray) {
+               fprintf(stderr, "Failed to allocate scratch memory!\n");
+               exit(1);
+       }
+
+        bigarray[BIG_TEST_BIT >> 3] = 0;
+
+       ext2fs_set_bit64(BIG_TEST_BIT, bigarray);
+       printf("64-bit: big bit number (%u) test: %d, expected %d\n",
+              BIG_TEST_BIT, bigarray[BIG_TEST_BIT >> 3],
+              (1 << (BIG_TEST_BIT & 7)));
+       if (bigarray[BIG_TEST_BIT >> 3] != (1 << (BIG_TEST_BIT & 7)))
+               exit(1);
+
+       ext2fs_clear_bit64(BIG_TEST_BIT, bigarray);
+
+       printf("64-bit: big bit number (%u) test: %d, expected 0\n",
+              BIG_TEST_BIT,
+              bigarray[BIG_TEST_BIT >> 3]);
+       if (bigarray[BIG_TEST_BIT >> 3] != 0)
+               exit(1);
+
+       printf("64-bit: ext2fs_set_bit big_test successful\n");
+
+       /* Now test ext2fs_fast_set_bit */
+       memset(testarray, 0, sizeof(testarray));
+       for (i=0; bits_list[i] > 0; i++) {
+               ext2fs_fast_set_bit64(bits_list[i], testarray);
+       }
+       if (memcmp(testarray, bitarray, sizeof(testarray)) == 0) {
+               printf("64-bit: ext2fs_fast_set_bit test succeeded.\n");
+       } else {
+               printf("64-bit: ext2fs_fast_set_bit test failed.\n");
+               for (i=0; i < sizeof(testarray); i++) {
+                       printf("%02x ", testarray[i]);
+               }
+               printf("\n");
+               exit(1);
+       }
+       for (i=0; bits_list[i] > 0; i++) {
+               ext2fs_clear_bit64(bits_list[i], testarray);
+       }
+       for (i=0; i < sizeof(testarray); i++) {
+               if (testarray[i]) {
+                       printf("64-bit: ext2fs_clear_bit failed, "
+                              "testarray[%d] is %d\n", i, testarray[i]);
+                       exit(1);
+               }
+       }
+       printf("64-bit: ext2fs_clear_bit test succeed.\n");
+
+        bigarray[BIG_TEST_BIT >> 3] = 0;
+
+       ext2fs_fast_set_bit64(BIG_TEST_BIT, bigarray);
+       printf("64-bit: big bit number (%u) test: %d, expected %d\n",
+              BIG_TEST_BIT, bigarray[BIG_TEST_BIT >> 3],
+              (1 << (BIG_TEST_BIT & 7)));
+       if (bigarray[BIG_TEST_BIT >> 3] != (1 << (BIG_TEST_BIT & 7)))
+               exit(1);
+
+       ext2fs_fast_clear_bit64(BIG_TEST_BIT, bigarray);
+
+       printf("64-bit: big bit number (%u) test: %d, expected 0\n",
+              BIG_TEST_BIT, bigarray[BIG_TEST_BIT >> 3]);
+       if (bigarray[BIG_TEST_BIT >> 3] != 0)
+               exit(1);
+
+       printf("64-bit: ext2fs_fast_set_bit big_test successful\n");
+
        exit(0);
 }