1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
/* 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);
}
|