+typedef struct s_heap_area{
+ int valid;
+ int block;
+ int fragment;
+}s_heap_area_t, *heap_area_t;
+
+typedef struct s_heap_area_pair{
+ int block1;
+ int fragment1;
+ int block2;
+ int fragment2;
+}s_heap_area_pair_t, *heap_area_pair_t;
+
+#define MMALLOC_TYPE_HEAPINFO (-2)
+#define MMALLOC_TYPE_FREE (-1)
+#define MMALLOC_TYPE_UNFRAGMENTED 0
+/* >0 values are fragmented blocks */
+
+/* Data structure giving per-block information.
+ *
+ * There is one such structure in the mdp->heapinfo array per block used in that heap,
+ * the array index is the block number.
+ *
+ * There is several types of blocks in memory:
+ * - full busy blocks: used when we are asked to malloc a block which size is > BLOCKSIZE/2
+ * In this situation, the full block is given to the malloc.
+ *
+ * - fragmented busy blocks: when asked for smaller amount of memory.
+ * Fragment sizes are only power of 2. When looking for such a free fragment,
+ * we get one from mdp->fraghead (that contains a linked list of blocks fragmented at that
+ * size and containing a free fragment), or we get a fresh block that we fragment.
+ *
+ * - free blocks are grouped by clusters, that are chained together.
+ * When looking for free blocks, we traverse the mdp->heapinfo looking
+ * for a cluster of free blocks that would be large enough.
+ *
+ * The size of the cluster is only to be trusted in the first block of the cluster, not in the middle blocks.
+ *
+ * The type field is consistently updated for every blocks, even within clusters of blocks.
+ * You can crawl the array and rely on that value.
+ *
+ */
+typedef struct {
+ s_xbt_swag_hookup_t freehook; /* to register this block as having empty frags when needed */
+ int type; /* 0: busy large block
+ >0: busy fragmented (fragments of size 2^type bytes)
+ <0: free block */
+
+ union {
+ /* Heap information for a busy block. */
+ struct {
+ size_t nfree; /* Free fragments in a fragmented block. */
+ ssize_t frag_size[MAX_FRAGMENT_PER_BLOCK];
+ //void *bt[MAX_FRAGMENT_PER_BLOCK][XBT_BACKTRACE_SIZE]; /* Where it was malloced (or realloced lastly) */
+ int ignore[MAX_FRAGMENT_PER_BLOCK];
+ } busy_frag;
+ struct {
+ size_t size; /* Size (in blocks) of a large cluster. */
+ size_t busy_size; /* Actually used space, in bytes */
+ //void *bt[XBT_BACKTRACE_SIZE]; /* Where it was malloced (or realloced lastly) */
+ //int bt_size;
+ int ignore;
+ } busy_block;
+ /* Heap information for a free block (that may be the first of a free cluster). */
+ struct {
+ size_t size; /* Size (in blocks) of a free cluster. */
+ size_t next; /* Index of next free cluster. */
+ size_t prev; /* Index of previous free cluster. */
+ } free_block;
+ };
+} malloc_info;