Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2021 Intel Corporation
3 : : *
4 : : * SPDX-License-Identifier: Apache-2.0
5 : : */
6 : :
7 : : #include <errno.h>
8 : : #include <stddef.h>
9 : : #include <stdbool.h>
10 : : #include <stdio.h>
11 : : #include <sys/bitarray.h>
12 : : #include <sys/check.h>
13 : : #include <sys/sys_io.h>
14 : :
15 : : /* Number of bits represented by one bundle */
16 : : #define bundle_bitness(ba) (sizeof(ba->bundles[0]) * 8)
17 : :
18 : : struct bundle_data {
19 : : /* Start and end index of bundles */
20 : : size_t sidx, eidx;
21 : :
22 : : /* Offset inside start and end bundles */
23 : : size_t soff, eoff;
24 : :
25 : : /* Masks for start/end bundles */
26 : : uint32_t smask, emask;
27 : : };
28 : :
29 : 0 : static void setup_bundle_data(sys_bitarray_t *bitarray,
30 : : struct bundle_data *bd,
31 : : size_t offset, size_t num_bits)
32 : : {
33 : 0 : bd->sidx = offset / bundle_bitness(bitarray);
34 : 0 : bd->soff = offset % bundle_bitness(bitarray);
35 : :
36 : 0 : bd->eidx = (offset + num_bits - 1) / bundle_bitness(bitarray);
37 : 0 : bd->eoff = (offset + num_bits - 1) % bundle_bitness(bitarray);
38 : :
39 : 0 : bd->smask = ~(BIT(bd->soff) - 1);
40 : 0 : bd->emask = (BIT(bd->eoff) - 1) | BIT(bd->eoff);
41 : :
42 [ # # ]: 0 : if (bd->sidx == bd->eidx) {
43 : : /* The region lies within the same bundle. So combine the masks. */
44 : 0 : bd->smask &= bd->emask;
45 : : }
46 : 0 : }
47 : :
48 : : /*
49 : : * Find out if the bits in a region is all set or all clear.
50 : : *
51 : : * @param[in] bitarray Bitarray struct
52 : : * @param[in] offset Starting bit location
53 : : * @param[in] num_bits Number of bits in the region
54 : : * @param[in] match_set True if matching all set bits,
55 : : * False if matching all cleared bits
56 : : * @param[out] bd Data related to matching which can be
57 : : * used later to find out where the region
58 : : * lies in the bitarray bundles.
59 : : * @param[out] mismatch Offset to the mismatched bit.
60 : : * Can be NULL.
61 : : *
62 : : * @retval true If all bits are set or cleared
63 : : * @retval false Not all bits are set or cleared
64 : : */
65 : 0 : static bool match_region(sys_bitarray_t *bitarray, size_t offset,
66 : : size_t num_bits, bool match_set,
67 : : struct bundle_data *bd,
68 : : size_t *mismatch)
69 : : {
70 : : int idx;
71 : : uint32_t bundle;
72 : : uint32_t mismatch_bundle;
73 : : size_t mismatch_bundle_idx;
74 : : size_t mismatch_bit_off;
75 : :
76 : 0 : setup_bundle_data(bitarray, bd, offset, num_bits);
77 : :
78 [ # # ]: 0 : if (bd->sidx == bd->eidx) {
79 : 0 : bundle = bitarray->bundles[bd->sidx];
80 [ # # ]: 0 : if (!match_set) {
81 : 0 : bundle = ~bundle;
82 : : }
83 : :
84 [ # # ]: 0 : if ((bundle & bd->smask) != bd->smask) {
85 : : /* Not matching to mask. */
86 : 0 : mismatch_bundle = ~bundle & bd->smask;
87 : 0 : mismatch_bundle_idx = bd->sidx;
88 : 0 : goto mismatch;
89 : : } else {
90 : : /* Matching to mask. */
91 : 0 : goto out;
92 : : }
93 : : }
94 : :
95 : : /* Region lies in a number of bundles. Need to loop through them. */
96 : :
97 : : /* Start of bundles */
98 : 0 : bundle = bitarray->bundles[bd->sidx];
99 [ # # ]: 0 : if (!match_set) {
100 : 0 : bundle = ~bundle;
101 : : }
102 : :
103 [ # # ]: 0 : if ((bundle & bd->smask) != bd->smask) {
104 : : /* Start bundle not matching to mask. */
105 : 0 : mismatch_bundle = ~bundle & bd->smask;
106 : 0 : mismatch_bundle_idx = bd->sidx;
107 : 0 : goto mismatch;
108 : : }
109 : :
110 : : /* End of bundles */
111 : 0 : bundle = bitarray->bundles[bd->eidx];
112 [ # # ]: 0 : if (!match_set) {
113 : 0 : bundle = ~bundle;
114 : : }
115 : :
116 [ # # ]: 0 : if ((bundle & bd->emask) != bd->emask) {
117 : : /* End bundle not matching to mask. */
118 : 0 : mismatch_bundle = ~bundle & bd->emask;
119 : 0 : mismatch_bundle_idx = bd->eidx;
120 : 0 : goto mismatch;
121 : : }
122 : :
123 : : /* In-between bundles */
124 [ # # ]: 0 : for (idx = bd->sidx + 1; idx < bd->eidx; idx++) {
125 : : /* Note that this is opposite from above so that
126 : : * we are simply checking if bundle == 0.
127 : : */
128 : 0 : bundle = bitarray->bundles[idx];
129 [ # # ]: 0 : if (match_set) {
130 : 0 : bundle = ~bundle;
131 : : }
132 : :
133 [ # # ]: 0 : if (bundle != 0U) {
134 : : /* Bits in "between bundles" do not match */
135 : 0 : mismatch_bundle = ~bundle;
136 : 0 : mismatch_bundle_idx = idx;
137 : 0 : goto mismatch;
138 : : }
139 : : }
140 : :
141 : 0 : out:
142 : : /* All bits in region matched. */
143 : 0 : return true;
144 : :
145 : 0 : mismatch:
146 [ # # ]: 0 : if (mismatch != NULL) {
147 : : /* Must have at least 1 bit set to indicate
148 : : * where the mismatch is.
149 : : */
150 [ # # ]: 0 : __ASSERT_NO_MSG(mismatch_bundle != 0);
151 : :
152 : 0 : mismatch_bit_off = find_lsb_set(mismatch_bundle) - 1;
153 : 0 : mismatch_bit_off += mismatch_bundle_idx *
154 : : bundle_bitness(bitarray);
155 : 0 : *mismatch = (uint32_t)mismatch_bit_off;
156 : : }
157 : 0 : return false;
158 : : }
159 : :
160 : : /*
161 : : * Set or clear a region of bits.
162 : : *
163 : : * @param bitarray Bitarray struct
164 : : * @param offset Starting bit location
165 : : * @param num_bits Number of bits in the region
166 : : * @param to_set True if to set all bits.
167 : : * False if to clear all bits.
168 : : * @param bd Bundle data. Can reuse the output from
169 : : * match_region(). NULL if there is no
170 : : * prior call to match_region().
171 : : */
172 : 0 : static void set_region(sys_bitarray_t *bitarray, size_t offset,
173 : : size_t num_bits, bool to_set,
174 : : struct bundle_data *bd)
175 : : {
176 : : int idx;
177 : : struct bundle_data bdata;
178 : :
179 [ # # ]: 0 : if (bd == NULL) {
180 : 0 : bd = &bdata;
181 : 0 : setup_bundle_data(bitarray, bd, offset, num_bits);
182 : : }
183 : :
184 [ # # ]: 0 : if (bd->sidx == bd->eidx) {
185 : : /* Start/end at same bundle */
186 [ # # ]: 0 : if (to_set) {
187 : 0 : bitarray->bundles[bd->sidx] |= bd->smask;
188 : : } else {
189 : 0 : bitarray->bundles[bd->sidx] &= ~bd->smask;
190 : : }
191 : : } else {
192 : : /* Start/end at different bundle.
193 : : * So set/clear the bits in start and end bundles
194 : : * separately. For in-between bundles,
195 : : * set/clear all bits.
196 : : */
197 [ # # ]: 0 : if (to_set) {
198 : 0 : bitarray->bundles[bd->sidx] |= bd->smask;
199 : 0 : bitarray->bundles[bd->eidx] |= bd->emask;
200 [ # # ]: 0 : for (idx = bd->sidx + 1; idx < bd->eidx; idx++) {
201 : 0 : bitarray->bundles[idx] = ~0U;
202 : : }
203 : : } else {
204 : 0 : bitarray->bundles[bd->sidx] &= ~bd->smask;
205 : 0 : bitarray->bundles[bd->eidx] &= ~bd->emask;
206 [ # # ]: 0 : for (idx = bd->sidx + 1; idx < bd->eidx; idx++) {
207 : 0 : bitarray->bundles[idx] = 0U;
208 : : }
209 : : }
210 : : }
211 : 0 : }
212 : :
213 : 0 : int sys_bitarray_set_bit(sys_bitarray_t *bitarray, size_t bit)
214 : : {
215 : : k_spinlock_key_t key;
216 : : int ret;
217 : : size_t idx, off;
218 : :
219 : 0 : key = k_spin_lock(&bitarray->lock);
220 : :
221 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray != NULL);
222 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray->num_bits > 0);
223 : :
224 [ # # ]: 0 : if (bit >= bitarray->num_bits) {
225 : 0 : ret = -EINVAL;
226 : 0 : goto out;
227 : : }
228 : :
229 : 0 : idx = bit / bundle_bitness(bitarray);
230 : 0 : off = bit % bundle_bitness(bitarray);
231 : :
232 : 0 : bitarray->bundles[idx] |= BIT(off);
233 : :
234 : 0 : ret = 0;
235 : :
236 : 0 : out:
237 : 0 : k_spin_unlock(&bitarray->lock, key);
238 : 0 : return ret;
239 : : }
240 : :
241 : 0 : int sys_bitarray_clear_bit(sys_bitarray_t *bitarray, size_t bit)
242 : : {
243 : : k_spinlock_key_t key;
244 : : int ret;
245 : : size_t idx, off;
246 : :
247 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray != NULL);
248 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray->num_bits > 0);
249 : :
250 : 0 : key = k_spin_lock(&bitarray->lock);
251 : :
252 [ # # ]: 0 : if (bit >= bitarray->num_bits) {
253 : 0 : ret = -EINVAL;
254 : 0 : goto out;
255 : : }
256 : :
257 : 0 : idx = bit / bundle_bitness(bitarray);
258 : 0 : off = bit % bundle_bitness(bitarray);
259 : :
260 : 0 : bitarray->bundles[idx] &= ~BIT(off);
261 : :
262 : 0 : ret = 0;
263 : :
264 : 0 : out:
265 : 0 : k_spin_unlock(&bitarray->lock, key);
266 : 0 : return ret;
267 : : }
268 : :
269 : 0 : int sys_bitarray_test_bit(sys_bitarray_t *bitarray, size_t bit, int *val)
270 : : {
271 : : k_spinlock_key_t key;
272 : : int ret;
273 : : size_t idx, off;
274 : :
275 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray != NULL);
276 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray->num_bits > 0);
277 : :
278 : 0 : key = k_spin_lock(&bitarray->lock);
279 : :
280 [ # # ]: 0 : CHECKIF(val == NULL) {
281 : 0 : ret = -EINVAL;
282 : 0 : goto out;
283 : : }
284 : :
285 [ # # ]: 0 : if (bit >= bitarray->num_bits) {
286 : 0 : ret = -EINVAL;
287 : 0 : goto out;
288 : : }
289 : :
290 : 0 : idx = bit / bundle_bitness(bitarray);
291 : 0 : off = bit % bundle_bitness(bitarray);
292 : :
293 [ # # ]: 0 : if ((bitarray->bundles[idx] & BIT(off)) != 0) {
294 : 0 : *val = 1;
295 : : } else {
296 : 0 : *val = 0;
297 : : }
298 : :
299 : 0 : ret = 0;
300 : :
301 : 0 : out:
302 : 0 : k_spin_unlock(&bitarray->lock, key);
303 : 0 : return ret;
304 : : }
305 : :
306 : 0 : int sys_bitarray_test_and_set_bit(sys_bitarray_t *bitarray, size_t bit, int *prev_val)
307 : : {
308 : : k_spinlock_key_t key;
309 : : int ret;
310 : : size_t idx, off;
311 : :
312 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray != NULL);
313 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray->num_bits > 0);
314 : :
315 : 0 : key = k_spin_lock(&bitarray->lock);
316 : :
317 [ # # ]: 0 : CHECKIF(prev_val == NULL) {
318 : 0 : ret = -EINVAL;
319 : 0 : goto out;
320 : : }
321 : :
322 [ # # ]: 0 : if (bit >= bitarray->num_bits) {
323 : 0 : ret = -EINVAL;
324 : 0 : goto out;
325 : : }
326 : :
327 : 0 : idx = bit / bundle_bitness(bitarray);
328 : 0 : off = bit % bundle_bitness(bitarray);
329 : :
330 [ # # ]: 0 : if ((bitarray->bundles[idx] & BIT(off)) != 0) {
331 : 0 : *prev_val = 1;
332 : : } else {
333 : 0 : *prev_val = 0;
334 : : }
335 : :
336 : 0 : bitarray->bundles[idx] |= BIT(off);
337 : :
338 : 0 : ret = 0;
339 : :
340 : 0 : out:
341 : 0 : k_spin_unlock(&bitarray->lock, key);
342 : 0 : return ret;
343 : : }
344 : :
345 : 0 : int sys_bitarray_test_and_clear_bit(sys_bitarray_t *bitarray, size_t bit, int *prev_val)
346 : : {
347 : : k_spinlock_key_t key;
348 : : int ret;
349 : : size_t idx, off;
350 : :
351 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray != NULL);
352 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray->num_bits > 0);
353 : :
354 : 0 : key = k_spin_lock(&bitarray->lock);
355 : :
356 [ # # ]: 0 : CHECKIF(prev_val == NULL) {
357 : 0 : ret = -EINVAL;
358 : 0 : goto out;
359 : : }
360 : :
361 [ # # ]: 0 : if (bit >= bitarray->num_bits) {
362 : 0 : ret = -EINVAL;
363 : 0 : goto out;
364 : : }
365 : :
366 : 0 : idx = bit / bundle_bitness(bitarray);
367 : 0 : off = bit % bundle_bitness(bitarray);
368 : :
369 [ # # ]: 0 : if ((bitarray->bundles[idx] & BIT(off)) != 0) {
370 : 0 : *prev_val = 1;
371 : : } else {
372 : 0 : *prev_val = 0;
373 : : }
374 : :
375 : 0 : bitarray->bundles[idx] &= ~BIT(off);
376 : :
377 : 0 : ret = 0;
378 : :
379 : 0 : out:
380 : 0 : k_spin_unlock(&bitarray->lock, key);
381 : 0 : return ret;
382 : : }
383 : :
384 : 0 : int sys_bitarray_alloc(sys_bitarray_t *bitarray, size_t num_bits,
385 : : size_t *offset)
386 : : {
387 : : k_spinlock_key_t key;
388 : : uint32_t bit_idx;
389 : : int ret;
390 : : struct bundle_data bd;
391 : : size_t off_start, off_end;
392 : : size_t mismatch;
393 : :
394 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray != NULL);
395 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray->num_bits > 0);
396 : :
397 : 0 : key = k_spin_lock(&bitarray->lock);
398 : :
399 [ # # ]: 0 : CHECKIF(offset == NULL) {
400 : 0 : ret = -EINVAL;
401 : 0 : goto out;
402 : : }
403 : :
404 [ # # # # ]: 0 : if ((num_bits == 0) || (num_bits > bitarray->num_bits)) {
405 : 0 : ret = -EINVAL;
406 : 0 : goto out;
407 : : }
408 : :
409 : 0 : bit_idx = 0;
410 : :
411 : : /* Find the first non-allocated bit by looking at bundles
412 : : * instead of individual bits.
413 : : *
414 : : * On RISC-V 64-bit, it complains about undefined reference to `ffs`.
415 : : * So don't use this on RISCV64.
416 : : */
417 [ # # ]: 0 : for (ret = 0; ret < bitarray->num_bundles; ret++) {
418 [ # # ]: 0 : if (~bitarray->bundles[ret] == 0U) {
419 : : /* bundle is all 1s => all allocated, skip */
420 : 0 : bit_idx += bundle_bitness(bitarray);
421 : 0 : continue;
422 : : }
423 : :
424 [ # # ]: 0 : if (bitarray->bundles[ret] != 0U) {
425 : : /* Find the first free bit in bundle if not all free */
426 : 0 : off_start = find_lsb_set(~bitarray->bundles[ret]) - 1;
427 : 0 : bit_idx += off_start;
428 : : }
429 : :
430 : 0 : break;
431 : : }
432 : :
433 : 0 : off_end = bitarray->num_bits - num_bits;
434 : 0 : ret = -ENOSPC;
435 [ # # ]: 0 : while (bit_idx <= off_end) {
436 [ # # ]: 0 : if (match_region(bitarray, bit_idx, num_bits, false,
437 : : &bd, &mismatch)) {
438 : 0 : off_end = bit_idx + num_bits - 1;
439 : :
440 : 0 : set_region(bitarray, bit_idx, num_bits, true, &bd);
441 : :
442 : 0 : *offset = bit_idx;
443 : 0 : ret = 0;
444 : 0 : break;
445 : : }
446 : :
447 : : /* Fast-forward to the bit just after
448 : : * the mismatched bit.
449 : : */
450 : 0 : bit_idx = mismatch + 1;
451 : : }
452 : :
453 : 0 : out:
454 : 0 : k_spin_unlock(&bitarray->lock, key);
455 : 0 : return ret;
456 : : }
457 : :
458 : 0 : int sys_bitarray_free(sys_bitarray_t *bitarray, size_t num_bits,
459 : : size_t offset)
460 : : {
461 : : k_spinlock_key_t key;
462 : : int ret;
463 : 0 : size_t off_end = offset + num_bits - 1;
464 : : struct bundle_data bd;
465 : :
466 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray != NULL);
467 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray->num_bits > 0);
468 : :
469 : 0 : key = k_spin_lock(&bitarray->lock);
470 : :
471 [ # # ]: 0 : if ((num_bits == 0)
472 [ # # ]: 0 : || (num_bits > bitarray->num_bits)
473 [ # # ]: 0 : || (offset >= bitarray->num_bits)
474 [ # # ]: 0 : || (off_end >= bitarray->num_bits)) {
475 : 0 : ret = -EINVAL;
476 : 0 : goto out;
477 : : }
478 : :
479 : : /* Note that we need to make sure the bits in specified region
480 : : * (offset to offset + num_bits) are all allocated before we clear
481 : : * them.
482 : : */
483 [ # # ]: 0 : if (match_region(bitarray, offset, num_bits, true, &bd, NULL)) {
484 : 0 : set_region(bitarray, offset, num_bits, false, &bd);
485 : 0 : ret = 0;
486 : : } else {
487 : 0 : ret = -EFAULT;
488 : : }
489 : :
490 : 0 : out:
491 : 0 : k_spin_unlock(&bitarray->lock, key);
492 : 0 : return ret;
493 : : }
494 : :
495 : 0 : static bool is_region_set_clear(sys_bitarray_t *bitarray, size_t num_bits,
496 : : size_t offset, bool to_set)
497 : : {
498 : : bool ret;
499 : : struct bundle_data bd;
500 : 0 : size_t off_end = offset + num_bits - 1;
501 : 0 : k_spinlock_key_t key = k_spin_lock(&bitarray->lock);
502 : :
503 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray != NULL);
504 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray->num_bits > 0);
505 : :
506 [ # # ]: 0 : if ((num_bits == 0)
507 [ # # ]: 0 : || (num_bits > bitarray->num_bits)
508 [ # # ]: 0 : || (offset >= bitarray->num_bits)
509 [ # # ]: 0 : || (off_end >= bitarray->num_bits)) {
510 : 0 : ret = false;
511 : 0 : goto out;
512 : : }
513 : :
514 : 0 : ret = match_region(bitarray, offset, num_bits, to_set, &bd, NULL);
515 : :
516 : 0 : out:
517 : 0 : k_spin_unlock(&bitarray->lock, key);
518 : 0 : return ret;
519 : : }
520 : :
521 : 0 : bool sys_bitarray_is_region_set(sys_bitarray_t *bitarray, size_t num_bits,
522 : : size_t offset)
523 : : {
524 : 0 : return is_region_set_clear(bitarray, num_bits, offset, true);
525 : : }
526 : :
527 : 0 : bool sys_bitarray_is_region_cleared(sys_bitarray_t *bitarray, size_t num_bits,
528 : : size_t offset)
529 : : {
530 : 0 : return is_region_set_clear(bitarray, num_bits, offset, false);
531 : : }
532 : :
533 : 0 : static int set_clear_region(sys_bitarray_t *bitarray, size_t num_bits,
534 : : size_t offset, bool to_set)
535 : : {
536 : : int ret;
537 : 0 : size_t off_end = offset + num_bits - 1;
538 : 0 : k_spinlock_key_t key = k_spin_lock(&bitarray->lock);
539 : :
540 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray != NULL);
541 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray->num_bits > 0);
542 : :
543 [ # # ]: 0 : if ((num_bits == 0)
544 [ # # ]: 0 : || (num_bits > bitarray->num_bits)
545 [ # # ]: 0 : || (offset >= bitarray->num_bits)
546 [ # # ]: 0 : || (off_end >= bitarray->num_bits)) {
547 : 0 : ret = -EINVAL;
548 : 0 : goto out;
549 : : }
550 : :
551 : 0 : set_region(bitarray, offset, num_bits, to_set, NULL);
552 : 0 : ret = 0;
553 : :
554 : 0 : out:
555 : 0 : k_spin_unlock(&bitarray->lock, key);
556 : 0 : return ret;
557 : : }
558 : :
559 : 0 : int sys_bitarray_test_and_set_region(sys_bitarray_t *bitarray, size_t num_bits,
560 : : size_t offset, bool to_set)
561 : : {
562 : : int ret;
563 : : bool region_clear;
564 : : struct bundle_data bd;
565 : :
566 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray != NULL);
567 [ # # ]: 0 : __ASSERT_NO_MSG(bitarray->num_bits > 0);
568 : :
569 : 0 : size_t off_end = offset + num_bits - 1;
570 : 0 : k_spinlock_key_t key = k_spin_lock(&bitarray->lock);
571 : :
572 : :
573 [ # # ]: 0 : if ((num_bits == 0)
574 [ # # ]: 0 : || (num_bits > bitarray->num_bits)
575 [ # # ]: 0 : || (offset >= bitarray->num_bits)
576 [ # # ]: 0 : || (off_end >= bitarray->num_bits)) {
577 : 0 : ret = -EINVAL;
578 : 0 : goto out;
579 : : }
580 : :
581 : 0 : region_clear = match_region(bitarray, offset, num_bits, !to_set, &bd, NULL);
582 [ # # ]: 0 : if (region_clear) {
583 : 0 : set_region(bitarray, offset, num_bits, to_set, &bd);
584 : 0 : ret = 0;
585 : : } else {
586 : 0 : ret = -EEXIST;
587 : : }
588 : :
589 : 0 : out:
590 : 0 : k_spin_unlock(&bitarray->lock, key);
591 : 0 : return ret;
592 : : }
593 : :
594 : 0 : int sys_bitarray_set_region(sys_bitarray_t *bitarray, size_t num_bits,
595 : : size_t offset)
596 : : {
597 : 0 : return set_clear_region(bitarray, num_bits, offset, true);
598 : : }
599 : :
600 : 0 : int sys_bitarray_clear_region(sys_bitarray_t *bitarray, size_t num_bits,
601 : : size_t offset)
602 : : {
603 : 0 : return set_clear_region(bitarray, num_bits, offset, false);
604 : : }
|