void dmp_free_atom(DMP *pool, void *atom, int size) { int k; if (!(1 <= size && size <= 256)) xerror("dmp_free_atom: size = %d; invalid atom size\n", size); #if 0 if (!(pool->size == 0 || pool->size == size)) xerror("dmp_free_atom: size = %d; wrong atom size\n", size); #endif if (pool->count.lo == 0 && pool->count.hi == 0) xerror("dmp_free_atom: pool allocation error\n"); #ifdef GLP_DEBUG atom = (char *)atom - align_datasize(sizeof(struct info)); xassert(((struct info *)atom)->pool == pool); xassert(((struct info *)atom)->size == size); #endif /* adjust the size to provide the proper data alignment */ size = align_datasize(size); #ifdef GLP_DEBUG size += align_datasize(sizeof(struct info)); #endif /* adjust the size to make it multiple of 8 bytes, if needed */ size = ((size + 7) / 8) * 8; /* determine the corresponding list of free cells */ k = size / 8 - 1; xassert(0 <= k && k <= 31); /* return the atom to the list of free cells */ *(void **)atom = pool->avail[k]; pool->avail[k] = atom; /* decrease the number of atoms which are currently in use */ pool->count.lo--; if (pool->count.lo == 0xFFFFFFFF) pool->count.hi--; return; }
void *dmp_get_atom(DMP *pool, int size) { void *atom; int k; #ifdef GLP_DEBUG int orig_size = size; #endif if (!(1 <= size && size <= 256)) xerror("dmp_get_atom: size = %d; invalid atom size\n", size); #if 0 if (!(pool->size == 0 || pool->size == size)) xerror("dmp_get_atom: size = %d; wrong atom size\n", size); #endif /* adjust the size to provide the proper data alignment */ size = align_datasize(size); #ifdef GLP_DEBUG size += align_datasize(sizeof(struct info)); #endif /* adjust the size to make it multiple of 8 bytes, if needed */ size = ((size + 7) / 8) * 8; /* determine the corresponding list of free cells */ k = size / 8 - 1; xassert(0 <= k && k <= 31); /* obtain a free atom */ if (pool->avail[k] == NULL) { /* the list of free cells is empty */ if (pool->used + size > DMP_BLK_SIZE) { /* allocate a new memory block */ void *block = xmalloc(DMP_BLK_SIZE); *(void **)block = pool->block; pool->block = block; pool->used = align_datasize(sizeof(void *)); } /* place the atom in the current memory block */ atom = (char *)pool->block + pool->used; pool->used += size; } else { /* obtain the atom from the list of free cells */ atom = pool->avail[k]; pool->avail[k] = *(void **)atom; } memset(atom, '?', size); /* increase the number of atoms which are currently in use */ pool->count.lo++; if (pool->count.lo == 0) pool->count.hi++; #ifdef GLP_DEBUG ((struct info *)atom)->pool = pool; ((struct info *)atom)->size = orig_size; atom = (char *)atom + align_datasize(sizeof(struct info)); #endif return atom; }
void *xmalloc(int size) { LIBENV *env = lib_link_env(); LIBMEM *desc; int size_of_desc = align_datasize(sizeof(LIBMEM)); if (size < 1 || size > INT_MAX - size_of_desc) xerror("xmalloc: size = %d; invalid parameter\n", size); size += size_of_desc; if (xlcmp(xlset(size), xlsub(env->mem_limit, env->mem_total)) > 0) xerror("xmalloc: memory limit exceeded\n"); if (env->mem_count == INT_MAX) xerror("xmalloc: too many memory blocks allocated\n"); desc = malloc(size); if (desc == NULL) xerror("xmalloc: no memory available\n"); memset(desc, '?', size); desc->flag = LIB_MEM_FLAG; desc->size = size; desc->prev = NULL; desc->next = env->mem_ptr; if (desc->next != NULL) desc->next->prev = desc; env->mem_ptr = desc; env->mem_count++; if (env->mem_cpeak < env->mem_count) env->mem_cpeak = env->mem_count; env->mem_total = xladd(env->mem_total, xlset(size)); if (xlcmp(env->mem_tpeak, env->mem_total) < 0) env->mem_tpeak = env->mem_total; return (void *)((char *)desc + size_of_desc); }
void xfree(void *ptr) { LIBENV *env = lib_link_env(); LIBMEM *desc; int size_of_desc = align_datasize(sizeof(LIBMEM)); if (ptr == NULL) xerror("xfree: ptr = %p; null pointer\n", ptr); desc = (void *)((char *)ptr - size_of_desc); if (desc->flag != LIB_MEM_FLAG) xerror("xfree: ptr = %p; invalid pointer\n", ptr); if (env->mem_count == 0 || xlcmp(env->mem_total, xlset(desc->size)) < 0) xerror("xfree: memory allocation error\n"); if (desc->prev == NULL) env->mem_ptr = desc->next; else desc->prev->next = desc->next; if (desc->next == NULL) ; else desc->next->prev = desc->prev; env->mem_count--; env->mem_total = xlsub(env->mem_total, xlset(desc->size)); memset(desc, '?', size_of_desc); free(desc); return; }
void *umalloc(int size) { ENV *env = get_env_ptr(); MEM *desc; int size_of_desc = align_datasize(sizeof(MEM)); if (size < 1) fault("umalloc: invalid size"); if (size > INT_MAX - size_of_desc) fault("umalloc: size too big"); size += size_of_desc; if (size > env->mem_limit - env->mem_total) fault("umalloc: no memory available"); desc = malloc(size); if (desc == NULL) fault("umalloc: malloc failed"); #if 1 memset(desc, '?', size); #endif desc->size = size; desc->flag = MEM_FLAG; desc->prev = NULL; desc->next = env->mem_ptr; if (desc->next != NULL) desc->next->prev = desc; env->mem_ptr = desc; env->mem_total += size; if (env->mem_tpeak < env->mem_total) env->mem_tpeak = env->mem_total; env->mem_count++; if (env->mem_cpeak < env->mem_count) env->mem_cpeak = env->mem_count; return (void *)((char *)desc + size_of_desc); }
void ufree(void *ptr) { ENV *env = get_env_ptr(); MEM *desc; int size_of_desc = align_datasize(sizeof(MEM)); if (ptr == NULL) fault("ufree: null pointer"); desc = (void *)((char *)ptr - size_of_desc); if (desc->flag != MEM_FLAG) fault("ufree: invalid pointer"); if (env->mem_total < desc->size || env->mem_count == 0) fault("ufree: memory allocation error"); if (desc->prev == NULL) env->mem_ptr = desc->next; else desc->prev->next = desc->next; if (desc->next == NULL) ; else desc->next->prev = desc->prev; env->mem_total -= desc->size; env->mem_count--; memset(desc, '?', size_of_desc); free(desc); return; }
void glp_free(void *ptr) { ENV *env = get_env_ptr(); MEM *desc; int size_of_desc = align_datasize(sizeof(MEM)); if (ptr == NULL) xerror("glp_free: ptr = %p; null pointer\n", ptr); desc = (void *)((char *)ptr - size_of_desc); if (desc->flag != MEM_MAGIC) xerror("glp_free: ptr = %p; invalid pointer\n", ptr); if (env->mem_count == 0 || xlcmp(env->mem_total, xlset(desc->size)) < 0) xerror("glp_free: memory allocation error\n"); if (desc->prev == NULL) env->mem_ptr = desc->next; else desc->prev->next = desc->next; if (desc->next == NULL) ; else desc->next->prev = desc->prev; env->mem_count--; env->mem_total = xlsub(env->mem_total, xlset(desc->size)); memset(desc, '?', size_of_desc); free(desc); return; }