Subversion Repositories Kolibri OS

Rev

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

Rev 3391 Rev 5056
Line 1... Line 1...
1
/*
1
/*
2
 * lib/bitmap.c
2
 * lib/bitmap.c
3
 * Helper functions for bitmap.h.
3
 * Helper functions for bitmap.h.
4
 *
4
 *
5
 * Tlhis source code is licensed under the GNU General Public License,
5
 * This source code is licensed under the GNU General Public License,
6
 * Version 2.  See the file COPYING for more details.
6
 * Version 2.  See the file COPYING for more details.
7
 */
7
 */
8
#include 
8
#include 
9
#include 
9
#include 
10
//#include 
10
//#include 
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...
43
 
43
 
44
int __bitmap_empty(const unsigned long *bitmap, int bits)
44
int __bitmap_empty(const unsigned long *bitmap, unsigned int bits)
45
{
45
{
46
	int k, lim = bits/BITS_PER_LONG;
46
	unsigned int k, lim = bits/BITS_PER_LONG;
47
	for (k = 0; k < lim; ++k)
47
	for (k = 0; k < lim; ++k)
48
		if (bitmap[k])
48
		if (bitmap[k])
Line 49... Line 49...
49
			return 0;
49
			return 0;
Line 54... Line 54...
54
 
54
 
55
	return 1;
55
	return 1;
56
}
56
}
Line 57... Line 57...
57
EXPORT_SYMBOL(__bitmap_empty);
57
EXPORT_SYMBOL(__bitmap_empty);
58
 
58
 
59
int __bitmap_full(const unsigned long *bitmap, int bits)
59
int __bitmap_full(const unsigned long *bitmap, unsigned int bits)
60
{
60
{
61
	int k, lim = bits/BITS_PER_LONG;
61
	unsigned int k, lim = bits/BITS_PER_LONG;
62
	for (k = 0; k < lim; ++k)
62
	for (k = 0; k < lim; ++k)
Line 63... Line 63...
63
		if (~bitmap[k])
63
		if (~bitmap[k])
Line 70... Line 70...
70
	return 1;
70
	return 1;
71
}
71
}
72
EXPORT_SYMBOL(__bitmap_full);
72
EXPORT_SYMBOL(__bitmap_full);
Line 73... Line 73...
73
 
73
 
74
int __bitmap_equal(const unsigned long *bitmap1,
74
int __bitmap_equal(const unsigned long *bitmap1,
75
		const unsigned long *bitmap2, int bits)
75
		const unsigned long *bitmap2, unsigned int bits)
76
{
76
{
77
	int k, lim = bits/BITS_PER_LONG;
77
	unsigned int k, lim = bits/BITS_PER_LONG;
78
	for (k = 0; k < lim; ++k)
78
	for (k = 0; k < lim; ++k)
79
		if (bitmap1[k] != bitmap2[k])
79
		if (bitmap1[k] != bitmap2[k])
Line 80... Line 80...
80
			return 0;
80
			return 0;
Line 85... Line 85...
85
 
85
 
86
	return 1;
86
	return 1;
87
}
87
}
Line 88... Line 88...
88
EXPORT_SYMBOL(__bitmap_equal);
88
EXPORT_SYMBOL(__bitmap_equal);
89
 
89
 
90
void __bitmap_complement(unsigned long *dst, const unsigned long *src, int bits)
90
void __bitmap_complement(unsigned long *dst, const unsigned long *src, unsigned int bits)
91
{
91
{
92
	int k, lim = bits/BITS_PER_LONG;
92
	unsigned int k, lim = bits/BITS_PER_LONG;
Line 93... Line 93...
93
	for (k = 0; k < lim; ++k)
93
	for (k = 0; k < lim; ++k)
94
		dst[k] = ~src[k];
94
		dst[k] = ~src[k];
95
 
95
 
96
	if (bits % BITS_PER_LONG)
96
	if (bits % BITS_PER_LONG)
Line 97... Line 97...
97
		dst[k] = ~src[k] & BITMAP_LAST_WORD_MASK(bits);
97
		dst[k] = ~src[k];
98
}
98
}
Line 181... Line 181...
181
		memset(dst, 0, off*sizeof(unsigned long));
181
		memset(dst, 0, off*sizeof(unsigned long));
182
}
182
}
183
EXPORT_SYMBOL(__bitmap_shift_left);
183
EXPORT_SYMBOL(__bitmap_shift_left);
Line 184... Line 184...
184
 
184
 
185
int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
185
int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
186
				const unsigned long *bitmap2, int bits)
186
				const unsigned long *bitmap2, unsigned int bits)
187
{
187
{
188
	int k;
188
	unsigned int k;
189
	int nr = BITS_TO_LONGS(bits);
189
	unsigned int lim = bits/BITS_PER_LONG;
Line 190... Line 190...
190
	unsigned long result = 0;
190
	unsigned long result = 0;
191
 
191
 
-
 
192
	for (k = 0; k < lim; k++)
-
 
193
		result |= (dst[k] = bitmap1[k] & bitmap2[k]);
-
 
194
	if (bits % BITS_PER_LONG)
192
	for (k = 0; k < nr; k++)
195
		result |= (dst[k] = bitmap1[k] & bitmap2[k] &
193
		result |= (dst[k] = bitmap1[k] & bitmap2[k]);
196
			   BITMAP_LAST_WORD_MASK(bits));
194
	return result != 0;
197
	return result != 0;
Line 195... Line 198...
195
}
198
}
196
EXPORT_SYMBOL(__bitmap_and);
199
EXPORT_SYMBOL(__bitmap_and);
197
 
200
 
198
void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
201
void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
199
				const unsigned long *bitmap2, int bits)
202
				const unsigned long *bitmap2, unsigned int bits)
Line 200... Line 203...
200
{
203
{
201
	int k;
204
	unsigned int k;
202
	int nr = BITS_TO_LONGS(bits);
205
	unsigned int nr = BITS_TO_LONGS(bits);
203
 
206
 
Line 204... Line 207...
204
	for (k = 0; k < nr; k++)
207
	for (k = 0; k < nr; k++)
205
		dst[k] = bitmap1[k] | bitmap2[k];
208
		dst[k] = bitmap1[k] | bitmap2[k];
206
}
209
}
207
EXPORT_SYMBOL(__bitmap_or);
210
EXPORT_SYMBOL(__bitmap_or);
208
 
211
 
Line 209... Line 212...
209
void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
212
void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
210
				const unsigned long *bitmap2, int bits)
213
				const unsigned long *bitmap2, unsigned int bits)
211
{
214
{
212
	int k;
215
	unsigned int k;
Line 213... Line 216...
213
	int nr = BITS_TO_LONGS(bits);
216
	unsigned int nr = BITS_TO_LONGS(bits);
214
 
217
 
215
	for (k = 0; k < nr; k++)
218
	for (k = 0; k < nr; k++)
216
		dst[k] = bitmap1[k] ^ bitmap2[k];
219
		dst[k] = bitmap1[k] ^ bitmap2[k];
217
}
220
}
218
EXPORT_SYMBOL(__bitmap_xor);
221
EXPORT_SYMBOL(__bitmap_xor);
Line 219... Line 222...
219
 
222
 
220
int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
223
int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
-
 
224
				const unsigned long *bitmap2, unsigned int bits)
-
 
225
{
-
 
226
	unsigned int k;
221
				const unsigned long *bitmap2, int bits)
227
	unsigned int lim = bits/BITS_PER_LONG;
222
{
228
	unsigned long result = 0;
223
	int k;
229
 
Line 224... Line 230...
224
	int nr = BITS_TO_LONGS(bits);
230
	for (k = 0; k < lim; k++)
225
	unsigned long result = 0;
231
		result |= (dst[k] = bitmap1[k] & ~bitmap2[k]);
226
 
232
	if (bits % BITS_PER_LONG)
227
	for (k = 0; k < nr; k++)
233
		result |= (dst[k] = bitmap1[k] & ~bitmap2[k] &
228
		result |= (dst[k] = bitmap1[k] & ~bitmap2[k]);
234
			   BITMAP_LAST_WORD_MASK(bits));
229
	return result != 0;
235
	return result != 0;
230
}
236
}
Line 231... Line 237...
231
EXPORT_SYMBOL(__bitmap_andnot);
237
EXPORT_SYMBOL(__bitmap_andnot);
Line 244... Line 250...
244
	return 0;
250
	return 0;
245
}
251
}
246
EXPORT_SYMBOL(__bitmap_intersects);
252
EXPORT_SYMBOL(__bitmap_intersects);
Line 247... Line 253...
247
 
253
 
248
int __bitmap_subset(const unsigned long *bitmap1,
254
int __bitmap_subset(const unsigned long *bitmap1,
249
				const unsigned long *bitmap2, int bits)
255
		    const unsigned long *bitmap2, unsigned int bits)
250
{
256
{
251
	int k, lim = bits/BITS_PER_LONG;
257
	unsigned int k, lim = bits/BITS_PER_LONG;
252
	for (k = 0; k < lim; ++k)
258
	for (k = 0; k < lim; ++k)
253
		if (bitmap1[k] & ~bitmap2[k])
259
		if (bitmap1[k] & ~bitmap2[k])
Line 254... Line 260...
254
			return 0;
260
			return 0;
Line 258... Line 264...
258
			return 0;
264
			return 0;
259
	return 1;
265
	return 1;
260
}
266
}
261
EXPORT_SYMBOL(__bitmap_subset);
267
EXPORT_SYMBOL(__bitmap_subset);
Line 262... Line 268...
262
 
268
 
263
int __bitmap_weight(const unsigned long *bitmap, int bits)
269
int __bitmap_weight(const unsigned long *bitmap, unsigned int bits)
264
{
270
{
-
 
271
	unsigned int k, lim = bits/BITS_PER_LONG;
Line 265... Line 272...
265
	int k, w = 0, lim = bits/BITS_PER_LONG;
272
	int w = 0;
266
 
273
 
Line 267... Line 274...
267
	for (k = 0; k < lim; k++)
274
	for (k = 0; k < lim; k++)
Line 272... Line 279...
272
 
279
 
273
	return w;
280
	return w;
274
}
281
}
Line 275... Line 282...
275
EXPORT_SYMBOL(__bitmap_weight);
282
EXPORT_SYMBOL(__bitmap_weight);
276
 
283
 
277
void bitmap_set(unsigned long *map, int start, int nr)
284
void bitmap_set(unsigned long *map, unsigned int start, int len)
278
{
285
{
279
	unsigned long *p = map + BIT_WORD(start);
286
	unsigned long *p = map + BIT_WORD(start);
280
	const int size = start + nr;
287
	const unsigned int size = start + len;
Line 281... Line 288...
281
	int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG);
288
	int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG);
282
	unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start);
289
	unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start);
283
 
290
 
284
	while (nr - bits_to_set >= 0) {
291
	while (len - bits_to_set >= 0) {
285
		*p |= mask_to_set;
292
		*p |= mask_to_set;
286
		nr -= bits_to_set;
293
		len -= bits_to_set;
287
		bits_to_set = BITS_PER_LONG;
294
		bits_to_set = BITS_PER_LONG;
288
		mask_to_set = ~0UL;
295
		mask_to_set = ~0UL;
289
		p++;
296
		p++;
290
	}
297
	}
291
	if (nr) {
298
	if (len) {
292
		mask_to_set &= BITMAP_LAST_WORD_MASK(size);
299
		mask_to_set &= BITMAP_LAST_WORD_MASK(size);
293
		*p |= mask_to_set;
300
		*p |= mask_to_set;
Line 294... Line 301...
294
	}
301
	}
295
}
302
}
296
EXPORT_SYMBOL(bitmap_set);
303
EXPORT_SYMBOL(bitmap_set);
297
 
304
 
298
void bitmap_clear(unsigned long *map, int start, int nr)
305
void bitmap_clear(unsigned long *map, unsigned int start, int len)
299
{
306
{
Line 300... Line 307...
300
	unsigned long *p = map + BIT_WORD(start);
307
	unsigned long *p = map + BIT_WORD(start);
301
	const int size = start + nr;
308
	const unsigned int size = start + len;
302
	int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG);
309
	int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG);
303
	unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start);
310
	unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start);
304
 
311
 
305
	while (nr - bits_to_clear >= 0) {
312
	while (len - bits_to_clear >= 0) {
306
		*p &= ~mask_to_clear;
313
		*p &= ~mask_to_clear;
307
		nr -= bits_to_clear;
314
		len -= bits_to_clear;
308
		bits_to_clear = BITS_PER_LONG;
315
		bits_to_clear = BITS_PER_LONG;
309
		mask_to_clear = ~0UL;
316
		mask_to_clear = ~0UL;
310
		p++;
317
		p++;
311
	}
318
	}
312
	if (nr) {
319
	if (len) {
Line 376... Line 383...
376
 * ordinal of which set bit it is.  If it is not set or if @pos
383
 * ordinal of which set bit it is.  If it is not set or if @pos
377
 * is not a valid bit position, map to -1.
384
 * is not a valid bit position, map to -1.
378
 *
385
 *
379
 * If for example, just bits 4 through 7 are set in @buf, then @pos
386
 * If for example, just bits 4 through 7 are set in @buf, then @pos
380
 * values 4 through 7 will get mapped to 0 through 3, respectively,
387
 * values 4 through 7 will get mapped to 0 through 3, respectively,
381
 * and other @pos values will get mapped to 0.  When @pos value 7
388
 * and other @pos values will get mapped to -1.  When @pos value 7
382
 * gets mapped to (returns) @ord value 3 in this example, that means
389
 * gets mapped to (returns) @ord value 3 in this example, that means
383
 * that bit 7 is the 3rd (starting with 0th) set bit in @buf.
390
 * that bit 7 is the 3rd (starting with 0th) set bit in @buf.
384
 *
391
 *
385
 * The bit positions 0 through @bits are valid positions in @buf.
392
 * The bit positions 0 through @bits are valid positions in @buf.
386
 */
393
 */
Line 706... Line 713...
706
	REG_OP_ISFREE,		/* true if region is all zero bits */
713
	REG_OP_ISFREE,		/* true if region is all zero bits */
707
	REG_OP_ALLOC,		/* set all bits in region */
714
	REG_OP_ALLOC,		/* set all bits in region */
708
	REG_OP_RELEASE,		/* clear all bits in region */
715
	REG_OP_RELEASE,		/* clear all bits in region */
709
};
716
};
Line 710... Line 717...
710
 
717
 
711
static int __reg_op(unsigned long *bitmap, int pos, int order, int reg_op)
718
static int __reg_op(unsigned long *bitmap, unsigned int pos, int order, int reg_op)
712
{
719
{
713
	int nbits_reg;		/* number of bits in region */
720
	int nbits_reg;		/* number of bits in region */
714
	int index;		/* index first long of region in bitmap */
721
	int index;		/* index first long of region in bitmap */
715
	int offset;		/* bit offset region in bitmap[index] */
722
	int offset;		/* bit offset region in bitmap[index] */
Line 772... Line 779...
772
 * makes the search algorithm much faster.
779
 * makes the search algorithm much faster.
773
 *
780
 *
774
 * Return the bit offset in bitmap of the allocated region,
781
 * Return the bit offset in bitmap of the allocated region,
775
 * or -errno on failure.
782
 * or -errno on failure.
776
 */
783
 */
777
int bitmap_find_free_region(unsigned long *bitmap, int bits, int order)
784
int bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order)
778
{
785
{
779
	int pos, end;		/* scans bitmap by regions of size order */
786
	unsigned int pos, end;		/* scans bitmap by regions of size order */
Line 780... Line 787...
780
 
787
 
781
	for (pos = 0 ; (end = pos + (1 << order)) <= bits; pos = end) {
788
	for (pos = 0 ; (end = pos + (1U << order)) <= bits; pos = end) {
782
		if (!__reg_op(bitmap, pos, order, REG_OP_ISFREE))
789
		if (!__reg_op(bitmap, pos, order, REG_OP_ISFREE))
783
			continue;
790
			continue;
784
		__reg_op(bitmap, pos, order, REG_OP_ALLOC);
791
		__reg_op(bitmap, pos, order, REG_OP_ALLOC);
785
		return pos;
792
		return pos;
Line 797... Line 804...
797
 * This is the complement to __bitmap_find_free_region() and releases
804
 * This is the complement to __bitmap_find_free_region() and releases
798
 * the found region (by clearing it in the bitmap).
805
 * the found region (by clearing it in the bitmap).
799
 *
806
 *
800
 * No return value.
807
 * No return value.
801
 */
808
 */
802
void bitmap_release_region(unsigned long *bitmap, int pos, int order)
809
void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order)
803
{
810
{
804
	__reg_op(bitmap, pos, order, REG_OP_RELEASE);
811
	__reg_op(bitmap, pos, order, REG_OP_RELEASE);
805
}
812
}
806
EXPORT_SYMBOL(bitmap_release_region);
813
EXPORT_SYMBOL(bitmap_release_region);
Line 814... Line 821...
814
 * Allocate (set bits in) a specified region of a bitmap.
821
 * Allocate (set bits in) a specified region of a bitmap.
815
 *
822
 *
816
 * Return 0 on success, or %-EBUSY if specified region wasn't
823
 * Return 0 on success, or %-EBUSY if specified region wasn't
817
 * free (not all bits were zero).
824
 * free (not all bits were zero).
818
 */
825
 */
819
int bitmap_allocate_region(unsigned long *bitmap, int pos, int order)
826
int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order)
820
{
827
{
821
	if (!__reg_op(bitmap, pos, order, REG_OP_ISFREE))
828
	if (!__reg_op(bitmap, pos, order, REG_OP_ISFREE))
822
		return -EBUSY;
829
		return -EBUSY;
823
	__reg_op(bitmap, pos, order, REG_OP_ALLOC);
830
	return __reg_op(bitmap, pos, order, REG_OP_ALLOC);
824
	return 0;
-
 
825
}
831
}
826
EXPORT_SYMBOL(bitmap_allocate_region);
832
EXPORT_SYMBOL(bitmap_allocate_region);
Line 827... Line 833...
827
 
833
 
828
/**
834
/**