Motr  M0
bitmap.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2012-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #include "lib/bitmap.h"
24 #include "lib/misc.h" /* M0_SET0 */
25 #include "lib/assert.h"
26 #include "lib/errno.h"
27 #include "lib/memory.h"
28 
29 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_LIB
30 #include "lib/trace.h"
31 
41 enum {
42  M0_BITMAP_BITS = (8 * sizeof ((struct m0_bitmap *)0)->b_words[0]),
44 };
45 
46 /*
47  Note that the following assertion validates both the relationship between
48  M0_BITMAP_BITS and M0_BITMAP_BITSHIFT, and that M0_BITMAP_BITS is
49  a power of 2.
50 */
52 
59 #define M0_BITMAP_WORDS(nr) (((nr) + (M0_BITMAP_BITS-1)) >> M0_BITMAP_BITSHIFT)
60 
61 /* verify the bounds of size macro */
64 M0_BASSERT(M0_BITMAP_WORDS(63) == 1);
65 M0_BASSERT(M0_BITMAP_WORDS(64) == 1);
66 M0_BASSERT(M0_BITMAP_WORDS(65) == 2);
67 
75 #define M0_BITMAP_SHIFT(idx) ((idx) >> M0_BITMAP_BITSHIFT)
76 
84 #define M0_BITMAP_MASK(idx) (1UL << ((idx) & (M0_BITMAP_BITS-1)))
85 
86 M0_INTERNAL int m0_bitmap_init(struct m0_bitmap *map, size_t nr)
87 {
88  M0_ALLOC_ARR(map->b_words, M0_BITMAP_WORDS(nr));
89  if (map->b_words == NULL)
90  return M0_ERR(-ENOMEM);
91  map->b_nr = nr;
92 
93  return 0;
94 }
95 M0_EXPORTED(m0_bitmap_init);
96 
97 M0_INTERNAL void m0_bitmap_fini(struct m0_bitmap *map)
98 {
99  M0_ASSERT(map->b_words != NULL);
100  m0_free(map->b_words);
101  M0_SET0(map);
102 }
103 M0_EXPORTED(m0_bitmap_fini);
104 
105 M0_INTERNAL bool m0_bitmap_get(const struct m0_bitmap *map, size_t idx)
106 {
107  M0_PRE(idx < map->b_nr && map->b_words != NULL);
108  return map->b_words[M0_BITMAP_SHIFT(idx)] & M0_BITMAP_MASK(idx);
109 }
110 M0_EXPORTED(m0_bitmap_get);
111 
112 M0_INTERNAL int m0_bitmap_ffs(const struct m0_bitmap *map)
113 {
114  int i;
115  int idx;
116 
117  for (i = 0; i < M0_BITMAP_WORDS(map->b_nr); i++) {
118  idx = __builtin_ffsll(map->b_words[i]);
119  if (idx > 0)
120  return i * M0_BITMAP_BITS + (idx - 1);
121  }
122  return -1;
123 }
124 M0_EXPORTED(m0_bitmap_ffs);
125 
126 M0_INTERNAL int m0_bitmap_ffz(const struct m0_bitmap *map)
127 {
128  int idx;
129 
130  /* use linux find_first_zero_bit() ? */
131  for (idx = 0; idx < map->b_nr; idx++) {
132  if (!m0_bitmap_get(map, idx))
133  return idx;
134  }
135  return -1;
136 }
137 M0_EXPORTED(m0_bitmap_ffz);
138 
139 M0_INTERNAL void m0_bitmap_set(struct m0_bitmap *map, size_t idx, bool val)
140 {
141  M0_ASSERT(idx < map->b_nr && map->b_words != NULL);
142  if (val)
143  map->b_words[M0_BITMAP_SHIFT(idx)] |= M0_BITMAP_MASK(idx);
144  else
145  map->b_words[M0_BITMAP_SHIFT(idx)] &= ~M0_BITMAP_MASK(idx);
146 }
147 M0_EXPORTED(m0_bitmap_set);
148 
149 M0_INTERNAL void m0_bitmap_reset(struct m0_bitmap *map)
150 {
151  size_t i;
152 
153  for (i = 0; i < M0_BITMAP_WORDS(map->b_nr); i++)
154  map->b_words[i] = 0;
155 }
156 M0_EXPORTED(m0_bitmap_reset);
157 
158 M0_INTERNAL void m0_bitmap_copy(struct m0_bitmap *dst,
159  const struct m0_bitmap *src)
160 {
161  int s = M0_BITMAP_WORDS(src->b_nr);
162  int d = M0_BITMAP_WORDS(dst->b_nr);
163 
164  M0_PRE(dst->b_nr >= src->b_nr &&
165  src->b_words != NULL && dst->b_words != NULL);
166 
167  memcpy(dst->b_words, src->b_words, s * sizeof src->b_words[0]);
168  if (d > s)
169  memset(&dst->b_words[s], 0, (d - s) * sizeof dst->b_words[0]);
170 }
171 
172 M0_INTERNAL size_t m0_bitmap_set_nr(const struct m0_bitmap *map)
173 {
174  size_t i;
175  size_t nr;
176  M0_PRE(map != NULL);
177  for (nr = 0, i = 0; i < map->b_nr; ++i)
178  nr += m0_bitmap_get(map, i);
179  return nr;
180 }
181 
182 M0_INTERNAL int m0_bitmap_onwire_init(struct m0_bitmap_onwire *ow_map, size_t nr)
183 {
184  ow_map->bo_size = M0_BITMAP_WORDS(nr);
186  if (ow_map->bo_words == NULL)
187  return M0_ERR(-ENOMEM);
188 
189  return 0;
190 }
191 
192 M0_INTERNAL void m0_bitmap_onwire_fini(struct m0_bitmap_onwire *ow_map)
193 {
194  M0_PRE(ow_map != NULL);
195 
196  m0_free(ow_map->bo_words);
197  M0_SET0(ow_map);
198 }
199 
200 M0_INTERNAL void m0_bitmap_store(const struct m0_bitmap *im_map,
201  struct m0_bitmap_onwire *ow_map)
202 {
203  size_t s = M0_BITMAP_WORDS(im_map->b_nr);
204 
205  M0_PRE(im_map != NULL && ow_map != NULL);
206  M0_PRE(im_map->b_words != NULL);
207  M0_PRE(s == ow_map->bo_size);
208 
209  memcpy(ow_map->bo_words, im_map->b_words,
210  s * sizeof im_map->b_words[0]);
211 }
212 
213 M0_INTERNAL void m0_bitmap_load(const struct m0_bitmap_onwire *ow_map,
214  struct m0_bitmap *im_map)
215 {
216  M0_PRE(ow_map != NULL && im_map != NULL);
217  M0_PRE(M0_BITMAP_WORDS(im_map->b_nr) == ow_map->bo_size);
218 
219  /* copy onwire bitmap words to in-memory bitmap words. */
220  memcpy(im_map->b_words, ow_map->bo_words,
221  ow_map->bo_size * sizeof ow_map->bo_words[0]);
222 }
223 
224 #undef M0_TRACE_SUBSYSTEM
225 
228 /*
229  * Local variables:
230  * c-indentation-style: "K&R"
231  * c-basic-offset: 8
232  * tab-width: 8
233  * fill-column: 80
234  * scroll-step: 1
235  * End:
236  */
static size_t nr
Definition: dump.c:1505
#define M0_PRE(cond)
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
M0_INTERNAL int m0_bitmap_init(struct m0_bitmap *map, size_t nr)
Definition: bitmap.c:86
#define NULL
Definition: misc.h:38
M0_INTERNAL void m0_bitmap_fini(struct m0_bitmap *map)
Definition: bitmap.c:97
static struct m0_bufvec dst
Definition: xform.c:61
map
Definition: processor.c:112
Definition: idx_mock.c:52
M0_INTERNAL size_t m0_bitmap_set_nr(const struct m0_bitmap *map)
Definition: bitmap.c:172
#define M0_SET0(obj)
Definition: misc.h:64
#define M0_BITMAP_MASK(idx)
Definition: bitmap.c:84
M0_BASSERT(M0_BITMAP_BITS==(1UL<< M0_BITMAP_BITSHIFT))
M0_INTERNAL void m0_bitmap_store(const struct m0_bitmap *im_map, struct m0_bitmap_onwire *ow_map)
Definition: bitmap.c:200
int i
Definition: dir.c:1033
M0_INTERNAL void m0_bitmap_onwire_fini(struct m0_bitmap_onwire *ow_map)
Definition: bitmap.c:192
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL int m0_bitmap_onwire_init(struct m0_bitmap_onwire *ow_map, size_t nr)
Definition: bitmap.c:182
#define M0_ASSERT(cond)
M0_INTERNAL int m0_bitmap_ffz(const struct m0_bitmap *map)
Definition: bitmap.c:126
uint64_t * bo_words
Definition: bitmap.h:53
size_t bo_size
Definition: bitmap.h:51
M0_INTERNAL void m0_bitmap_set(struct m0_bitmap *map, size_t idx, bool val)
Definition: bitmap.c:139
#define M0_BITMAP_SHIFT(idx)
Definition: bitmap.c:75
M0_INTERNAL int m0_bitmap_ffs(const struct m0_bitmap *map)
Definition: bitmap.c:112
M0_INTERNAL void m0_bitmap_copy(struct m0_bitmap *dst, const struct m0_bitmap *src)
Definition: bitmap.c:158
uint64_t * b_words
Definition: bitmap.h:46
#define M0_BITMAP_WORDS(nr)
Definition: bitmap.c:59
M0_INTERNAL bool m0_bitmap_get(const struct m0_bitmap *map, size_t idx)
Definition: bitmap.c:105
M0_INTERNAL void m0_bitmap_reset(struct m0_bitmap *map)
Definition: bitmap.c:149
size_t b_nr
Definition: bitmap.h:44
M0_INTERNAL void m0_bitmap_load(const struct m0_bitmap_onwire *ow_map, struct m0_bitmap *im_map)
Definition: bitmap.c:213
void m0_free(void *data)
Definition: memory.c:146
static struct m0_addb2_source * s
Definition: consumer.c:39
struct m0_pdclust_src_addr src
Definition: fd.c:108