2 * bitext.c: kernel little helper (of bit shuffling variety).
4 * Copyright (C) 2002 Pete Zaitcev <zaitcev@yahoo.com>
6 * The algorithm to search a zero bit string is geared towards its application.
7 * We expect a couple of fixed sizes of requests, so a rotating counter, reset
8 * by align size, should provide fast enough search while maintaining low
12 #include <linux/smp_lock.h>
13 #include <linux/string.h>
14 #include <linux/bitops.h>
16 #include <asm/bitext.h>
19 * bit_map_string_get - find and set a bit string in bit map.
21 * @len: requested string length
22 * @align: requested alignment
24 * Returns offset in the map or -1 if out of space.
26 * Not safe to call from an interrupt (uses spin_lock).
28 int bit_map_string_get(struct bit_map
*t
, int len
, int align
)
30 int offset
, count
; /* siamese twins */
36 /* align is overloaded to be the page color */
38 align
= t
->num_colors
;
45 if ((align
& align1
) != 0)
47 if (align
< 0 || align
>= t
->size
)
49 if (len
<= 0 || len
> t
->size
)
54 if (len
< t
->last_size
)
55 offset
= t
->first_free
;
57 offset
= t
->last_off
& ~align1
;
60 off_new
= find_next_zero_bit(t
->map
, t
->size
, offset
);
61 off_new
= ((off_new
+ align1
) & ~align1
) + color
;
62 count
+= off_new
- offset
;
64 if (offset
>= t
->size
)
66 if (count
+ len
> t
->size
) {
67 spin_unlock(&t
->lock
);
68 /* P3 */ printk(KERN_ERR
69 "bitmap out: size %d used %d off %d len %d align %d count %d\n",
70 t
->size
, t
->used
, offset
, len
, align
, count
);
74 if (offset
+ len
> t
->size
) {
75 count
+= t
->size
- offset
;
81 while (test_bit(offset
+ i
, t
->map
) == 0) {
84 for (i
= 0; i
< len
; i
++)
85 __set_bit(offset
+ i
, t
->map
);
86 if (offset
== t
->first_free
)
87 t
->first_free
= find_next_zero_bit
90 if ((t
->last_off
= offset
+ len
) >= t
->size
)
94 spin_unlock(&t
->lock
);
99 if ((offset
+= i
+ 1) >= t
->size
)
104 void bit_map_clear(struct bit_map
*t
, int offset
, int len
)
109 BUG(); /* Much too late to do any good, but alas... */
111 for (i
= 0; i
< len
; i
++) {
112 if (test_bit(offset
+ i
, t
->map
) == 0)
114 __clear_bit(offset
+ i
, t
->map
);
116 if (offset
< t
->first_free
)
117 t
->first_free
= offset
;
119 spin_unlock(&t
->lock
);
122 void bit_map_init(struct bit_map
*t
, unsigned long *map
, int size
)
125 if ((size
& 07) != 0)
127 memset(map
, 0, size
>>3);
129 memset(t
, 0, sizeof *t
);
130 spin_lock_init(&t
->lock
);