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
12#ifdef DEBUG_SLAB_DEEP
13bool slab_check_traces(struct slab *s) {
14 /* Verify that it begins at the end of the page array */
15 slab_check_assert_return_false(
16 s->bitmap == ((uint8_t *) s->traces +
17 sizeof(stack_handle_t) * s->parent_cache->objs_per_slab));
18
19 return true;
20}
21#else
22bool slab_check_traces(struct slab *s) {
23 (void) s;
24 return true;
25}
26#endif
27
28bool slab_check_reset_slab(struct slab *slab) {
29 slab_check_assert_return_false(slab->state == SLAB_FREE);
30 slab_check_assert_return_false(slab->bitmap == NULL);
31 slab_check_assert_return_false(slab->used == 0);
32 return true;
33}
34
35bool slab_check_bitmap(struct slab *slab) {
36 slab_check_assert_return_false(slab->bitmap != NULL);
37 struct slab_cache *cache = slab->parent_cache;
38 size_t bitmap_bytes = SLAB_BITMAP_BYTES_FOR(cache->objs_per_slab);
39 size_t expected_set_bits = slab->used;
40 size_t set_bits_accumulator = 0;
41
42 /* Bitmap is rounded up to 64 bit words, ones past objs_per_slab are set */
43 for (size_t i = 0; i < cache->objs_per_slab; i++) {
44 if (slab->bitmap[i / 8] & (uint8_t) (1U << (i % 8)))
45 set_bits_accumulator++;
46 }
47 (void) bitmap_bytes;
48
49 slab_check_assert_return_false(expected_set_bits == set_bits_accumulator);
50
51 return true;
52}
53
54bool slab_check_meta(struct slab *slab) {
55 slab_check_assert_return_false(slab->mem);
56 slab_check_assert_return_false(slab->parent_cache->pages_per_slab > 0);
57 return true;
58}
59
60bool slab_check(struct slab *slab) {
61 switch (slab->state) {
62 case SLAB_FREE:
63 case SLAB_PARTIAL:
64 case SLAB_IN_GC:
65 case SLAB_FULL: break;
66 default: return false; /* Invalid state */
67 }
68
69 struct slab_cache *cache = slab->parent_cache;
70 if (!cache)
71 return slab_check_reset_slab(slab);
72
73 slab_check_assert_return_false(slab_check_traces(slab));
74 slab_check_assert_return_false(slab_check_bitmap(slab));
75 slab_check_assert_return_false(slab_check_meta(slab));
76 return true;
77}
78