File indexing completed on 2025-05-11 08:24:18
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 #ifdef HAVE_CONFIG_H
0042 #include "config.h"
0043 #endif
0044
0045
0046
0047
0048 #define RTEMS_RFS_BITMAP_WARNINGS 0
0049
0050 #if RTEMS_RFS_BITMAP_WARNINGS
0051 #include <stdio.h>
0052 #endif
0053 #include <stdlib.h>
0054 #include <rtems/rfs/rtems-rfs-bitmaps.h>
0055
0056 #define rtems_rfs_bitmap_check(_c, _sm) \
0057 _Assert(_sm >= _c->search_bits && \
0058 _sm < (_c->search_bits + \
0059 rtems_rfs_bitmap_elements(rtems_rfs_bitmap_elements(_c->size))))
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 static bool
0071 rtems_rfs_bitmap_test (rtems_rfs_bitmap_element target,
0072 rtems_rfs_bitmap_bit bit)
0073 {
0074 return RTEMS_RFS_BITMAP_TEST_BIT (target, bit);
0075 }
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 static rtems_rfs_bitmap_element
0086 rtems_rfs_bitmap_set (rtems_rfs_bitmap_element target,
0087 rtems_rfs_bitmap_element bits)
0088 {
0089 return RTEMS_RFS_BITMAP_SET_BITS (target, bits);
0090 }
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100 static rtems_rfs_bitmap_element
0101 rtems_rfs_bitmap_clear (rtems_rfs_bitmap_element target,
0102 rtems_rfs_bitmap_element bits)
0103 {
0104 return RTEMS_RFS_BITMAP_CLEAR_BITS (target, bits);
0105 }
0106
0107
0108
0109
0110
0111
0112 static rtems_rfs_bitmap_element
0113 rtems_rfs_bitmap_merge (rtems_rfs_bitmap_element bits1,
0114 rtems_rfs_bitmap_element bits2,
0115 rtems_rfs_bitmap_element mask)
0116 {
0117
0118
0119
0120
0121 bits1 &= mask;
0122 bits2 &= RTEMS_RFS_BITMAP_INVERT_MASK (mask);
0123 return bits1 | bits2;
0124 }
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 static bool
0136 rtems_rfs_bitmap_match (rtems_rfs_bitmap_element bits1,
0137 rtems_rfs_bitmap_element bits2)
0138 {
0139 return bits1 ^ bits2 ? false : true;
0140 }
0141
0142 #if RTEMS_NOT_USED_BUT_KEPT
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153 static bool
0154 rtems_rfs_bitmap_match_masked (rtems_rfs_bitmap_element mask,
0155 rtems_rfs_bitmap_element bits1,
0156 rtems_rfs_bitmap_element bits2)
0157 {
0158 return (bits1 ^ bits2) & mask ? false : true;
0159 }
0160 #endif
0161
0162
0163
0164
0165
0166
0167
0168
0169 static int
0170 rtems_rfs_bitmap_load_map (rtems_rfs_bitmap_control* control,
0171 rtems_rfs_bitmap_map* map)
0172 {
0173 int rc;
0174
0175 if (!control->buffer)
0176 return ENXIO;
0177
0178 *map = NULL;
0179
0180 rc = rtems_rfs_buffer_handle_request (control->fs,
0181 control->buffer,
0182 control->block,
0183 true);
0184 if (rc)
0185 return rc;
0186
0187 *map = rtems_rfs_buffer_data (control->buffer);
0188 return 0;
0189 }
0190
0191 rtems_rfs_bitmap_element
0192 rtems_rfs_bitmap_mask (unsigned int size)
0193 {
0194 rtems_rfs_bitmap_element mask = RTEMS_RFS_BITMAP_ELEMENT_FULL_MASK;
0195 mask >>= (rtems_rfs_bitmap_element_bits () - size);
0196 return mask;
0197 }
0198
0199 rtems_rfs_bitmap_element
0200 rtems_rfs_bitmap_mask_section (unsigned int start, unsigned int end)
0201 {
0202 rtems_rfs_bitmap_element mask = 0;
0203 if (end > start)
0204 mask = rtems_rfs_bitmap_mask (end - start) << start;
0205 return mask;
0206 }
0207
0208 int
0209 rtems_rfs_bitmap_map_set (rtems_rfs_bitmap_control* control,
0210 rtems_rfs_bitmap_bit bit)
0211 {
0212 rtems_rfs_bitmap_map map;
0213 rtems_rfs_bitmap_map search_map;
0214 int index;
0215 int offset;
0216 int rc;
0217 rtems_rfs_bitmap_element element;
0218
0219 rc = rtems_rfs_bitmap_load_map (control, &map);
0220 if (rc > 0)
0221 return rc;
0222
0223 if (bit >= control->size)
0224 return EINVAL;
0225
0226 search_map = control->search_bits;
0227 index = rtems_rfs_bitmap_map_index (bit);
0228 offset = rtems_rfs_bitmap_map_offset (bit);
0229 element = map[index];
0230 map[index] = rtems_rfs_bitmap_set (element, 1 << offset);
0231
0232
0233
0234
0235
0236 if (rtems_rfs_bitmap_match(element, map[index]))
0237 return 0;
0238
0239 control->free--;
0240
0241 rtems_rfs_buffer_mark_dirty (control->buffer);
0242 if (rtems_rfs_bitmap_match(map[index], RTEMS_RFS_BITMAP_ELEMENT_SET))
0243 {
0244 bit = index;
0245 index = rtems_rfs_bitmap_map_index (bit);
0246 offset = rtems_rfs_bitmap_map_offset (bit);
0247 search_map[index] = rtems_rfs_bitmap_set (search_map[index], 1 << offset);
0248 rtems_rfs_bitmap_check(control, &search_map[index]);
0249 }
0250
0251 return 0;
0252 }
0253
0254 int
0255 rtems_rfs_bitmap_map_clear (rtems_rfs_bitmap_control* control,
0256 rtems_rfs_bitmap_bit bit)
0257 {
0258 rtems_rfs_bitmap_map map;
0259 rtems_rfs_bitmap_map search_map;
0260 int index;
0261 int offset;
0262 int rc;
0263 rtems_rfs_bitmap_element element;
0264
0265 rc = rtems_rfs_bitmap_load_map (control, &map);
0266 if (rc > 0)
0267 return rc;
0268
0269 if (bit >= control->size)
0270 return EINVAL;
0271
0272 search_map = control->search_bits;
0273 index = rtems_rfs_bitmap_map_index (bit);
0274 offset = rtems_rfs_bitmap_map_offset (bit);
0275 element = map[index];
0276 map[index] = rtems_rfs_bitmap_clear (element, 1 << offset);
0277
0278
0279
0280
0281
0282 if (rtems_rfs_bitmap_match(element, map[index]))
0283 return 0;
0284
0285 bit = index;
0286 index = rtems_rfs_bitmap_map_index (bit);
0287 offset = rtems_rfs_bitmap_map_offset(bit);
0288 search_map[index] = rtems_rfs_bitmap_clear (search_map[index], 1 << offset);
0289 rtems_rfs_bitmap_check(control, &search_map[index]);
0290 rtems_rfs_buffer_mark_dirty (control->buffer);
0291 control->free++;
0292
0293 return 0;
0294 }
0295
0296 int
0297 rtems_rfs_bitmap_map_test (rtems_rfs_bitmap_control* control,
0298 rtems_rfs_bitmap_bit bit,
0299 bool* state)
0300 {
0301 rtems_rfs_bitmap_map map;
0302 int index;
0303 int rc;
0304 rc = rtems_rfs_bitmap_load_map (control, &map);
0305 if (rc > 0)
0306 return rc;
0307 if (bit >= control->size)
0308 return EINVAL;
0309 index = rtems_rfs_bitmap_map_index (bit);
0310 *state = rtems_rfs_bitmap_test (map[index], bit);
0311 return 0;
0312 }
0313
0314 int
0315 rtems_rfs_bitmap_map_set_all (rtems_rfs_bitmap_control* control)
0316 {
0317 rtems_rfs_bitmap_map map;
0318 size_t elements;
0319 int e;
0320 int rc;
0321
0322 rc = rtems_rfs_bitmap_load_map (control, &map);
0323 if (rc > 0)
0324 return rc;
0325
0326 elements = rtems_rfs_bitmap_elements (control->size);
0327
0328 control->free = 0;
0329
0330 for (e = 0; e < elements; e++)
0331 map[e] = RTEMS_RFS_BITMAP_ELEMENT_SET;
0332
0333 elements = rtems_rfs_bitmap_elements (elements);
0334
0335 for (e = 0; e < elements; e++)
0336 control->search_bits[e] = RTEMS_RFS_BITMAP_ELEMENT_SET;
0337
0338 rtems_rfs_buffer_mark_dirty (control->buffer);
0339
0340 return 0;
0341 }
0342
0343 int
0344 rtems_rfs_bitmap_map_clear_all (rtems_rfs_bitmap_control* control)
0345 {
0346 rtems_rfs_bitmap_map map;
0347 rtems_rfs_bitmap_bit last_search_bit;
0348 size_t elements;
0349 int e;
0350 int rc;
0351
0352 rc = rtems_rfs_bitmap_load_map (control, &map);
0353 if (rc > 0)
0354 return rc;
0355
0356 elements = rtems_rfs_bitmap_elements (control->size);
0357
0358 control->free = control->size;
0359
0360 for (e = 0; e < elements; e++)
0361 map[e] = RTEMS_RFS_BITMAP_ELEMENT_CLEAR;
0362
0363
0364
0365
0366
0367 last_search_bit = rtems_rfs_bitmap_map_offset (elements);
0368
0369 if (last_search_bit == 0)
0370 last_search_bit = rtems_rfs_bitmap_element_bits ();
0371
0372 elements = rtems_rfs_bitmap_elements (elements);
0373
0374 for (e = 0; e < (elements - 1); e++)
0375 control->search_bits[e] = RTEMS_RFS_BITMAP_ELEMENT_CLEAR;
0376
0377 control->search_bits[elements - 1] =
0378 rtems_rfs_bitmap_merge (RTEMS_RFS_BITMAP_ELEMENT_CLEAR,
0379 RTEMS_RFS_BITMAP_ELEMENT_SET,
0380 rtems_rfs_bitmap_mask (last_search_bit));
0381
0382 rtems_rfs_buffer_mark_dirty (control->buffer);
0383
0384 return 0;
0385 }
0386
0387 static int
0388 rtems_rfs_search_map_for_clear_bit (rtems_rfs_bitmap_control* control,
0389 rtems_rfs_bitmap_bit* bit,
0390 bool* found,
0391 size_t window,
0392 int direction)
0393 {
0394 rtems_rfs_bitmap_map map;
0395 rtems_rfs_bitmap_bit test_bit;
0396 rtems_rfs_bitmap_bit end_bit;
0397 rtems_rfs_bitmap_element* search_bits;
0398 int search_index;
0399 int search_offset;
0400 rtems_rfs_bitmap_element* map_bits;
0401 int map_index;
0402 int map_offset;
0403 int rc;
0404
0405 *found = false;
0406
0407
0408
0409
0410 rc = rtems_rfs_bitmap_load_map (control, &map);
0411 if (rc > 0)
0412 return rc;
0413
0414
0415
0416
0417 test_bit = *bit;
0418 end_bit = test_bit + (window * direction);
0419
0420 if (end_bit < 0)
0421 end_bit = 0;
0422 else if (end_bit >= control->size)
0423 end_bit = control->size - 1;
0424
0425 map_index = rtems_rfs_bitmap_map_index (test_bit);
0426 map_offset = rtems_rfs_bitmap_map_offset (test_bit);
0427 search_index = rtems_rfs_bitmap_map_index (map_index);
0428 search_offset = rtems_rfs_bitmap_map_offset (map_index);
0429
0430 search_bits = &control->search_bits[search_index];
0431 map_bits = &map[map_index];
0432
0433
0434
0435
0436 do
0437 {
0438
0439
0440
0441
0442
0443 if (!rtems_rfs_bitmap_match (*search_bits, RTEMS_RFS_BITMAP_ELEMENT_SET))
0444 {
0445 while ((search_offset >= 0)
0446 && (search_offset < rtems_rfs_bitmap_element_bits ()))
0447 {
0448 if (!rtems_rfs_bitmap_test (*search_bits, search_offset))
0449 {
0450
0451
0452
0453
0454 while ((map_offset >= 0)
0455 && (map_offset < rtems_rfs_bitmap_element_bits ()))
0456 {
0457 if (!rtems_rfs_bitmap_test (*map_bits, map_offset))
0458 {
0459 *map_bits = rtems_rfs_bitmap_set (*map_bits, 1 << map_offset);
0460 if (rtems_rfs_bitmap_match(*map_bits,
0461 RTEMS_RFS_BITMAP_ELEMENT_SET))
0462 *search_bits = rtems_rfs_bitmap_set (*search_bits,
0463 1 << search_offset);
0464 control->free--;
0465 *bit = test_bit;
0466 *found = true;
0467 rtems_rfs_buffer_mark_dirty (control->buffer);
0468 return 0;
0469 }
0470
0471 if (test_bit == end_bit)
0472 break;
0473
0474 map_offset += direction;
0475 test_bit += direction;
0476 }
0477 }
0478
0479 map_bits += direction;
0480 map_index += direction;
0481 map_offset = direction > 0 ? 0 : rtems_rfs_bitmap_element_bits () - 1;
0482
0483 test_bit = (map_index * rtems_rfs_bitmap_element_bits ()) + map_offset;
0484
0485 search_offset += direction;
0486
0487 if (((direction < 0) && (test_bit <= end_bit))
0488 || ((direction > 0) && (test_bit >= end_bit)))
0489 break;
0490 }
0491 }
0492 else
0493 {
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504 rtems_rfs_bitmap_bit bits_skipped;
0505 test_bit &= ~((1 << RTEMS_RFS_ELEMENT_BITS_POWER_2) - 1);
0506 if (direction > 0)
0507 {
0508 bits_skipped = rtems_rfs_bitmap_element_bits () - search_offset;
0509 test_bit += bits_skipped * rtems_rfs_bitmap_element_bits ();
0510 map_offset = 0;
0511 }
0512 else
0513 {
0514 bits_skipped = search_offset + 1;
0515
0516
0517
0518
0519 test_bit -= ((bits_skipped - 1) * rtems_rfs_bitmap_element_bits ()) + 1;
0520 map_offset = rtems_rfs_bitmap_element_bits () - 1;
0521 }
0522 map_bits += direction * bits_skipped;
0523 map_index += direction * bits_skipped;
0524 }
0525
0526 search_bits += direction;
0527 search_offset = direction > 0 ? 0 : rtems_rfs_bitmap_element_bits () - 1;
0528 }
0529 while (((direction < 0) && (test_bit >= end_bit))
0530 || ((direction > 0) && (test_bit <= end_bit)));
0531
0532 return 0;
0533 }
0534
0535 int
0536 rtems_rfs_bitmap_map_alloc (rtems_rfs_bitmap_control* control,
0537 rtems_rfs_bitmap_bit seed,
0538 bool* allocated,
0539 rtems_rfs_bitmap_bit* bit)
0540 {
0541 rtems_rfs_bitmap_bit upper_seed;
0542 rtems_rfs_bitmap_bit lower_seed;
0543 rtems_rfs_bitmap_bit window;
0544 int rc = 0;
0545
0546
0547
0548
0549 *allocated = false;
0550
0551
0552
0553
0554
0555 window = RTEMS_RFS_BITMAP_SEARCH_WINDOW;
0556
0557
0558
0559
0560
0561
0562
0563
0564 upper_seed = seed;
0565 lower_seed = seed;
0566
0567
0568
0569
0570
0571
0572
0573
0574 while (((upper_seed >= 0) && (upper_seed < control->size))
0575 || ((lower_seed >= 0) && (lower_seed < control->size)))
0576 {
0577
0578
0579
0580 if (upper_seed < control->size)
0581 {
0582 *bit = upper_seed;
0583 rc = rtems_rfs_search_map_for_clear_bit (control, bit, allocated,
0584 window, 1);
0585 if ((rc > 0) || *allocated)
0586 break;
0587 }
0588
0589 if (lower_seed >= 0)
0590 {
0591 *bit = lower_seed;
0592 rc = rtems_rfs_search_map_for_clear_bit (control, bit, allocated,
0593 window, -1);
0594 if ((rc > 0) || *allocated)
0595 break;
0596 }
0597
0598
0599
0600
0601
0602 if (upper_seed < control->size)
0603 upper_seed += window;
0604 if (lower_seed >= 0)
0605 lower_seed -= window;
0606 }
0607
0608 return 0;
0609 }
0610
0611 int
0612 rtems_rfs_bitmap_create_search (rtems_rfs_bitmap_control* control)
0613 {
0614 rtems_rfs_bitmap_map search_map;
0615 rtems_rfs_bitmap_map map;
0616 size_t size;
0617 rtems_rfs_bitmap_bit bit;
0618 int rc;
0619
0620 rc = rtems_rfs_bitmap_load_map (control, &map);
0621 if (rc > 0)
0622 return rc;
0623
0624 control->free = 0;
0625 search_map = control->search_bits;
0626 size = control->size;
0627 bit = 0;
0628
0629 rtems_rfs_bitmap_check(control, search_map);
0630 *search_map = RTEMS_RFS_BITMAP_ELEMENT_CLEAR;
0631 while (size)
0632 {
0633 rtems_rfs_bitmap_element bits;
0634 int available;
0635 if (size < rtems_rfs_bitmap_element_bits ())
0636 {
0637 bits = rtems_rfs_bitmap_merge (*map,
0638 RTEMS_RFS_BITMAP_ELEMENT_SET,
0639 rtems_rfs_bitmap_mask_section (0, size));
0640 available = size;
0641 }
0642 else
0643 {
0644 bits = *map;
0645 available = rtems_rfs_bitmap_element_bits ();
0646 }
0647
0648 if (rtems_rfs_bitmap_match (bits, RTEMS_RFS_BITMAP_ELEMENT_SET))
0649 rtems_rfs_bitmap_set (*search_map, bit);
0650 else
0651 {
0652 int b;
0653 for (b = 0; b < available; b++)
0654 if (!rtems_rfs_bitmap_test (bits, b))
0655 control->free++;
0656 }
0657
0658 size -= available;
0659
0660
0661 if (bit == (rtems_rfs_bitmap_element_bits () - 1))
0662 {
0663 bit = 0;
0664 if (size > 0)
0665 {
0666 search_map++;
0667 rtems_rfs_bitmap_check(control, search_map);
0668 *search_map = RTEMS_RFS_BITMAP_ELEMENT_CLEAR;
0669 }
0670 }
0671 else
0672 bit++;
0673 map++;
0674 }
0675
0676 return 0;
0677 }
0678
0679 int
0680 rtems_rfs_bitmap_open (rtems_rfs_bitmap_control* control,
0681 rtems_rfs_file_system* fs,
0682 rtems_rfs_buffer_handle* buffer,
0683 size_t size,
0684 rtems_rfs_buffer_block block)
0685 {
0686 size_t elements = rtems_rfs_bitmap_elements (size);
0687
0688 control->buffer = buffer;
0689 control->fs = fs;
0690 control->block = block;
0691 control->size = size;
0692
0693 elements = rtems_rfs_bitmap_elements (elements);
0694 control->search_bits = malloc (elements * sizeof (rtems_rfs_bitmap_element));
0695
0696 if (!control->search_bits)
0697 return ENOMEM;
0698
0699 return rtems_rfs_bitmap_create_search (control);
0700 }
0701
0702 int
0703 rtems_rfs_bitmap_close (rtems_rfs_bitmap_control* control)
0704 {
0705 free (control->search_bits);
0706 return 0;
0707 }