]> git.karo-electronics.de Git - linux-beck.git/blobdiff - lib/bitmap.c
lib/string.c: improve strrchr()
[linux-beck.git] / lib / bitmap.c
index 324ea9eab8c1c6f2abbe6daf546370f0cdbafa5b..a13c7f4e325a15e09307c1fd98fc230ee3dab990 100644 (file)
@@ -104,18 +104,18 @@ EXPORT_SYMBOL(__bitmap_complement);
  *   @dst : destination bitmap
  *   @src : source bitmap
  *   @shift : shift by this many bits
- *   @bits : bitmap size, in bits
+ *   @nbits : bitmap size, in bits
  *
  * Shifting right (dividing) means moving bits in the MS -> LS bit
  * direction.  Zeros are fed into the vacated MS positions and the
  * LS bits shifted off the bottom are lost.
  */
-void __bitmap_shift_right(unsigned long *dst,
-                       const unsigned long *src, int shift, int bits)
+void __bitmap_shift_right(unsigned long *dst, const unsigned long *src,
+                       unsigned shift, unsigned nbits)
 {
-       int k, lim = BITS_TO_LONGS(bits), left = bits % BITS_PER_LONG;
-       int off = shift/BITS_PER_LONG, rem = shift % BITS_PER_LONG;
-       unsigned long mask = (1UL << left) - 1;
+       unsigned k, lim = BITS_TO_LONGS(nbits);
+       unsigned off = shift/BITS_PER_LONG, rem = shift % BITS_PER_LONG;
+       unsigned long mask = BITMAP_LAST_WORD_MASK(nbits);
        for (k = 0; off + k < lim; ++k) {
                unsigned long upper, lower;
 
@@ -127,17 +127,15 @@ void __bitmap_shift_right(unsigned long *dst,
                        upper = 0;
                else {
                        upper = src[off + k + 1];
-                       if (off + k + 1 == lim - 1 && left)
+                       if (off + k + 1 == lim - 1)
                                upper &= mask;
+                       upper <<= (BITS_PER_LONG - rem);
                }
                lower = src[off + k];
-               if (left && off + k == lim - 1)
+               if (off + k == lim - 1)
                        lower &= mask;
-               dst[k] = lower >> rem;
-               if (rem)
-                       dst[k] |= upper << (BITS_PER_LONG - rem);
-               if (left && k == lim - 1)
-                       dst[k] &= mask;
+               lower >>= rem;
+               dst[k] = lower | upper;
        }
        if (off)
                memset(&dst[lim - off], 0, off*sizeof(unsigned long));
@@ -150,18 +148,19 @@ EXPORT_SYMBOL(__bitmap_shift_right);
  *   @dst : destination bitmap
  *   @src : source bitmap
  *   @shift : shift by this many bits
- *   @bits : bitmap size, in bits
+ *   @nbits : bitmap size, in bits
  *
  * Shifting left (multiplying) means moving bits in the LS -> MS
  * direction.  Zeros are fed into the vacated LS bit positions
  * and those MS bits shifted off the top are lost.
  */
 
-void __bitmap_shift_left(unsigned long *dst,
-                       const unsigned long *src, int shift, int bits)
+void __bitmap_shift_left(unsigned long *dst, const unsigned long *src,
+                       unsigned int shift, unsigned int nbits)
 {
-       int k, lim = BITS_TO_LONGS(bits), left = bits % BITS_PER_LONG;
-       int off = shift/BITS_PER_LONG, rem = shift % BITS_PER_LONG;
+       int k;
+       unsigned int lim = BITS_TO_LONGS(nbits);
+       unsigned int off = shift/BITS_PER_LONG, rem = shift % BITS_PER_LONG;
        for (k = lim - off - 1; k >= 0; --k) {
                unsigned long upper, lower;
 
@@ -170,17 +169,11 @@ void __bitmap_shift_left(unsigned long *dst,
                 * word below and make them the bottom rem bits of result.
                 */
                if (rem && k > 0)
-                       lower = src[k - 1];
+                       lower = src[k - 1] >> (BITS_PER_LONG - rem);
                else
                        lower = 0;
-               upper = src[k];
-               if (left && k == lim - 1)
-                       upper &= (1UL << left) - 1;
-               dst[k + off] = upper << rem;
-               if (rem)
-                       dst[k + off] |= lower >> (BITS_PER_LONG - rem);
-               if (left && k + off == lim - 1)
-                       dst[k + off] &= (1UL << left) - 1;
+               upper = src[k] << rem;
+               dst[k + off] = lower | upper;
        }
        if (off)
                memset(dst, 0, off*sizeof(unsigned long));
@@ -744,10 +737,10 @@ EXPORT_SYMBOL(bitmap_parselist_user);
 /**
  * bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap
  *     @buf: pointer to a bitmap
- *     @pos: a bit position in @buf (0 <= @pos < @bits)
- *     @bits: number of valid bit positions in @buf
+ *     @pos: a bit position in @buf (0 <= @pos < @nbits)
+ *     @nbits: number of valid bit positions in @buf
  *
- * Map the bit at position @pos in @buf (of length @bits) to the
+ * Map the bit at position @pos in @buf (of length @nbits) to the
  * ordinal of which set bit it is.  If it is not set or if @pos
  * is not a valid bit position, map to -1.
  *
@@ -759,56 +752,40 @@ EXPORT_SYMBOL(bitmap_parselist_user);
  *
  * The bit positions 0 through @bits are valid positions in @buf.
  */
-static int bitmap_pos_to_ord(const unsigned long *buf, int pos, int bits)
+static int bitmap_pos_to_ord(const unsigned long *buf, unsigned int pos, unsigned int nbits)
 {
-       int i, ord;
-
-       if (pos < 0 || pos >= bits || !test_bit(pos, buf))
+       if (pos >= nbits || !test_bit(pos, buf))
                return -1;
 
-       i = find_first_bit(buf, bits);
-       ord = 0;
-       while (i < pos) {
-               i = find_next_bit(buf, bits, i + 1);
-               ord++;
-       }
-       BUG_ON(i != pos);
-
-       return ord;
+       return __bitmap_weight(buf, pos);
 }
 
 /**
  * bitmap_ord_to_pos - find position of n-th set bit in bitmap
  *     @buf: pointer to bitmap
  *     @ord: ordinal bit position (n-th set bit, n >= 0)
- *     @bits: number of valid bit positions in @buf
+ *     @nbits: number of valid bit positions in @buf
  *
  * Map the ordinal offset of bit @ord in @buf to its position in @buf.
- * Value of @ord should be in range 0 <= @ord < weight(buf), else
- * results are undefined.
+ * Value of @ord should be in range 0 <= @ord < weight(buf). If @ord
+ * >= weight(buf), returns @nbits.
  *
  * If for example, just bits 4 through 7 are set in @buf, then @ord
  * values 0 through 3 will get mapped to 4 through 7, respectively,
- * and all other @ord values return undefined values.  When @ord value 3
+ * and all other @ord values returns @nbits.  When @ord value 3
  * gets mapped to (returns) @pos value 7 in this example, that means
  * that the 3rd set bit (starting with 0th) is at position 7 in @buf.
  *
- * The bit positions 0 through @bits are valid positions in @buf.
+ * The bit positions 0 through @nbits-1 are valid positions in @buf.
  */
-int bitmap_ord_to_pos(const unsigned long *buf, int ord, int bits)
+unsigned int bitmap_ord_to_pos(const unsigned long *buf, unsigned int ord, unsigned int nbits)
 {
-       int pos = 0;
-
-       if (ord >= 0 && ord < bits) {
-               int i;
+       unsigned int pos;
 
-               for (i = find_first_bit(buf, bits);
-                    i < bits && ord > 0;
-                    i = find_next_bit(buf, bits, i + 1))
-                       ord--;
-               if (i < bits && ord == 0)
-                       pos = i;
-       }
+       for (pos = find_first_bit(buf, nbits);
+            pos < nbits && ord;
+            pos = find_next_bit(buf, nbits, pos + 1))
+               ord--;
 
        return pos;
 }
@@ -819,7 +796,7 @@ int bitmap_ord_to_pos(const unsigned long *buf, int ord, int bits)
  *     @src: subset to be remapped
  *     @old: defines domain of map
  *     @new: defines range of map
- *     @bits: number of bits in each of these bitmaps
+ *     @nbits: number of bits in each of these bitmaps
  *
  * Let @old and @new define a mapping of bit positions, such that
  * whatever position is held by the n-th set bit in @old is mapped
@@ -847,22 +824,22 @@ int bitmap_ord_to_pos(const unsigned long *buf, int ord, int bits)
  */
 void bitmap_remap(unsigned long *dst, const unsigned long *src,
                const unsigned long *old, const unsigned long *new,
-               int bits)
+               unsigned int nbits)
 {
-       int oldbit, w;
+       unsigned int oldbit, w;
 
        if (dst == src)         /* following doesn't handle inplace remaps */
                return;
-       bitmap_zero(dst, bits);
+       bitmap_zero(dst, nbits);
 
-       w = bitmap_weight(new, bits);
-       for_each_set_bit(oldbit, src, bits) {
-               int n = bitmap_pos_to_ord(old, oldbit, bits);
+       w = bitmap_weight(new, nbits);
+       for_each_set_bit(oldbit, src, nbits) {
+               int n = bitmap_pos_to_ord(old, oldbit, nbits);
 
                if (n < 0 || w == 0)
                        set_bit(oldbit, dst);   /* identity map */
                else
-                       set_bit(bitmap_ord_to_pos(new, n % w, bits), dst);
+                       set_bit(bitmap_ord_to_pos(new, n % w, nbits), dst);
        }
 }
 EXPORT_SYMBOL(bitmap_remap);
@@ -1006,9 +983,9 @@ EXPORT_SYMBOL(bitmap_bitremap);
  * All bits in @dst not set by the above rule are cleared.
  */
 void bitmap_onto(unsigned long *dst, const unsigned long *orig,
-                       const unsigned long *relmap, int bits)
+                       const unsigned long *relmap, unsigned int bits)
 {
-       int n, m;               /* same meaning as in above comment */
+       unsigned int n, m;      /* same meaning as in above comment */
 
        if (dst == orig)        /* following doesn't handle inplace mappings */
                return;
@@ -1039,22 +1016,22 @@ EXPORT_SYMBOL(bitmap_onto);
  *     @dst: resulting smaller bitmap
  *     @orig: original larger bitmap
  *     @sz: specified size
- *     @bits: number of bits in each of these bitmaps
+ *     @nbits: number of bits in each of these bitmaps
  *
  * For each bit oldbit in @orig, set bit oldbit mod @sz in @dst.
  * Clear all other bits in @dst.  See further the comment and
  * Example [2] for bitmap_onto() for why and how to use this.
  */
 void bitmap_fold(unsigned long *dst, const unsigned long *orig,
-                       int sz, int bits)
+                       unsigned int sz, unsigned int nbits)
 {
-       int oldbit;
+       unsigned int oldbit;
 
        if (dst == orig)        /* following doesn't handle inplace mappings */
                return;
-       bitmap_zero(dst, bits);
+       bitmap_zero(dst, nbits);
 
-       for_each_set_bit(oldbit, orig, bits)
+       for_each_set_bit(oldbit, orig, nbits)
                set_bit(oldbit % sz, dst);
 }
 EXPORT_SYMBOL(bitmap_fold);
@@ -1207,16 +1184,17 @@ EXPORT_SYMBOL(bitmap_allocate_region);
  *
  * Require nbits % BITS_PER_LONG == 0.
  */
-void bitmap_copy_le(void *dst, const unsigned long *src, int nbits)
+#ifdef __BIG_ENDIAN
+void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int nbits)
 {
-       unsigned long *d = dst;
-       int i;
+       unsigned int i;
 
        for (i = 0; i < nbits/BITS_PER_LONG; i++) {
                if (BITS_PER_LONG == 64)
-                       d[i] = cpu_to_le64(src[i]);
+                       dst[i] = cpu_to_le64(src[i]);
                else
-                       d[i] = cpu_to_le32(src[i]);
+                       dst[i] = cpu_to_le32(src[i]);
        }
 }
 EXPORT_SYMBOL(bitmap_copy_le);
+#endif