1 // SPDX-License-Identifier: GPL-2.0
3 * bitext.c: kernel little helper (of bit shuffling variety).
5 * Copyright (C) 2002 Pete Zaitcev <zaitcev@yahoo.com>
7 * The algorithm to search a zero bit string is geared towards its application.
8 * We expect a couple of fixed sizes of requests, so a rotating counter, reset
9 * by align size, should provide fast enough search while maintaining low
13 #include <linux/string.h>
14 #include <linux/bitmap.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 bitmap_set(t
->map
, offset
, len
);
85 if (offset
== t
->first_free
)
86 t
->first_free
= find_next_zero_bit
89 if ((t
->last_off
= offset
+ len
) >= t
->size
)
93 spin_unlock(&t
->lock
);
98 if ((offset
+= i
+ 1) >= t
->size
)
103 void bit_map_clear(struct bit_map
*t
, int offset
, int len
)
108 BUG(); /* Much too late to do any good, but alas... */
110 for (i
= 0; i
< len
; i
++) {
111 if (test_bit(offset
+ i
, t
->map
) == 0)
113 __clear_bit(offset
+ i
, t
->map
);
115 if (offset
< t
->first_free
)
116 t
->first_free
= offset
;
118 spin_unlock(&t
->lock
);
121 void bit_map_init(struct bit_map
*t
, unsigned long *map
, int size
)
123 bitmap_zero(map
, size
);
124 memset(t
, 0, sizeof *t
);
125 spin_lock_init(&t
->lock
);