0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/string.h>
0014 #include <linux/bitmap.h>
0015
0016 #include <asm/bitext.h>
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 int bit_map_string_get(struct bit_map *t, int len, int align)
0029 {
0030 int offset, count;
0031 int off_new;
0032 int align1;
0033 int i, color;
0034
0035 if (t->num_colors) {
0036
0037 color = align;
0038 align = t->num_colors;
0039 } else {
0040 color = 0;
0041 if (align == 0)
0042 align = 1;
0043 }
0044 align1 = align - 1;
0045 if ((align & align1) != 0)
0046 BUG();
0047 if (align < 0 || align >= t->size)
0048 BUG();
0049 if (len <= 0 || len > t->size)
0050 BUG();
0051 color &= align1;
0052
0053 spin_lock(&t->lock);
0054 if (len < t->last_size)
0055 offset = t->first_free;
0056 else
0057 offset = t->last_off & ~align1;
0058 count = 0;
0059 for (;;) {
0060 off_new = find_next_zero_bit(t->map, t->size, offset);
0061 off_new = ((off_new + align1) & ~align1) + color;
0062 count += off_new - offset;
0063 offset = off_new;
0064 if (offset >= t->size)
0065 offset = 0;
0066 if (count + len > t->size) {
0067 spin_unlock(&t->lock);
0068 printk(KERN_ERR
0069 "bitmap out: size %d used %d off %d len %d align %d count %d\n",
0070 t->size, t->used, offset, len, align, count);
0071 return -1;
0072 }
0073
0074 if (offset + len > t->size) {
0075 count += t->size - offset;
0076 offset = 0;
0077 continue;
0078 }
0079
0080 i = 0;
0081 while (test_bit(offset + i, t->map) == 0) {
0082 i++;
0083 if (i == len) {
0084 bitmap_set(t->map, offset, len);
0085 if (offset == t->first_free)
0086 t->first_free = find_next_zero_bit
0087 (t->map, t->size,
0088 t->first_free + len);
0089 if ((t->last_off = offset + len) >= t->size)
0090 t->last_off = 0;
0091 t->used += len;
0092 t->last_size = len;
0093 spin_unlock(&t->lock);
0094 return offset;
0095 }
0096 }
0097 count += i + 1;
0098 if ((offset += i + 1) >= t->size)
0099 offset = 0;
0100 }
0101 }
0102
0103 void bit_map_clear(struct bit_map *t, int offset, int len)
0104 {
0105 int i;
0106
0107 if (t->used < len)
0108 BUG();
0109 spin_lock(&t->lock);
0110 for (i = 0; i < len; i++) {
0111 if (test_bit(offset + i, t->map) == 0)
0112 BUG();
0113 __clear_bit(offset + i, t->map);
0114 }
0115 if (offset < t->first_free)
0116 t->first_free = offset;
0117 t->used -= len;
0118 spin_unlock(&t->lock);
0119 }
0120
0121 void bit_map_init(struct bit_map *t, unsigned long *map, int size)
0122 {
0123 bitmap_zero(map, size);
0124 memset(t, 0, sizeof *t);
0125 spin_lock_init(&t->lock);
0126 t->map = map;
0127 t->size = size;
0128 }