void sm_free_pool(struct smalloc_pool *spool, void *p) { struct smalloc_hdr *shdr; char *s; if (!smalloc_verify_pool(spool)) { errno = EINVAL; return; } if (!p) return; shdr = USER_TO_HEADER(p); if (smalloc_is_alloc(spool, shdr)) { if (spool->do_zero) memset(p, 0, shdr->rsz); s = CHAR_PTR(p); s += shdr->usz; memset(s, 0, HEADER_SZ); if (spool->do_zero) memset(s+HEADER_SZ, 0, shdr->rsz - shdr->usz); memset(shdr, 0, HEADER_SZ); if (!spool->do_zero) { memcpy(shdr, "FREED MEMORY", 12); memcpy(s, "FREEDBARRIER", 12); } return; } smalloc_UB(spool, p); return; }
/* }}} */ static XC_ALLOCATOR_FREE(xc_allocator_bestfit_free) /* {{{ return block size freed */ { xc_allocator_bestfit_block_t *cur, *b; int size; cur = (xc_allocator_bestfit_block_t *) (CHAR_PTR(p) - BLOCK_HEADER_SIZE()); TRACE("freeing: %p, size=%lu", p, cur->size); xc_block_check(cur); assert((char*)allocator < (char*)cur); assert((char*)cur < (char*)allocator + allocator->size); /* find free block right before the p */ b = allocator->headblock; while (b->next != 0 && b->next < cur) { b = b->next; } /* restore block */ cur->next = b->next; b->next = cur; size = cur->size; TRACE(" avail %lu (%luKB)", allocator->avail, allocator->avail / 1024); allocator->avail += size; /* combine prev|cur */ if (PADD(b, b->size) == (char *)cur) { b->size += cur->size; b->next = cur->next; cur = b; TRACE("%s", " combine prev"); } /* combine cur|next */ b = cur->next; if (PADD(cur, cur->size) == (char *)b) { cur->size += b->size; cur->next = b->next; TRACE("%s", " combine next"); } TRACE(" -> avail %lu (%luKB)", allocator->avail, allocator->avail / 1024); return size; }