/* File: z-virt.c */ /* * Copyright (c) 1997 Ben Harrison * * This software may be copied and distributed for educational, research, * and not for profit purposes provided that this copyright and statement * are included in all such copies. */ /* Purpose: Memory management routines -BEN- */ #include "z-virt.h" #include "z-util.h" /* * Allow debugging messages to track memory usage. */ #ifdef VERBOSE_RALLOC static long virt_make = 0; static long virt_kill = 0; static long virt_size = 0; #endif /* * Optional auxiliary "rnfree" function */ vptr (*rnfree_aux)(vptr, huge) = NULL; /* * Free some memory (allocated by ralloc), return NULL */ vptr rnfree(vptr p, huge len) { /* Easy to free zero bytes */ if (len == 0) return (NULL); #ifdef VERBOSE_RALLOC /* Decrease memory count */ virt_kill += len; /* Message */ if (len > virt_size) { char buf[80]; sprintf(buf, "Kill (%ld): %ld - %ld = %ld.", len, virt_make, virt_kill, virt_make - virt_kill); plog(buf); } #endif /* Use the "aux" function */ if (rnfree_aux) return ((*rnfree_aux)(p, len)); /* Use "free" */ free ((char*)(p)); /* Done */ return (NULL); } /* * Optional auxiliary "rpanic" function */ vptr (*rpanic_aux)(huge) = NULL; /* * The system is out of memory, so panic. If "rpanic_aux" is set, * it can be used to free up some memory and do a new "ralloc()", * or if not, it can be used to save things, clean up, and exit. * By default, this function simply crashes the computer. */ vptr rpanic(huge len) { /* Hopefully, we have a real "panic" function */ if (rpanic_aux) return ((*rpanic_aux)(len)); /* Attempt to crash before icky things happen */ core("Out of Memory!"); /* Paranoia */ return ((vptr)(NULL)); } /* * Optional auxiliary "ralloc" function */ vptr (*ralloc_aux)(huge) = NULL; /* * Allocate some memory */ vptr ralloc(huge len) { vptr mem; /* Allow allocation of "zero bytes" */ if (len == 0) return ((vptr)(NULL)); #ifdef VERBOSE_RALLOC /* Count allocated memory */ virt_make += len; /* Log important allocations */ if (len > virt_size) { char buf[80]; sprintf(buf, "Make (%ld): %ld - %ld = %ld.", len, virt_make, virt_kill, virt_make - virt_kill); plog(buf); } #endif /* Use the aux function if set */ if (ralloc_aux) mem = (*ralloc_aux)(len); /* Use malloc() to allocate some memory */ else mem = ((vptr)(malloc((size_t)(len)))); /* We were able to acquire memory */ if (!mem) mem = rpanic(len); /* Return the memory, if any */ return (mem); } /* * Allocate a constant string, containing the same thing as 'str' */ cptr string_make(cptr str) { huge len = 0; cptr t = str; char *s, *res; /* Simple sillyness */ if (!str) return (str); /* Get the number of chars in the string, including terminator */ while (str[len++]) /* loop */; /* Allocate space for the string */ s = res = (char*)(ralloc(len)); /* Copy the string (with terminator) */ while ((*s++ = *t++) != 0) /* loop */; /* Return the allocated, initialized, string */ return (res); } /* * Un-allocate a string allocated above. * Depends on no changes being made to the string. */ errr string_free(cptr str) { huge len = 0; /* Succeed on non-strings */ if (!str) return (0); /* Count the number of chars in 'str' plus the terminator */ while (str[len++]) /* loop */; /* Kill the buffer of chars we must have allocated above */ rnfree((vptr)(str), len); /* Success */ return (0); }