1#include "internal.h"
2#include <math/bit_ops.h>
3
4#define slab_check_assert_return_false(statement) \
5 do { \
6 if (!(statement)) { \
7 printf("%s is false\n", #statement); \
8 return false; \
9 } \
10 } while (0)
11
12bool slab_check_reset_slab(struct slab *slab) {
13 slab_check_assert_return_false(slab->state == SLAB_FREE);
14 slab_check_assert_return_false(slab->bitmap == NULL);
15 slab_check_assert_return_false(slab->used == 0);
16 return true;
17}
18
19bool slab_check_bitmap(struct slab *slab) {
20 slab_check_assert_return_false(slab->bitmap != NULL);
21 struct slab_cache *cache = slab->parent_cache;
22 size_t bitmap_bytes = SLAB_BITMAP_BYTES_FOR(cache->objs_per_slab);
23 size_t expected_set_bits = slab->used;
24 size_t set_bits_accumulator = 0;
25
26 for (size_t i = 0; i < bitmap_bytes; i++) {
27 uint8_t byte = slab->bitmap[i];
28 set_bits_accumulator += popcount(n: (size_t) byte);
29 }
30
31 slab_check_assert_return_false(expected_set_bits == set_bits_accumulator);
32
33 return true;
34}
35
36bool slab_check_meta(struct slab *slab) {
37 slab_check_assert_return_false(slab->mem);
38 slab_check_assert_return_false(slab->parent_cache->pages_per_slab > 0);
39 return true;
40}
41
42bool slab_check(struct slab *slab) {
43 switch (slab->state) {
44 case SLAB_FREE:
45 case SLAB_PARTIAL:
46 case SLAB_IN_GC:
47 case SLAB_FULL: break;
48 default: return false; /* Invalid state */
49 }
50
51 struct slab_cache *cache = slab->parent_cache;
52 if (!cache)
53 return slab_check_reset_slab(slab);
54
55 slab_check_assert_return_false(slab_check_bitmap(slab));
56 slab_check_assert_return_false(slab_check_meta(slab));
57 return true;
58}
59