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 *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 lib_mem_usage(int *count, int *cpeak, xlong_t *total, xlong_t *tpeak) { LIBENV *env = lib_link_env(); if (count != NULL) *count = env->mem_count; if (cpeak != NULL) *cpeak = env->mem_cpeak; if (total != NULL) *total = env->mem_total; if (tpeak != NULL) *tpeak = env->mem_tpeak; return; }
int lib_close_log(void) { /* close hardcopy file */ LIBENV *env = lib_link_env(); if (env->log_file == NULL) { /* hardcopy file is already closed */ return 1; } fclose(env->log_file); env->log_file = NULL; return 0; }
void lib_term_hook(int (*func)(void *info, const char *s), void *info) { LIBENV *env = lib_link_env(); if (func == NULL) { env->term_hook = NULL; env->term_info = NULL; } else { env->term_hook = func; env->term_info = info; } return; }
int lib_open_log(const char *fname) { /* open hardcopy file */ LIBENV *env = lib_link_env(); if (env->log_file != NULL) { /* hardcopy file is already open */ return 1; } env->log_file = fopen(fname, "w"); if (env->log_file == NULL) { /* cannot create hardcopy file */ return 2; } setvbuf(env->log_file, NULL, _IOLBF, BUFSIZ); return 0; }
void xputc(int c) { LIBENV *env = lib_link_env(); /* if terminal output is disabled, do nothing */ if (!env->term_out) goto skip; /* pass the character to the user-defined routine */ if (env->term_hook != NULL) { char s[1+1]; s[0] = (char)c, s[1] = '\0'; if (env->term_hook(env->term_info, s) != 0) goto skip; } /* write the character to the terminal */ fputc(c, stdout); #if 1 /* 10/XII-2008 */ if (c == '\n') fflush(stdout); #endif /* write the character to the log file */ if (env->log_file != NULL) fputc(c, env->log_file); skip: return; }
void lib_mem_limit(xlong_t limit) { LIBENV *env = lib_link_env(); env->mem_limit = limit; return; }
const char *lib_version(void) { LIBENV *env = lib_link_env(); return env->version; }