1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright 2015-2020, Intel Corporation */
5 * heap_layout.h -- internal definitions for heap layout
8 #ifndef LIBPMEMOBJ_HEAP_LAYOUT_H
9 #define LIBPMEMOBJ_HEAP_LAYOUT_H 1
21 #define MAX_CHUNK (UINT16_MAX - 7) /* has to be multiple of 8 */
22 #define CHUNK_BASE_ALIGNMENT 1024
23 #define CHUNKSIZE ((size_t)1024 * 256) /* 256 kilobytes */
24 #define MAX_MEMORY_BLOCK_SIZE (MAX_CHUNK * CHUNKSIZE)
25 #define HEAP_SIGNATURE_LEN 16
26 #define HEAP_SIGNATURE "MEMORY_HEAP_HDR\0"
27 #define ZONE_HEADER_MAGIC 0xC3F0A2D2
28 #define ZONE_MIN_SIZE (sizeof(struct zone) + sizeof(struct chunk))
29 #define ZONE_MAX_SIZE (sizeof(struct zone) + sizeof(struct chunk) * MAX_CHUNK)
30 #define HEAP_MIN_SIZE (sizeof(struct heap_layout) + ZONE_MIN_SIZE)
32 /* Base bitmap values, relevant for both normal and flexible bitmaps */
33 #define RUN_BITS_PER_VALUE 64U
34 #define RUN_BASE_METADATA_VALUES\
35 ((unsigned)(sizeof(struct chunk_run_header) / sizeof(uint64_t)))
36 #define RUN_BASE_METADATA_SIZE (sizeof(struct chunk_run_header))
38 #define RUN_CONTENT_SIZE (CHUNKSIZE - RUN_BASE_METADATA_SIZE)
41 * Calculates the size in bytes of a single run instance, including bitmap
43 #define RUN_CONTENT_SIZE_BYTES(size_idx)\
44 (RUN_CONTENT_SIZE + (((size_idx) - 1) * CHUNKSIZE))
46 /* Default bitmap values, specific for old, non-flexible, bitmaps */
47 #define RUN_DEFAULT_METADATA_VALUES 40 /* in 8 byte words, 320 bytes total */
48 #define RUN_DEFAULT_BITMAP_VALUES \
49 (RUN_DEFAULT_METADATA_VALUES - RUN_BASE_METADATA_VALUES)
50 #define RUN_DEFAULT_BITMAP_SIZE (sizeof(uint64_t) * RUN_DEFAULT_BITMAP_VALUES)
51 #define RUN_DEFAULT_BITMAP_NBITS\
52 (RUN_BITS_PER_VALUE * RUN_DEFAULT_BITMAP_VALUES)
53 #define RUN_DEFAULT_SIZE \
54 (CHUNKSIZE - RUN_BASE_METADATA_SIZE - RUN_DEFAULT_BITMAP_SIZE)
57 * Calculates the size in bytes of a single run instance, without bitmap,
58 * but only for the default fixed-bitmap algorithm
60 #define RUN_DEFAULT_SIZE_BYTES(size_idx)\
61 (RUN_DEFAULT_SIZE + (((size_idx) - 1) * CHUNKSIZE))
63 #define CHUNK_MASK ((CHUNKSIZE) - 1)
64 #define CHUNK_ALIGN_UP(value) ((((value) + CHUNK_MASK) & ~CHUNK_MASK))
67 CHUNK_FLAG_COMPACT_HEADER
= 0x0001,
68 CHUNK_FLAG_HEADER_NONE
= 0x0002,
69 CHUNK_FLAG_ALIGNED
= 0x0004,
70 CHUNK_FLAG_FLEX_BITMAP
= 0x0008,
73 #define CHUNK_FLAGS_ALL_VALID (\
74 CHUNK_FLAG_COMPACT_HEADER |\
75 CHUNK_FLAG_HEADER_NONE |\
77 CHUNK_FLAG_FLEX_BITMAP\
82 CHUNK_TYPE_FOOTER
, /* not actual chunk type */
92 uint8_t data
[CHUNKSIZE
];
95 struct chunk_run_header
{
97 uint64_t alignment
; /* valid only /w CHUNK_FLAG_ALIGNED */
101 struct chunk_run_header hdr
;
102 uint8_t content
[RUN_CONTENT_SIZE
]; /* bitmap + data */
105 struct chunk_header
{
114 uint8_t reserved
[56];
118 struct zone_header header
;
119 struct chunk_header chunk_headers
[MAX_CHUNK
];
120 struct chunk chunks
[];
124 char signature
[HEAP_SIGNATURE_LEN
];
127 uint64_t unused
; /* might be garbage */
129 uint64_t chunks_per_zone
;
130 uint8_t reserved
[960];
135 struct heap_header header
;
136 struct zone zone0
; /* first element of zones array */
139 #define ALLOC_HDR_SIZE_SHIFT (48ULL)
140 #define ALLOC_HDR_FLAGS_MASK (((1ULL) << ALLOC_HDR_SIZE_SHIFT) - 1)
142 struct allocation_header_legacy
{
150 #define ALLOC_HDR_COMPACT_SIZE sizeof(struct allocation_header_compact)
152 struct allocation_header_compact
{
165 static const size_t header_type_to_size
[MAX_HEADER_TYPES
] = {
166 sizeof(struct allocation_header_legacy
),
167 sizeof(struct allocation_header_compact
),
171 static const enum chunk_flags header_type_to_flag
[MAX_HEADER_TYPES
] = {
173 CHUNK_FLAG_COMPACT_HEADER
,
174 CHUNK_FLAG_HEADER_NONE
177 static inline struct zone
*
178 ZID_TO_ZONE(struct heap_layout
*layout
, size_t zone_id
)
180 return (struct zone
*)
181 ((uintptr_t)&layout
->zone0
+ ZONE_MAX_SIZE
* zone_id
);
184 static inline struct chunk_header
*
185 GET_CHUNK_HDR(struct heap_layout
*layout
, size_t zone_id
, unsigned chunk_id
)
187 return &ZID_TO_ZONE(layout
, zone_id
)->chunk_headers
[chunk_id
];
190 static inline struct chunk
*
191 GET_CHUNK(struct heap_layout
*layout
, size_t zone_id
, unsigned chunk_id
)
193 return &ZID_TO_ZONE(layout
, zone_id
)->chunks
[chunk_id
];
196 static inline struct chunk_run
*
197 GET_CHUNK_RUN(struct heap_layout
*layout
, size_t zone_id
, unsigned chunk_id
)
199 return (struct chunk_run
*)GET_CHUNK(layout
, zone_id
, chunk_id
);