X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=libcfs%2Finclude%2Flibcfs%2Fuser-bitops.h;h=3e667f1005da1a782c39aa15d4a68ff42e55adec;hb=353e3c2f8d9f195c0f87a16259f22b2f84de11d4;hp=5ed4a74f94deb20663a416b4fd9313f52c1d2f9c;hpb=6869932b552ac705f411de3362f01bd50c1f6f7d;p=fs%2Flustre-release.git diff --git a/libcfs/include/libcfs/user-bitops.h b/libcfs/include/libcfs/user-bitops.h index 5ed4a74..3e667f1 100644 --- a/libcfs/include/libcfs/user-bitops.h +++ b/libcfs/include/libcfs/user-bitops.h @@ -1,6 +1,4 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * +/* * GPL HEADER START * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -26,7 +24,7 @@ * GPL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. */ /* @@ -42,9 +40,9 @@ #define __LIBCFS_USER_BITOPS_H__ /* test if bit nr is set in bitmap addr; returns previous value of bit nr */ -static __inline__ int set_bit(int nr, unsigned long * addr) +static __inline__ int cfs_test_and_set_bit(int nr, unsigned long *addr) { - long mask; + unsigned long mask; addr += nr / BITS_PER_LONG; mask = 1UL << (nr & (BITS_PER_LONG - 1)); @@ -53,10 +51,12 @@ static __inline__ int set_bit(int nr, unsigned long * addr) return nr; } +#define cfs_set_bit(n, a) cfs_test_and_set_bit(n, a) + /* clear bit nr in bitmap addr; returns previous value of bit nr*/ -static __inline__ int clear_bit(int nr, unsigned long * addr) +static __inline__ int cfs_test_and_clear_bit(int nr, unsigned long *addr) { - long mask; + unsigned long mask; addr += nr / BITS_PER_LONG; mask = 1UL << (nr & (BITS_PER_LONG - 1)); @@ -65,13 +65,55 @@ static __inline__ int clear_bit(int nr, unsigned long * addr) return nr; } -static __inline__ int test_bit(int nr, const unsigned long * addr) +#define cfs_clear_bit(n, a) cfs_test_and_clear_bit(n, a) + +static __inline__ int cfs_test_bit(int nr, const unsigned long *addr) { - return ((1UL << (nr & (BITS_PER_LONG - 1))) & ((addr)[nr / BITS_PER_LONG])) != 0; + return ((1UL << (nr & (BITS_PER_LONG - 1))) & + ((addr)[nr / BITS_PER_LONG])) != 0; } /* using binary seach */ -static __inline__ unsigned long __ffs(long data) +static __inline__ unsigned long __cfs_fls(long data) +{ + int pos = 32; + + if (!data) + return 0; + +#if BITS_PER_LONG == 64 + /* If any bit of the high 32 bits are set, shift the high + * 32 bits down and pretend like it is a 32-bit value. */ + if ((data & 0xFFFFFFFF00000000llu)) { + data >>= 32; + pos += 32; + } +#endif + + if (!(data & 0xFFFF0000u)) { + data <<= 16; + pos -= 16; + } + if (!(data & 0xFF000000u)) { + data <<= 8; + pos -= 8; + } + if (!(data & 0xF0000000u)) { + data <<= 4; + pos -= 4; + } + if (!(data & 0xC0000000u)) { + data <<= 2; + pos -= 2; + } + if (!(data & 0x80000000u)) { + data <<= 1; + pos -= 1; + } + return pos; +} + +static __inline__ unsigned long __cfs_ffs(long data) { int pos = 0; @@ -103,15 +145,17 @@ static __inline__ unsigned long __ffs(long data) return pos; } -#define __ffz(x) __ffs(~(x)) +#define __cfs_ffz(x) __cfs_ffs(~(x)) +#define __cfs_flz(x) __cfs_fls(~(x)) -unsigned long find_next_bit(unsigned long *addr, - unsigned long size, unsigned long offset); +unsigned long cfs_find_next_bit(unsigned long *addr, + unsigned long size, unsigned long offset); -unsigned long find_next_zero_bit(unsigned long *addr, - unsigned long size, unsigned long offset); +unsigned long cfs_find_next_zero_bit(unsigned long *addr, + unsigned long size, unsigned long offset); -#define find_first_bit(addr,size) (find_next_bit((addr),(size),0)) -#define find_first_zero_bit(addr,size) (find_next_zero_bit((addr),(size),0)) +#define cfs_find_first_bit(addr,size) (cfs_find_next_bit((addr),(size),0)) +#define cfs_find_first_zero_bit(addr,size) \ + (cfs_find_next_zero_bit((addr),(size),0)) #endif