Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

mud-memory.c File Reference

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <winsock.h>
#include <richedit.h>
#include "mud-client.h"
#include <assert.h>

Include dependency graph for mud-memory.c:

Include dependency graph

Go to the source code of this file.

Defines

#define DEBUG
#define MALLOC_LOG
#define MINEFIELD
#define PAGESIZE   4096
#define PAGESIZE   4096

Functions

void debug_memdump (void *buf, int len, int L)
void dprintf (char *fmt,...)
void dputs (char *buf)
void minefield_admin_hide (int hide)
void * minefield_alloc (int size)
void minefield_bomb (void)
void minefield_c_free (void *p)
void * minefield_c_malloc (size_t size)
void * minefield_c_realloc (void *p, size_t size)
void minefield_free (void *ptr)
int minefield_get_size (void *ptr)
void minefield_init (void)
void mlog (char *file, int line)
void safefree (void *ptr)
void * safemalloc (size_t size)
void * saferealloc (void *ptr, size_t size)

Variables

FILE * debug_fp = NULL
int debug_got_console = 0
FILE * fp = NULL
unsigned short * minefield_admin = NULL
long minefield_curpos = 0
int minefield_initialised = 0
long minefield_npages = 0
void * minefield_pages = NULL
void * minefield_region = NULL
long minefield_size = 0
char * mlog_file = NULL
int mlog_line = 0


Define Documentation

#define DEBUG
 

Definition at line 21 of file mud-memory.c.

#define MALLOC_LOG
 

Definition at line 19 of file mud-memory.c.

#define MINEFIELD
 

Definition at line 17 of file mud-memory.c.

#define PAGESIZE   4096
 

Definition at line 37 of file mud-memory.c.

#define PAGESIZE   4096
 

Definition at line 37 of file mud-memory.c.

Referenced by minefield_alloc(), minefield_free(), minefield_get_size(), and minefield_init().


Function Documentation

void debug_memdump void *  buf,
int  len,
int  L
 

Definition at line 396 of file mud-memory.c.

References dprintf(), and dputs().

00397 {
00398     int i;
00399     unsigned char *p = buf;
00400     char foo[17];
00401     if (L) {
00402     int delta;
00403     dprintf("\t%d (0x%x) bytes:\n", len, len);
00404     delta = 15 & (int) p;
00405     p -= delta;
00406     len += delta;
00407     }
00408     for (; 0 < len; p += 16, len -= 16) {
00409     dputs("  ");
00410     if (L)
00411         dprintf("%p: ", p);
00412     strcpy(foo, "................");    /* sixteen dots */
00413     for (i = 0; i < 16 && i < len; ++i) {
00414         if (&p[i] < (unsigned char *) buf) {
00415         dputs("   ");          /* 3 spaces */
00416         foo[i] = ' ';
00417         } else {
00418         dprintf("%c%02.2x",
00419             &p[i] != (unsigned char *) buf
00420             && i % 4 ? '.' : ' ', p[i]
00421             );
00422         if (p[i] >= ' ' && p[i] <= '~')
00423             foo[i] = (char) p[i];
00424         }
00425     }
00426     foo[i] = '\0';
00427     dprintf("%*s%s\n", (16 - i) * 3 + 2, "", foo);
00428     }
00429 }

Here is the call graph for this function:

void dprintf char *  fmt,
  ...
 

Definition at line 384 of file mud-memory.c.

References dputs().

Referenced by debug_memdump().

00385 {
00386     char buf[2048];
00387     va_list ap;
00388 
00389     va_start(ap, fmt);
00390     vsprintf(buf, fmt, ap);
00391     dputs(buf);
00392     va_end(ap);
00393 }

Here is the call graph for this function:

void dputs char *  buf  )  [static]
 

Definition at line 365 of file mud-memory.c.

References debug_fp, and debug_got_console.

Referenced by debug_memdump(), and dprintf().

00366 {
00367     DWORD dw;
00368 
00369     if (!debug_got_console) {
00370     AllocConsole();
00371     debug_got_console = 1;
00372     }
00373     if (!debug_fp) {
00374     debug_fp = fopen("debug.log", "w");
00375     }
00376 
00377     WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, strlen(buf), &dw,
00378           NULL);
00379     fputs(buf, debug_fp);
00380     fflush(debug_fp);
00381 }

void minefield_admin_hide int  hide  )  [static]
 

Definition at line 62 of file mud-memory.c.

References minefield_admin, and minefield_npages.

Referenced by minefield_alloc(), minefield_free(), minefield_get_size(), and minefield_init().

00063 {
00064     int access = hide ? PAGE_NOACCESS : PAGE_READWRITE;
00065     VirtualProtect(minefield_admin, minefield_npages * 2, access, NULL);
00066 }

void* minefield_alloc int  size  )  [static]
 

Definition at line 117 of file mud-memory.c.

References minefield_admin, minefield_admin_hide(), minefield_curpos, minefield_pages, PAGESIZE, and pos.

Referenced by minefield_c_malloc(), and minefield_c_realloc().

00118 {
00119     int npages;
00120     int pos, lim, region_end, region_start;
00121     int start;
00122     int i;
00123 
00124     npages = (size + PAGESIZE - 1) / PAGESIZE;
00125 
00126     minefield_admin_hide(0);
00127 
00128     /*
00129      * Search from current position until we find a contiguous
00130      * bunch of npages+2 unused pages.
00131      */
00132     pos = minefield_curpos;
00133     lim = minefield_npages;
00134     while (1) {
00135     /* Skip over used pages. */
00136     while (pos < lim && minefield_admin[pos] != 0xFFFF)
00137         pos++;
00138     /* Count unused pages. */
00139     start = pos;
00140     while (pos < lim && pos - start < npages + 2 &&
00141            minefield_admin[pos] == 0xFFFF)
00142         pos++;
00143     if (pos - start == npages + 2)
00144         break;
00145     /* If we've reached the limit, reset the limit or stop. */
00146     if (pos >= lim) {
00147         if (lim == minefield_npages) {
00148         /* go round and start again at zero */
00149         lim = minefield_curpos;
00150         pos = 0;
00151         } else {
00152         minefield_admin_hide(1);
00153         return NULL;
00154         }
00155     }
00156     }
00157 
00158     minefield_curpos = pos - 1;
00159 
00160     /*
00161      * We have npages+2 unused pages starting at start. We leave
00162      * the first and last of these alone and use the rest.
00163      */
00164     region_end = (start + npages + 1) * PAGESIZE;
00165     region_start = region_end - size;
00166     /* FIXME: could align here if we wanted */
00167 
00168     /*
00169      * Update the admin region.
00170      */
00171     for (i = start + 2; i < start + npages + 1; i++)
00172     minefield_admin[i] = 0xFFFE;   /* used but no region starts here */
00173     minefield_admin[start + 1] = region_start % PAGESIZE;
00174 
00175     minefield_admin_hide(1);
00176 
00177     VirtualAlloc((char *) minefield_pages + region_start, size,
00178          MEM_COMMIT, PAGE_READWRITE);
00179     return (char *) minefield_pages + region_start;
00180 }

Here is the call graph for this function:

void minefield_bomb void   )  [static]
 

Definition at line 112 of file mud-memory.c.

References minefield_pages.

Referenced by minefield_free(), and minefield_get_size().

00113 {
00114     div(1, *(int *) minefield_pages);
00115 }

void minefield_c_free void *  p  )  [static]
 

Definition at line 227 of file mud-memory.c.

References minefield_free(), and minefield_init().

Referenced by safefree().

00228 {
00229     if (!minefield_initialised)
00230     minefield_init();
00231     minefield_free(p);
00232 }

Here is the call graph for this function:

void* minefield_c_malloc size_t  size  )  [static]
 

Definition at line 220 of file mud-memory.c.

References minefield_alloc(), and minefield_init().

Referenced by safemalloc(), and saferealloc().

00221 {
00222     if (!minefield_initialised)
00223     minefield_init();
00224     return minefield_alloc(size);
00225 }

Here is the call graph for this function:

void* minefield_c_realloc void *  p,
size_t  size
[static]
 

Definition at line 238 of file mud-memory.c.

References minefield_alloc(), minefield_free(), minefield_get_size(), and minefield_init().

Referenced by saferealloc().

00239 {
00240     size_t oldsize;
00241     void *q;
00242     if (!minefield_initialised)
00243     minefield_init();
00244     q = minefield_alloc(size);
00245     oldsize = minefield_get_size(p);
00246     memcpy(q, p, (oldsize < size ? oldsize : size));
00247     minefield_free(p);
00248     return q;
00249 }

Here is the call graph for this function:

void minefield_free void *  ptr  )  [static]
 

Definition at line 182 of file mud-memory.c.

References minefield_admin, minefield_admin_hide(), minefield_bomb(), minefield_npages, and PAGESIZE.

Referenced by minefield_c_free(), and minefield_c_realloc().

00183 {
00184     int region_start, i, j;
00185 
00186     minefield_admin_hide(0);
00187 
00188     region_start = (char *) ptr - (char *) minefield_pages;
00189     i = region_start / PAGESIZE;
00190     if (i < 0 || i >= minefield_npages ||
00191     minefield_admin[i] != region_start % PAGESIZE)
00192     minefield_bomb();
00193     for (j = i; j < minefield_npages && minefield_admin[j] != 0xFFFF; j++) {
00194     minefield_admin[j] = 0xFFFF;
00195     }
00196 
00197     VirtualFree(ptr, j * PAGESIZE - region_start, MEM_DECOMMIT);
00198 
00199     minefield_admin_hide(1);
00200 }

Here is the call graph for this function:

int minefield_get_size void *  ptr  )  [static]
 

Definition at line 202 of file mud-memory.c.

References minefield_admin, minefield_admin_hide(), minefield_bomb(), minefield_npages, and PAGESIZE.

Referenced by minefield_c_realloc().

00203 {
00204     int region_start, i, j;
00205 
00206     minefield_admin_hide(0);
00207 
00208     region_start = (char *) ptr - (char *) minefield_pages;
00209     i = region_start / PAGESIZE;
00210     if (i < 0 || i >= minefield_npages ||
00211     minefield_admin[i] != region_start % PAGESIZE)
00212     minefield_bomb();
00213     for (j = i; j < minefield_npages && minefield_admin[j] != 0xFFFF; j++);
00214 
00215     minefield_admin_hide(1);
00216 
00217     return j * PAGESIZE - region_start;
00218 }

Here is the call graph for this function:

void minefield_init void   )  [static]
 

Definition at line 68 of file mud-memory.c.

References minefield_admin, minefield_admin_hide(), minefield_initialised, minefield_npages, minefield_pages, minefield_region, minefield_size, and PAGESIZE.

Referenced by minefield_c_free(), minefield_c_malloc(), and minefield_c_realloc().

00069 {
00070     int size;
00071     int admin_size;
00072     int i;
00073 
00074     for (size = 0x40000000; size > 0; size = ((size >> 3) * 7) & ~0xFFF) {
00075     minefield_region = VirtualAlloc(NULL, size,
00076                     MEM_RESERVE, PAGE_NOACCESS);
00077     if (minefield_region)
00078         break;
00079     }
00080     minefield_size = size;
00081 
00082     /*
00083      * Firstly, allocate a section of that to be the admin block.
00084      * We'll need a two-byte field for each page.
00085      */
00086     minefield_admin = minefield_region;
00087     minefield_npages = minefield_size / PAGESIZE;
00088     admin_size = (minefield_npages * 2 + PAGESIZE - 1) & ~(PAGESIZE - 1);
00089     minefield_npages = (minefield_size - admin_size) / PAGESIZE;
00090     minefield_pages = (char *) minefield_region + admin_size;
00091 
00092     /*
00093      * Commit the admin region.
00094      */
00095     VirtualAlloc(minefield_admin, minefield_npages * 2,
00096          MEM_COMMIT, PAGE_READWRITE);
00097 
00098     /*
00099      * Mark all pages as unused (0xFFFF).
00100      */
00101     for (i = 0; i < minefield_npages; i++)
00102     minefield_admin[i] = 0xFFFF;
00103 
00104     /*
00105      * Hide the admin region.
00106      */
00107     minefield_admin_hide(1);
00108 
00109     minefield_initialised = 1;
00110 }

Here is the call graph for this function:

void mlog char *  file,
int  line
 

Definition at line 259 of file mud-memory.c.

References fp, mlog_file, and mlog_line.

00260 {
00261     mlog_file = file;
00262     mlog_line = line;
00263     if (!fp) {
00264     fp = fopen("Mud-client_mem.log", "w");
00265     setvbuf(fp, NULL, _IONBF, BUFSIZ);
00266     }
00267     if (fp)
00268     fprintf(fp, "%s:%d: ", file, line);
00269 }

void safefree void *  ptr  ) 
 

Definition at line 338 of file mud-memory.c.

References fp, free, and minefield_c_free().

00339 {
00340     if (ptr) {
00341 #ifdef MALLOC_LOG
00342     if (fp)
00343         fprintf(fp, "free(%p)\n", ptr);
00344 #endif
00345 #ifdef MINEFIELD
00346     minefield_c_free(ptr);
00347 #else
00348     free(ptr);
00349 #endif
00350     }
00351 #ifdef MALLOC_LOG
00352     else if (fp)
00353     fprintf(fp, "freeing null pointer - no action taken\n");
00354 #endif
00355 }

Here is the call graph for this function:

void* safemalloc size_t  size  ) 
 

Definition at line 272 of file mud-memory.c.

References fp, malloc, minefield_c_malloc(), mlog_file, and mlog_line.

00273 {
00274     void *p;
00275 #ifdef MINEFIELD
00276     p = minefield_c_malloc(size);
00277 #else
00278     p = malloc(size);
00279 #endif
00280     if (!p) {
00281     char str[200];
00282 #ifdef MALLOC_LOG
00283     sprintf(str, "Out of memory! (%s:%d, size=%d)",
00284         mlog_file, mlog_line, size);
00285     fprintf(fp, "*** %s\n", str);
00286     fclose(fp);
00287 #else
00288     strcpy(str, "Out of memory!");
00289 #endif
00290     MessageBox(NULL, str, "Mud-client Fatal Error",
00291            MB_SYSTEMMODAL | MB_ICONERROR | MB_OK);
00292     
00293     }
00294 #ifdef MALLOC_LOG
00295     if (fp)
00296     fprintf(fp, "malloc(%d) returns %p\n", size, p);
00297 #endif
00298     return p;
00299 }

Here is the call graph for this function:

void* saferealloc void *  ptr,
size_t  size
 

Definition at line 301 of file mud-memory.c.

References fp, malloc, minefield_c_malloc(), minefield_c_realloc(), mlog_file, mlog_line, and realloc.

00302 {
00303     void *p;
00304     if (!ptr) {
00305 #ifdef MINEFIELD
00306     p = minefield_c_malloc(size);
00307 #else
00308     p = malloc(size);
00309 #endif
00310     } else {
00311 #ifdef MINEFIELD
00312     p = minefield_c_realloc(ptr, size);
00313 #else
00314     p = realloc(ptr, size);
00315 #endif
00316     }
00317     if (!p) {
00318     char str[200];
00319 #ifdef MALLOC_LOG
00320     sprintf(str, "Out of memory! (%s:%d, size=%d)",
00321         mlog_file, mlog_line, size);
00322     fprintf(fp, "*** %s\n", str);
00323     fclose(fp);
00324 #else
00325     strcpy(str, "Out of memory!");
00326 #endif
00327     MessageBox(NULL, str, "Mud-client Fatal Error",
00328            MB_SYSTEMMODAL | MB_ICONERROR | MB_OK);
00329     
00330     }
00331 #ifdef MALLOC_LOG
00332     if (fp)
00333     fprintf(fp, "realloc(%p,%d) returns %p\n", ptr, size, p);
00334 #endif
00335     return p;
00336 }

Here is the call graph for this function:


Variable Documentation

FILE* debug_fp = NULL [static]
 

Definition at line 362 of file mud-memory.c.

Referenced by dputs().

int debug_got_console = 0 [static]
 

Definition at line 363 of file mud-memory.c.

Referenced by dputs().

FILE* fp = NULL [static]
 

Definition at line 254 of file mud-memory.c.

Referenced by mlog(), safefree(), safemalloc(), and saferealloc().

unsigned short* minefield_admin = NULL [static]
 

Definition at line 59 of file mud-memory.c.

Referenced by minefield_admin_hide(), minefield_alloc(), minefield_free(), minefield_get_size(), and minefield_init().

long minefield_curpos = 0 [static]
 

Definition at line 58 of file mud-memory.c.

Referenced by minefield_alloc().

int minefield_initialised = 0 [static]
 

Definition at line 54 of file mud-memory.c.

Referenced by minefield_init().

long minefield_npages = 0 [static]
 

Definition at line 57 of file mud-memory.c.

Referenced by minefield_admin_hide(), minefield_free(), minefield_get_size(), and minefield_init().

void* minefield_pages = NULL [static]
 

Definition at line 60 of file mud-memory.c.

Referenced by minefield_alloc(), minefield_bomb(), and minefield_init().

void* minefield_region = NULL [static]
 

Definition at line 55 of file mud-memory.c.

Referenced by minefield_init().

long minefield_size = 0 [static]
 

Definition at line 56 of file mud-memory.c.

Referenced by minefield_init().

char* mlog_file = NULL [static]
 

Definition at line 256 of file mud-memory.c.

Referenced by mlog(), safemalloc(), and saferealloc().

int mlog_line = 0 [static]
 

Definition at line 257 of file mud-memory.c.

Referenced by mlog(), safemalloc(), and saferealloc().


Generated on Sun Dec 26 17:22:31 2004 for mudclient by  doxygen 1.3.9.1