Subversion Repositories Kolibri OS

Rev

Rev 5270 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5270 Rev 6082
Line 39... Line 39...
39
 * endian architectures.  See the big-endian headers
39
 * endian architectures.  See the big-endian headers
40
 * include/asm-ppc64/bitops.h and include/asm-s390/bitops.h
40
 * include/asm-ppc64/bitops.h and include/asm-s390/bitops.h
41
 * for the best explanations of this ordering.
41
 * for the best explanations of this ordering.
42
 */
42
 */
Line 43... Line -...
43
 
-
 
44
int __bitmap_empty(const unsigned long *bitmap, unsigned int bits)
-
 
45
{
-
 
46
	unsigned int k, lim = bits/BITS_PER_LONG;
-
 
47
	for (k = 0; k < lim; ++k)
-
 
48
		if (bitmap[k])
-
 
49
			return 0;
-
 
50
 
-
 
51
	if (bits % BITS_PER_LONG)
-
 
52
		if (bitmap[k] & BITMAP_LAST_WORD_MASK(bits))
-
 
53
			return 0;
-
 
54
 
-
 
55
	return 1;
-
 
56
}
-
 
57
EXPORT_SYMBOL(__bitmap_empty);
-
 
58
 
-
 
59
int __bitmap_full(const unsigned long *bitmap, unsigned int bits)
-
 
60
{
-
 
61
	unsigned int k, lim = bits/BITS_PER_LONG;
-
 
62
	for (k = 0; k < lim; ++k)
-
 
63
		if (~bitmap[k])
-
 
64
			return 0;
-
 
65
 
-
 
66
	if (bits % BITS_PER_LONG)
-
 
67
		if (~bitmap[k] & BITMAP_LAST_WORD_MASK(bits))
-
 
68
			return 0;
-
 
69
 
-
 
70
	return 1;
-
 
71
}
-
 
72
EXPORT_SYMBOL(__bitmap_full);
-
 
73
 
43
 
74
int __bitmap_equal(const unsigned long *bitmap1,
44
int __bitmap_equal(const unsigned long *bitmap1,
75
		const unsigned long *bitmap2, unsigned int bits)
45
		const unsigned long *bitmap2, unsigned int bits)
76
{
46
{
77
	unsigned int k, lim = bits/BITS_PER_LONG;
47
	unsigned int k, lim = bits/BITS_PER_LONG;
Line 101... Line 71...
101
/**
71
/**
102
 * __bitmap_shift_right - logical right shift of the bits in a bitmap
72
 * __bitmap_shift_right - logical right shift of the bits in a bitmap
103
 *   @dst : destination bitmap
73
 *   @dst : destination bitmap
104
 *   @src : source bitmap
74
 *   @src : source bitmap
105
 *   @shift : shift by this many bits
75
 *   @shift : shift by this many bits
106
 *   @bits : bitmap size, in bits
76
 *   @nbits : bitmap size, in bits
107
 *
77
 *
108
 * Shifting right (dividing) means moving bits in the MS -> LS bit
78
 * Shifting right (dividing) means moving bits in the MS -> LS bit
109
 * direction.  Zeros are fed into the vacated MS positions and the
79
 * direction.  Zeros are fed into the vacated MS positions and the
110
 * LS bits shifted off the bottom are lost.
80
 * LS bits shifted off the bottom are lost.
111
 */
81
 */
112
void __bitmap_shift_right(unsigned long *dst,
82
void __bitmap_shift_right(unsigned long *dst, const unsigned long *src,
113
			const unsigned long *src, int shift, int bits)
83
			unsigned shift, unsigned nbits)
114
{
84
{
115
	int k, lim = BITS_TO_LONGS(bits), left = bits % BITS_PER_LONG;
85
	unsigned k, lim = BITS_TO_LONGS(nbits);
116
	int off = shift/BITS_PER_LONG, rem = shift % BITS_PER_LONG;
86
	unsigned off = shift/BITS_PER_LONG, rem = shift % BITS_PER_LONG;
117
	unsigned long mask = (1UL << left) - 1;
87
	unsigned long mask = BITMAP_LAST_WORD_MASK(nbits);
118
	for (k = 0; off + k < lim; ++k) {
88
	for (k = 0; off + k < lim; ++k) {
119
		unsigned long upper, lower;
89
		unsigned long upper, lower;
Line 120... Line 90...
120
 
90
 
121
		/*
91
		/*
Line 124... Line 94...
124
		 */
94
		 */
125
		if (!rem || off + k + 1 >= lim)
95
		if (!rem || off + k + 1 >= lim)
126
			upper = 0;
96
			upper = 0;
127
		else {
97
		else {
128
			upper = src[off + k + 1];
98
			upper = src[off + k + 1];
129
			if (off + k + 1 == lim - 1 && left)
99
			if (off + k + 1 == lim - 1)
130
				upper &= mask;
100
				upper &= mask;
-
 
101
			upper <<= (BITS_PER_LONG - rem);
131
		}
102
		}
132
		lower = src[off + k];
103
		lower = src[off + k];
133
		if (left && off + k == lim - 1)
104
		if (off + k == lim - 1)
134
			lower &= mask;
105
			lower &= mask;
135
		dst[k] = lower >> rem;
106
		lower >>= rem;
136
		if (rem)
-
 
137
			dst[k] |= upper << (BITS_PER_LONG - rem);
-
 
138
		if (left && k == lim - 1)
-
 
139
			dst[k] &= mask;
107
		dst[k] = lower | upper;
140
	}
108
	}
141
	if (off)
109
	if (off)
142
		memset(&dst[lim - off], 0, off*sizeof(unsigned long));
110
		memset(&dst[lim - off], 0, off*sizeof(unsigned long));
143
}
111
}
144
EXPORT_SYMBOL(__bitmap_shift_right);
112
EXPORT_SYMBOL(__bitmap_shift_right);
Line 147... Line 115...
147
/**
115
/**
148
 * __bitmap_shift_left - logical left shift of the bits in a bitmap
116
 * __bitmap_shift_left - logical left shift of the bits in a bitmap
149
 *   @dst : destination bitmap
117
 *   @dst : destination bitmap
150
 *   @src : source bitmap
118
 *   @src : source bitmap
151
 *   @shift : shift by this many bits
119
 *   @shift : shift by this many bits
152
 *   @bits : bitmap size, in bits
120
 *   @nbits : bitmap size, in bits
153
 *
121
 *
154
 * Shifting left (multiplying) means moving bits in the LS -> MS
122
 * Shifting left (multiplying) means moving bits in the LS -> MS
155
 * direction.  Zeros are fed into the vacated LS bit positions
123
 * direction.  Zeros are fed into the vacated LS bit positions
156
 * and those MS bits shifted off the top are lost.
124
 * and those MS bits shifted off the top are lost.
157
 */
125
 */
Line 158... Line 126...
158
 
126
 
159
void __bitmap_shift_left(unsigned long *dst,
127
void __bitmap_shift_left(unsigned long *dst, const unsigned long *src,
160
			const unsigned long *src, int shift, int bits)
128
			unsigned int shift, unsigned int nbits)
-
 
129
{
161
{
130
	int k;
162
	int k, lim = BITS_TO_LONGS(bits), left = bits % BITS_PER_LONG;
131
	unsigned int lim = BITS_TO_LONGS(nbits);
163
	int off = shift/BITS_PER_LONG, rem = shift % BITS_PER_LONG;
132
	unsigned int off = shift/BITS_PER_LONG, rem = shift % BITS_PER_LONG;
164
	for (k = lim - off - 1; k >= 0; --k) {
133
	for (k = lim - off - 1; k >= 0; --k) {
Line 165... Line 134...
165
		unsigned long upper, lower;
134
		unsigned long upper, lower;
166
 
135
 
167
		/*
136
		/*
168
		 * If shift is not word aligned, take upper rem bits of
137
		 * If shift is not word aligned, take upper rem bits of
169
		 * word below and make them the bottom rem bits of result.
138
		 * word below and make them the bottom rem bits of result.
170
		 */
139
		 */
171
		if (rem && k > 0)
140
		if (rem && k > 0)
172
			lower = src[k - 1];
141
			lower = src[k - 1] >> (BITS_PER_LONG - rem);
173
		else
142
		else
174
			lower = 0;
-
 
175
		upper = src[k];
-
 
176
		if (left && k == lim - 1)
143
			lower = 0;
177
			upper &= (1UL << left) - 1;
-
 
178
		dst[k + off] = upper << rem;
-
 
179
		if (rem)
-
 
180
			dst[k + off] |= lower >> (BITS_PER_LONG - rem);
-
 
181
		if (left && k + off == lim - 1)
144
		upper = src[k] << rem;
182
			dst[k + off] &= (1UL << left) - 1;
145
		dst[k + off] = lower | upper;
183
	}
146
	}
184
	if (off)
147
	if (off)
185
		memset(dst, 0, off*sizeof(unsigned long));
148
		memset(dst, 0, off*sizeof(unsigned long));
Line 380... Line 343...
380
 
343
 
381
 
344
 
382
/**
345
/**
383
 * bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap
346
 * bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap
384
 *	@buf: pointer to a bitmap
347
 *	@buf: pointer to a bitmap
385
 *	@pos: a bit position in @buf (0 <= @pos < @bits)
348
 *	@pos: a bit position in @buf (0 <= @pos < @nbits)
386
 *	@bits: number of valid bit positions in @buf
349
 *	@nbits: number of valid bit positions in @buf
387
 *
350
 *
388
 * Map the bit at position @pos in @buf (of length @bits) to the
351
 * Map the bit at position @pos in @buf (of length @nbits) to the
389
 * ordinal of which set bit it is.  If it is not set or if @pos
352
 * ordinal of which set bit it is.  If it is not set or if @pos
390
 * is not a valid bit position, map to -1.
353
 * is not a valid bit position, map to -1.
391
 *
354
 *
Line 395... Line 358...
395
 * gets mapped to (returns) @ord value 3 in this example, that means
358
 * gets mapped to (returns) @ord value 3 in this example, that means
396
 * that bit 7 is the 3rd (starting with 0th) set bit in @buf.
359
 * that bit 7 is the 3rd (starting with 0th) set bit in @buf.
397
 *
360
 *
398
 * The bit positions 0 through @bits are valid positions in @buf.
361
 * The bit positions 0 through @bits are valid positions in @buf.
399
 */
362
 */
400
static int bitmap_pos_to_ord(const unsigned long *buf, int pos, int bits)
363
static int bitmap_pos_to_ord(const unsigned long *buf, unsigned int pos, unsigned int nbits)
401
{
364
{
402
	int i, ord;
-
 
403
 
-
 
404
	if (pos < 0 || pos >= bits || !test_bit(pos, buf))
365
	if (pos >= nbits || !test_bit(pos, buf))
405
		return -1;
366
		return -1;
Line 406... Line 367...
406
 
367
 
407
	i = find_first_bit(buf, bits);
-
 
408
	ord = 0;
-
 
409
	while (i < pos) {
-
 
410
		i = find_next_bit(buf, bits, i + 1);
-
 
411
	     	ord++;
-
 
412
	}
-
 
413
	BUG_ON(i != pos);
-
 
414
 
-
 
415
	return ord;
368
	return __bitmap_weight(buf, pos);
Line 416... Line 369...
416
}
369
}
417
 
370
 
418
/**
371
/**
419
 * bitmap_ord_to_pos - find position of n-th set bit in bitmap
372
 * bitmap_ord_to_pos - find position of n-th set bit in bitmap
420
 *	@buf: pointer to bitmap
373
 *	@buf: pointer to bitmap
421
 *	@ord: ordinal bit position (n-th set bit, n >= 0)
374
 *	@ord: ordinal bit position (n-th set bit, n >= 0)
422
 *	@bits: number of valid bit positions in @buf
375
 *	@nbits: number of valid bit positions in @buf
423
 *
376
 *
424
 * Map the ordinal offset of bit @ord in @buf to its position in @buf.
377
 * Map the ordinal offset of bit @ord in @buf to its position in @buf.
425
 * Value of @ord should be in range 0 <= @ord < weight(buf), else
378
 * Value of @ord should be in range 0 <= @ord < weight(buf). If @ord
426
 * results are undefined.
379
 * >= weight(buf), returns @nbits.
427
 *
380
 *
428
 * If for example, just bits 4 through 7 are set in @buf, then @ord
381
 * If for example, just bits 4 through 7 are set in @buf, then @ord
429
 * values 0 through 3 will get mapped to 4 through 7, respectively,
382
 * values 0 through 3 will get mapped to 4 through 7, respectively,
430
 * and all other @ord values return undefined values.  When @ord value 3
383
 * and all other @ord values returns @nbits.  When @ord value 3
431
 * gets mapped to (returns) @pos value 7 in this example, that means
384
 * gets mapped to (returns) @pos value 7 in this example, that means
432
 * that the 3rd set bit (starting with 0th) is at position 7 in @buf.
385
 * that the 3rd set bit (starting with 0th) is at position 7 in @buf.
433
 *
386
 *
434
 * The bit positions 0 through @bits are valid positions in @buf.
387
 * The bit positions 0 through @nbits-1 are valid positions in @buf.
435
 */
388
 */
436
int bitmap_ord_to_pos(const unsigned long *buf, int ord, int bits)
389
unsigned int bitmap_ord_to_pos(const unsigned long *buf, unsigned int ord, unsigned int nbits)
437
{
-
 
438
	int pos = 0;
-
 
439
 
-
 
Line 440... Line 390...
440
	if (ord >= 0 && ord < bits) {
390
{
441
		int i;
391
	unsigned int pos;
442
 
392
 
443
		for (i = find_first_bit(buf, bits);
393
	for (pos = find_first_bit(buf, nbits);
444
		     i < bits && ord > 0;
-
 
445
		     i = find_next_bit(buf, bits, i + 1))
-
 
446
	     		ord--;
-
 
Line 447... Line 394...
447
		if (i < bits && ord == 0)
394
	     pos < nbits && ord;
448
			pos = i;
395
	     pos = find_next_bit(buf, nbits, pos + 1))
Line 449... Line 396...
449
	}
396
	     		ord--;
450
 
397
 
451
	return pos;
398
	return pos;
452
}
399
}
453
 
400
 
454
/**
401
/**
455
 * bitmap_remap - Apply map defined by a pair of bitmaps to another bitmap
402
 * bitmap_remap - Apply map defined by a pair of bitmaps to another bitmap
456
 *	@dst: remapped result
403
 *	@dst: remapped result
457
 *	@src: subset to be remapped
404
 *	@src: subset to be remapped
458
 *	@old: defines domain of map
405
 *	@old: defines domain of map
459
 *	@new: defines range of map
406
 *	@new: defines range of map
460
 *	@bits: number of bits in each of these bitmaps
407
 *	@nbits: number of bits in each of these bitmaps
Line 483... Line 430...
483
 * with bits 1, 5 and 7 set, then @dst should leave with bits 1,
430
 * with bits 1, 5 and 7 set, then @dst should leave with bits 1,
484
 * 13 and 15 set.
431
 * 13 and 15 set.
485
 */
432
 */
486
void bitmap_remap(unsigned long *dst, const unsigned long *src,
433
void bitmap_remap(unsigned long *dst, const unsigned long *src,
487
		const unsigned long *old, const unsigned long *new,
434
		const unsigned long *old, const unsigned long *new,
488
		int bits)
435
		unsigned int nbits)
489
{
436
{
490
	int oldbit, w;
437
	unsigned int oldbit, w;
Line 491... Line 438...
491
 
438
 
492
	if (dst == src)		/* following doesn't handle inplace remaps */
439
	if (dst == src)		/* following doesn't handle inplace remaps */
493
		return;
440
		return;
Line 494... Line 441...
494
	bitmap_zero(dst, bits);
441
	bitmap_zero(dst, nbits);
495
 
442
 
496
	w = bitmap_weight(new, bits);
443
	w = bitmap_weight(new, nbits);
Line 497... Line 444...
497
	for_each_set_bit(oldbit, src, bits) {
444
	for_each_set_bit(oldbit, src, nbits) {
498
	     	int n = bitmap_pos_to_ord(old, oldbit, bits);
445
		int n = bitmap_pos_to_ord(old, oldbit, nbits);
499
 
446
 
500
		if (n < 0 || w == 0)
447
		if (n < 0 || w == 0)
501
			set_bit(oldbit, dst);	/* identity map */
448
			set_bit(oldbit, dst);	/* identity map */
502
		else
449
		else
503
			set_bit(bitmap_ord_to_pos(new, n % w, bits), dst);
450
			set_bit(bitmap_ord_to_pos(new, n % w, nbits), dst);
Line 504... Line 451...
504
	}
451
	}
Line 555... Line 502...
555
 * the n-th bit of @relmap is also the m-th _set_ bit of @relmap.
502
 * the n-th bit of @relmap is also the m-th _set_ bit of @relmap.
556
 * (If you understood the previous sentence the first time your
503
 * (If you understood the previous sentence the first time your
557
 * read it, you're overqualified for your current job.)
504
 * read it, you're overqualified for your current job.)
558
 *
505
 *
559
 * In other words, @orig is mapped onto (surjectively) @dst,
506
 * In other words, @orig is mapped onto (surjectively) @dst,
560
 * using the the map {  | the n-th bit of @relmap is the
507
 * using the map {  | the n-th bit of @relmap is the
561
 * m-th set bit of @relmap }.
508
 * m-th set bit of @relmap }.
562
 *
509
 *
563
 * Any set bits in @orig above bit number W, where W is the
510
 * Any set bits in @orig above bit number W, where W is the
564
 * weight of (number of set bits in) @relmap are mapped nowhere.
511
 * weight of (number of set bits in) @relmap are mapped nowhere.
565
 * In particular, if for all bits m set in @orig, m >= W, then
512
 * In particular, if for all bits m set in @orig, m >= W, then
Line 642... Line 589...
642
 * once again be returned empty.
589
 * once again be returned empty.
643
 *
590
 *
644
 * All bits in @dst not set by the above rule are cleared.
591
 * All bits in @dst not set by the above rule are cleared.
645
 */
592
 */
646
void bitmap_onto(unsigned long *dst, const unsigned long *orig,
593
void bitmap_onto(unsigned long *dst, const unsigned long *orig,
647
			const unsigned long *relmap, int bits)
594
			const unsigned long *relmap, unsigned int bits)
648
{
595
{
649
	int n, m;       	/* same meaning as in above comment */
596
	unsigned int n, m;	/* same meaning as in above comment */
Line 650... Line 597...
650
 
597
 
651
	if (dst == orig)	/* following doesn't handle inplace mappings */
598
	if (dst == orig)	/* following doesn't handle inplace mappings */
652
		return;
599
		return;
Line 675... Line 622...
675
/**
622
/**
676
 * bitmap_fold - fold larger bitmap into smaller, modulo specified size
623
 * bitmap_fold - fold larger bitmap into smaller, modulo specified size
677
 *	@dst: resulting smaller bitmap
624
 *	@dst: resulting smaller bitmap
678
 *	@orig: original larger bitmap
625
 *	@orig: original larger bitmap
679
 *	@sz: specified size
626
 *	@sz: specified size
680
 *	@bits: number of bits in each of these bitmaps
627
 *	@nbits: number of bits in each of these bitmaps
681
 *
628
 *
682
 * For each bit oldbit in @orig, set bit oldbit mod @sz in @dst.
629
 * For each bit oldbit in @orig, set bit oldbit mod @sz in @dst.
683
 * Clear all other bits in @dst.  See further the comment and
630
 * Clear all other bits in @dst.  See further the comment and
684
 * Example [2] for bitmap_onto() for why and how to use this.
631
 * Example [2] for bitmap_onto() for why and how to use this.
685
 */
632
 */
686
void bitmap_fold(unsigned long *dst, const unsigned long *orig,
633
void bitmap_fold(unsigned long *dst, const unsigned long *orig,
687
			int sz, int bits)
634
			unsigned int sz, unsigned int nbits)
688
{
635
{
689
	int oldbit;
636
	unsigned int oldbit;
Line 690... Line 637...
690
 
637
 
691
	if (dst == orig)	/* following doesn't handle inplace mappings */
638
	if (dst == orig)	/* following doesn't handle inplace mappings */
692
		return;
639
		return;
Line 693... Line 640...
693
	bitmap_zero(dst, bits);
640
	bitmap_zero(dst, nbits);
694
 
641
 
695
	for_each_set_bit(oldbit, orig, bits)
642
	for_each_set_bit(oldbit, orig, nbits)
696
		set_bit(oldbit % sz, dst);
643
		set_bit(oldbit % sz, dst);
Line 697... Line 644...
697
}
644
}
Line 843... Line 790...
843
 * @src:   bitmap to copy
790
 * @src:   bitmap to copy
844
 * @nbits: number of bits in the bitmap
791
 * @nbits: number of bits in the bitmap
845
 *
792
 *
846
 * Require nbits % BITS_PER_LONG == 0.
793
 * Require nbits % BITS_PER_LONG == 0.
847
 */
794
 */
-
 
795
#ifdef __BIG_ENDIAN
848
void bitmap_copy_le(void *dst, const unsigned long *src, int nbits)
796
void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int nbits)
849
{
797
{
850
	unsigned long *d = dst;
798
	unsigned int i;
851
	int i;
-
 
Line 852... Line 799...
852
 
799
 
853
	for (i = 0; i < nbits/BITS_PER_LONG; i++) {
800
	for (i = 0; i < nbits/BITS_PER_LONG; i++) {
854
		if (BITS_PER_LONG == 64)
801
		if (BITS_PER_LONG == 64)
855
			d[i] = cpu_to_le64(src[i]);
802
			dst[i] = cpu_to_le64(src[i]);
856
		else
803
		else
857
			d[i] = cpu_to_le32(src[i]);
804
			dst[i] = cpu_to_le32(src[i]);
858
	}
805
	}
859
}
806
}
-
 
807
EXPORT_SYMBOL(bitmap_copy_le);