aboutsummaryrefslogtreecommitdiffstats
path: root/lib/bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bitmap.c')
-rw-r--r--lib/bitmap.c80
1 files changed, 32 insertions, 48 deletions
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 324ea9eab8c1..ad161a6c82db 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -744,10 +744,10 @@ EXPORT_SYMBOL(bitmap_parselist_user);
744/** 744/**
745 * bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap 745 * bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap
746 * @buf: pointer to a bitmap 746 * @buf: pointer to a bitmap
747 * @pos: a bit position in @buf (0 <= @pos < @bits) 747 * @pos: a bit position in @buf (0 <= @pos < @nbits)
748 * @bits: number of valid bit positions in @buf 748 * @nbits: number of valid bit positions in @buf
749 * 749 *
750 * Map the bit at position @pos in @buf (of length @bits) to the 750 * Map the bit at position @pos in @buf (of length @nbits) to the
751 * ordinal of which set bit it is. If it is not set or if @pos 751 * ordinal of which set bit it is. If it is not set or if @pos
752 * is not a valid bit position, map to -1. 752 * is not a valid bit position, map to -1.
753 * 753 *
@@ -759,56 +759,40 @@ EXPORT_SYMBOL(bitmap_parselist_user);
759 * 759 *
760 * The bit positions 0 through @bits are valid positions in @buf. 760 * The bit positions 0 through @bits are valid positions in @buf.
761 */ 761 */
762static int bitmap_pos_to_ord(const unsigned long *buf, int pos, int bits) 762static int bitmap_pos_to_ord(const unsigned long *buf, unsigned int pos, unsigned int nbits)
763{ 763{
764 int i, ord; 764 if (pos >= nbits || !test_bit(pos, buf))
765
766 if (pos < 0 || pos >= bits || !test_bit(pos, buf))
767 return -1; 765 return -1;
768 766
769 i = find_first_bit(buf, bits); 767 return __bitmap_weight(buf, pos);
770 ord = 0;
771 while (i < pos) {
772 i = find_next_bit(buf, bits, i + 1);
773 ord++;
774 }
775 BUG_ON(i != pos);
776
777 return ord;
778} 768}
779 769
780/** 770/**
781 * bitmap_ord_to_pos - find position of n-th set bit in bitmap 771 * bitmap_ord_to_pos - find position of n-th set bit in bitmap
782 * @buf: pointer to bitmap 772 * @buf: pointer to bitmap
783 * @ord: ordinal bit position (n-th set bit, n >= 0) 773 * @ord: ordinal bit position (n-th set bit, n >= 0)
784 * @bits: number of valid bit positions in @buf 774 * @nbits: number of valid bit positions in @buf
785 * 775 *
786 * Map the ordinal offset of bit @ord in @buf to its position in @buf. 776 * Map the ordinal offset of bit @ord in @buf to its position in @buf.
787 * Value of @ord should be in range 0 <= @ord < weight(buf), else 777 * Value of @ord should be in range 0 <= @ord < weight(buf). If @ord
788 * results are undefined. 778 * >= weight(buf), returns @nbits.
789 * 779 *
790 * If for example, just bits 4 through 7 are set in @buf, then @ord 780 * If for example, just bits 4 through 7 are set in @buf, then @ord
791 * values 0 through 3 will get mapped to 4 through 7, respectively, 781 * values 0 through 3 will get mapped to 4 through 7, respectively,
792 * and all other @ord values return undefined values. When @ord value 3 782 * and all other @ord values returns @nbits. When @ord value 3
793 * gets mapped to (returns) @pos value 7 in this example, that means 783 * gets mapped to (returns) @pos value 7 in this example, that means
794 * that the 3rd set bit (starting with 0th) is at position 7 in @buf. 784 * that the 3rd set bit (starting with 0th) is at position 7 in @buf.
795 * 785 *
796 * The bit positions 0 through @bits are valid positions in @buf. 786 * The bit positions 0 through @nbits-1 are valid positions in @buf.
797 */ 787 */
798int bitmap_ord_to_pos(const unsigned long *buf, int ord, int bits) 788unsigned int bitmap_ord_to_pos(const unsigned long *buf, unsigned int ord, unsigned int nbits)
799{ 789{
800 int pos = 0; 790 unsigned int pos;
801
802 if (ord >= 0 && ord < bits) {
803 int i;
804 791
805 for (i = find_first_bit(buf, bits); 792 for (pos = find_first_bit(buf, nbits);
806 i < bits && ord > 0; 793 pos < nbits && ord;
807 i = find_next_bit(buf, bits, i + 1)) 794 pos = find_next_bit(buf, nbits, pos + 1))
808 ord--; 795 ord--;
809 if (i < bits && ord == 0)
810 pos = i;
811 }
812 796
813 return pos; 797 return pos;
814} 798}
@@ -819,7 +803,7 @@ int bitmap_ord_to_pos(const unsigned long *buf, int ord, int bits)
819 * @src: subset to be remapped 803 * @src: subset to be remapped
820 * @old: defines domain of map 804 * @old: defines domain of map
821 * @new: defines range of map 805 * @new: defines range of map
822 * @bits: number of bits in each of these bitmaps 806 * @nbits: number of bits in each of these bitmaps
823 * 807 *
824 * Let @old and @new define a mapping of bit positions, such that 808 * Let @old and @new define a mapping of bit positions, such that
825 * whatever position is held by the n-th set bit in @old is mapped 809 * whatever position is held by the n-th set bit in @old is mapped
@@ -847,22 +831,22 @@ int bitmap_ord_to_pos(const unsigned long *buf, int ord, int bits)
847 */ 831 */
848void bitmap_remap(unsigned long *dst, const unsigned long *src, 832void bitmap_remap(unsigned long *dst, const unsigned long *src,
849 const unsigned long *old, const unsigned long *new, 833 const unsigned long *old, const unsigned long *new,
850 int bits) 834 unsigned int nbits)
851{ 835{
852 int oldbit, w; 836 unsigned int oldbit, w;
853 837
854 if (dst == src) /* following doesn't handle inplace remaps */ 838 if (dst == src) /* following doesn't handle inplace remaps */
855 return; 839 return;
856 bitmap_zero(dst, bits); 840 bitmap_zero(dst, nbits);
857 841
858 w = bitmap_weight(new, bits); 842 w = bitmap_weight(new, nbits);
859 for_each_set_bit(oldbit, src, bits) { 843 for_each_set_bit(oldbit, src, nbits) {
860 int n = bitmap_pos_to_ord(old, oldbit, bits); 844 int n = bitmap_pos_to_ord(old, oldbit, nbits);
861 845
862 if (n < 0 || w == 0) 846 if (n < 0 || w == 0)
863 set_bit(oldbit, dst); /* identity map */ 847 set_bit(oldbit, dst); /* identity map */
864 else 848 else
865 set_bit(bitmap_ord_to_pos(new, n % w, bits), dst); 849 set_bit(bitmap_ord_to_pos(new, n % w, nbits), dst);
866 } 850 }
867} 851}
868EXPORT_SYMBOL(bitmap_remap); 852EXPORT_SYMBOL(bitmap_remap);
@@ -1006,9 +990,9 @@ EXPORT_SYMBOL(bitmap_bitremap);
1006 * All bits in @dst not set by the above rule are cleared. 990 * All bits in @dst not set by the above rule are cleared.
1007 */ 991 */
1008void bitmap_onto(unsigned long *dst, const unsigned long *orig, 992void bitmap_onto(unsigned long *dst, const unsigned long *orig,
1009 const unsigned long *relmap, int bits) 993 const unsigned long *relmap, unsigned int bits)
1010{ 994{
1011 int n, m; /* same meaning as in above comment */ 995 unsigned int n, m; /* same meaning as in above comment */
1012 996
1013 if (dst == orig) /* following doesn't handle inplace mappings */ 997 if (dst == orig) /* following doesn't handle inplace mappings */
1014 return; 998 return;
@@ -1039,22 +1023,22 @@ EXPORT_SYMBOL(bitmap_onto);
1039 * @dst: resulting smaller bitmap 1023 * @dst: resulting smaller bitmap
1040 * @orig: original larger bitmap 1024 * @orig: original larger bitmap
1041 * @sz: specified size 1025 * @sz: specified size
1042 * @bits: number of bits in each of these bitmaps 1026 * @nbits: number of bits in each of these bitmaps
1043 * 1027 *
1044 * For each bit oldbit in @orig, set bit oldbit mod @sz in @dst. 1028 * For each bit oldbit in @orig, set bit oldbit mod @sz in @dst.
1045 * Clear all other bits in @dst. See further the comment and 1029 * Clear all other bits in @dst. See further the comment and
1046 * Example [2] for bitmap_onto() for why and how to use this. 1030 * Example [2] for bitmap_onto() for why and how to use this.
1047 */ 1031 */
1048void bitmap_fold(unsigned long *dst, const unsigned long *orig, 1032void bitmap_fold(unsigned long *dst, const unsigned long *orig,
1049 int sz, int bits) 1033 unsigned int sz, unsigned int nbits)
1050{ 1034{
1051 int oldbit; 1035 unsigned int oldbit;
1052 1036
1053 if (dst == orig) /* following doesn't handle inplace mappings */ 1037 if (dst == orig) /* following doesn't handle inplace mappings */
1054 return; 1038 return;
1055 bitmap_zero(dst, bits); 1039 bitmap_zero(dst, nbits);
1056 1040
1057 for_each_set_bit(oldbit, orig, bits) 1041 for_each_set_bit(oldbit, orig, nbits)
1058 set_bit(oldbit % sz, dst); 1042 set_bit(oldbit % sz, dst);
1059} 1043}
1060EXPORT_SYMBOL(bitmap_fold); 1044EXPORT_SYMBOL(bitmap_fold);