-void mfree(void *md, void *ptr)
-{
- struct mdesc *mdp;
- register struct alignlist *l;
-
- if (ptr != NULL) {
- mdp = MD_TO_MDP(md);
- for (l = mdp->aligned_blocks; l != NULL; l = l->next) {
- if (l->aligned == ptr) {
- l->aligned = NULL; /* Mark the slot in the list as free. */
- ptr = l->exact;
- break;
- }
+// fprintf(stderr,"nfree:%zu capa:%d\n", mdp->heapinfo[block].busy_frag.nfree,(BLOCKSIZE >> type));
+ if (mdp->heapinfo[block].busy_frag.nfree ==
+ (BLOCKSIZE >> type) - 1) {
+ /* If all fragments of this block are free, remove this block from its swag and free the whole block. */
+ xbt_swag_remove(&mdp->heapinfo[block],&mdp->fraghead[type]);
+
+ /* pretend that this block is used and free it so that it gets properly coalesced with adjacent free blocks */
+ mdp->heapinfo[block].type = 0;
+ mdp->heapinfo[block].busy_block.size = 1;
+ mdp->heapinfo[block].busy_block.busy_size = 0;
+
+ /* Keep the statistics accurate. */
+ mdp -> heapstats.chunks_used++;
+ mdp -> heapstats.bytes_used += BLOCKSIZE;
+ mdp -> heapstats.chunks_free -= BLOCKSIZE >> type;
+ mdp -> heapstats.bytes_free -= BLOCKSIZE;
+
+ mfree((void *) mdp, (void *) ADDRESS(block));
+ } else if (mdp->heapinfo[block].busy_frag.nfree != 0) {
+ /* If some fragments of this block are free, you know what? I'm already happy. */
+ ++mdp->heapinfo[block].busy_frag.nfree;
+ } else {
+ /* No fragments of this block were free before the one we just released,
+ * so add this block to the swag and announce that
+ it is the first free fragment of this block. */
+ mdp->heapinfo[block].busy_frag.nfree = 1;
+ mdp->heapinfo[block].freehook.prev = NULL;
+ mdp->heapinfo[block].freehook.next = NULL;
+
+ xbt_swag_insert(&mdp->heapinfo[block],&mdp->fraghead[type]);