static void free_mapping_file(int cap, void *addr, size_t mapsize) /* NOTE: addr needs to be the same as what was supplied by alloc_mapping_file */ { Q__printf("MAPPING: free, cap=%s, addr=%p, mapsize=%zx\n", cap, addr, mapsize); smfree(&pgmpool, addr); }
void lowmem_free(char *p, int size) { if (smget_area_size(&mp, p) != size) { error("lowmem_free size mismatch: found %i, requested %i, builtin=%s\n", smget_area_size(&mp, p), size, builtin_name); } return smfree(&mp, p); }
static inline void free_checked(int *ptr) { fail_unless(ptr[0] < OBJECTS_MAX && ptr[ptr[1]/sizeof(int)-1] == ptr[0]); int pos = ptr[0]; fail_unless(ptrs[pos] == ptr); ptrs[pos][0] = ptrs[pos][ptr[1]/sizeof(int)-1] = INT_MAX; smfree(&alloc, ptrs[pos], ptrs[pos][1]); ptrs[pos] = NULL; }
int smdestroy(struct mempool *mp) { struct memnode *mn; int leaked, avail = smget_free_space(mp); while (POOL_USED(mp)) { mn = &mp->mn; if (!mn->used) mn = mn->next; assert(mn && mn->used); smfree(mp, mn->mem_area); } assert(!mp->mn.next && mp->mn.size >= avail); leaked = mp->mn.size - avail; return leaked; }
static inline void smfree_batch(struct small_alloc *alloc) { if (alloc->is_delayed_free_mode || lifo_is_empty(&alloc->delayed)) return; const int BATCH = 100; for (int i = 0; i < BATCH; i++) { void *item = lifo_pop(&alloc->delayed); if (item == NULL) break; smfree(alloc, item); } }
void *smrealloc(struct mempool *mp, void *ptr, size_t size) { struct memnode *mn, *pmn; if (!ptr) return smalloc(mp, size); if (!(mn = find_mn(mp, ptr))) { smerror("SMALLOC: bad pointer passed to smrealloc()\n"); return NULL; } if (!mn->used) { smerror("SMALLOC: attempt to realloc the not allocated region\n"); return NULL; } if (size == 0) { smfree(mp, ptr); return NULL; } if (size == mn->size) return ptr; if (size < mn->size) { /* shrink */ #if SM_COMMIT_SUPPORT if (mp->uncommit) mp->uncommit(mn->mem_area + size, mn->size - size); #endif mntruncate(mn, size); } else { /* grow */ struct memnode *nmn = mn->next; if (nmn && !nmn->used && mn->size + nmn->size >= size) { /* expand */ #if SM_COMMIT_SUPPORT if (mp->commit && !mp->commit(nmn->mem_area, size - mn->size)) return NULL; #endif memset(nmn->mem_area, 0, size - mn->size); mntruncate(mn, size); } else { pmn = mn->prev; if (pmn && !pmn->used && pmn->size + mn->size + (nmn->used ? 0 : nmn->size) >= size) { /* move */ #if SM_COMMIT_SUPPORT if (mp->commit) { size_t psize = min(size, pmn->size); if (!mp->commit(pmn->mem_area, psize)) return NULL; if (size > pmn->size + mn->size && !mp->commit(nmn->mem_area, size - pmn->size - mn->size)) { if (mp->uncommit) mp->uncommit(pmn->mem_area, psize); return NULL; } } #endif pmn->used = 1; memmove(pmn->mem_area, mn->mem_area, mn->size); memset(pmn->mem_area + mn->size, 0, size - mn->size); mn->used = 0; #if SM_COMMIT_SUPPORT if (size < pmn->size + mn->size) { size_t overl = size > pmn->size ? size - pmn->size : 0; if (mp->uncommit) mp->uncommit(mn->mem_area + overl, mn->size - overl); } #endif if (!nmn->used) mntruncate(mn, mn->size + nmn->size); mntruncate(pmn, size); return pmn->mem_area; } else { /* relocate */ void *new_ptr = smalloc(mp, size); if (!new_ptr) { smerror("SMALLOC: Out Of Memory on realloc, requested=%zu\n", size); return NULL; } memcpy(new_ptr, mn->mem_area, mn->size); smfree(mp, mn->mem_area); return new_ptr; } } } assert(mn->size == size); return mn->mem_area; }
static void xms_free(unsigned addr) { smfree(&mp, &ext_mem_base[addr - (LOWMEM_SIZE + HMASIZE)]); }