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) xfault("xmalloc: size = %d; invalid parameter\n", size); size += size_of_desc; if (ulcmp(ulset(0, size), ulsub(env->mem_limit, env->mem_total)) > 0) xfault("xmalloc: memory limit exceeded\n"); if (env->mem_count == INT_MAX) xfault("xmalloc: too many memory blocks allocated\n"); desc = malloc(size); if (desc == NULL) xfault("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 = uladd(env->mem_total, ulset(0, size)); if (ulcmp(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) xfault("xfree: ptr = %p; null pointer\n", ptr); desc = (void *)((char *)ptr - size_of_desc); if (desc->flag != LIB_MEM_FLAG) xfault("xfree: ptr = %p; invalid pointer\n", ptr); if (env->mem_count == 0 || ulcmp(env->mem_total, ulset(0, desc->size)) < 0) xfault("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 = ulsub(env->mem_total, ulset(0, desc->size)); memset(desc, '?', size_of_desc); free(desc); return; }
/* All combinations for each of the above values. */ #define ulcmp(l, s, m) \ s, l, l, l, l, l, m, s, l, l, l, l, \ m, m, s, l, l, l, m, m, m, s, l, l, \ m, m, m, m, s, l, m, m, m, m, m, s #define lcmp(l, s, m) \ s, l, l, m, m, m, m, s, l, m, m, m, \ m, m, s, m, m, m, l, l, l, s, l, l, \ l, l, l, m, s, l, l, l, l, m, m, s /* All combinations of the above for high/low words. */ static int lcmp_results[] = { lcmp(ulcmp(-1, -1, -1), ulcmp(-1, 0, 1), ulcmp(1, 1, 1)) }; static int ulcmp_results[] = { ulcmp(ulcmp(-1, -1, -1), ulcmp(-1, 0, 1), ulcmp(1, 1, 1)) }; static int signof(int i) { if (i < 0) return -1; if (i == 0) return 0;