00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <types.h>
00035 #include <kern/errno.h>
00036 #include <lib.h>
00037 #include <bitmap.h>
00038
00039
00040
00041
00042
00043
00044
00045
00046 #define BITS_PER_WORD (CHAR_BIT)
00047 #define WORD_TYPE unsigned char
00048 #define WORD_ALLBITS (0xff)
00049
00050 struct bitmap {
00051 unsigned nbits;
00052 WORD_TYPE *v;
00053 };
00054
00055
00056 struct bitmap *
00057 bitmap_create(unsigned nbits)
00058 {
00059 struct bitmap *b;
00060 unsigned words;
00061
00062 words = DIVROUNDUP(nbits, BITS_PER_WORD);
00063 b = kmalloc(sizeof(struct bitmap));
00064 if (b == NULL) {
00065 return NULL;
00066 }
00067 b->v = kmalloc(words*sizeof(WORD_TYPE));
00068 if (b->v == NULL) {
00069 kfree(b);
00070 return NULL;
00071 }
00072
00073 bzero(b->v, words*sizeof(WORD_TYPE));
00074 b->nbits = nbits;
00075
00076
00077 if (words > nbits / BITS_PER_WORD) {
00078 unsigned j, ix = words-1;
00079 unsigned overbits = nbits - ix*BITS_PER_WORD;
00080
00081 KASSERT(nbits / BITS_PER_WORD == words-1);
00082 KASSERT(overbits > 0 && overbits < BITS_PER_WORD);
00083
00084 for (j=overbits; j<BITS_PER_WORD; j++) {
00085 b->v[ix] |= ((WORD_TYPE)1 << j);
00086 }
00087 }
00088
00089 return b;
00090 }
00091
00092 void *
00093 bitmap_getdata(struct bitmap *b)
00094 {
00095 return b->v;
00096 }
00097
00098 int
00099 bitmap_alloc(struct bitmap *b, unsigned *index)
00100 {
00101 unsigned ix;
00102 unsigned maxix = DIVROUNDUP(b->nbits, BITS_PER_WORD);
00103 unsigned offset;
00104
00105 for (ix=0; ix<maxix; ix++) {
00106 if (b->v[ix]!=WORD_ALLBITS) {
00107 for (offset = 0; offset < BITS_PER_WORD; offset++) {
00108 WORD_TYPE mask = ((WORD_TYPE)1) << offset;
00109
00110 if ((b->v[ix] & mask)==0) {
00111 b->v[ix] |= mask;
00112 *index = (ix*BITS_PER_WORD)+offset;
00113 KASSERT(*index < b->nbits);
00114 return 0;
00115 }
00116 }
00117 KASSERT(0);
00118 }
00119 }
00120 return ENOSPC;
00121 }
00122
00123 static
00124 inline
00125 void
00126 bitmap_translate(unsigned bitno, unsigned *ix, WORD_TYPE *mask)
00127 {
00128 unsigned offset;
00129 *ix = bitno / BITS_PER_WORD;
00130 offset = bitno % BITS_PER_WORD;
00131 *mask = ((WORD_TYPE)1) << offset;
00132 }
00133
00134 void
00135 bitmap_mark(struct bitmap *b, unsigned index)
00136 {
00137 unsigned ix;
00138 WORD_TYPE mask;
00139
00140 KASSERT(index < b->nbits);
00141 bitmap_translate(index, &ix, &mask);
00142
00143 KASSERT((b->v[ix] & mask)==0);
00144 b->v[ix] |= mask;
00145 }
00146
00147 void
00148 bitmap_unmark(struct bitmap *b, unsigned index)
00149 {
00150 unsigned ix;
00151 WORD_TYPE mask;
00152
00153 KASSERT(index < b->nbits);
00154 bitmap_translate(index, &ix, &mask);
00155
00156 KASSERT((b->v[ix] & mask)!=0);
00157 b->v[ix] &= ~mask;
00158 }
00159
00160
00161 int
00162 bitmap_isset(struct bitmap *b, unsigned index)
00163 {
00164 unsigned ix;
00165 WORD_TYPE mask;
00166
00167 bitmap_translate(index, &ix, &mask);
00168 return (b->v[ix] & mask);
00169 }
00170
00171 void
00172 bitmap_destroy(struct bitmap *b)
00173 {
00174 kfree(b->v);
00175 kfree(b);
00176 }