w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

gmem.cc
Go to the documentation of this file.
1 /*
2  * gmem.c
3  *
4  * Memory routines with out-of-memory checking.
5  *
6  * Copyright 1996-2003 Glyph & Cog, LLC
7  */
8 
9 #include <aconf.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <stddef.h>
13 // older compilers won't define SIZE_MAX in stdint.h without this
14 #ifndef __STDC_LIMIT_MACROS
15 # define __STDC_LIMIT_MACROS 1
16 #endif
17 #include <stdint.h>
18 #include <string.h>
19 #include <limits.h>
20 #if MULTITHREADED && defined(_WIN32)
21 # include <windows.h>
22 #endif
23 #include "gmem.h"
24 
25 #ifdef DEBUG_MEM
26 
27 typedef struct _GMemHdr {
28  unsigned int magic;
29  int index;
30  size_t size;
31  struct _GMemHdr *next, *prev;
32 } GMemHdr;
33 
34 #define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7)
35 #define gMemTrlSize (sizeof(long))
36 
37 #define gMemMagic 0xabcd9999
38 
39 #if ULONG_MAX > 0xffffffffL
40 #define gMemDeadVal 0xdeadbeefdeadbeefUL
41 #else
42 #define gMemDeadVal 0xdeadbeefUL
43 #endif
44 
45 /* round data size so trailer will be aligned */
46 #define gMemDataSize(size) \
47  (int)(((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize))
48 
49 #define gMemDataSize64(size) \
50  (size_t)(((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize))
51 
52 static GMemHdr *gMemHead = NULL;
53 static GMemHdr *gMemTail = NULL;
54 
55 static int gMemIndex = 0;
56 static int gMemAlloc = 0;
57 static size_t gMemInUse = 0;
58 static size_t gMaxMemInUse = 0;
59 
60 #if MULTITHREADED
61 # ifdef _WIN32
62  static CRITICAL_SECTION gMemMutex;
63  static INIT_ONCE gMemMutexInitStruct = INIT_ONCE_STATIC_INIT;
64  static BOOL CALLBACK gMemMutexInitFunc(PINIT_ONCE initOnce, PVOID param,
65  PVOID *context) {
66  InitializeCriticalSection(&gMemMutex);
67  return TRUE;
68  }
69 # define gMemInitMutex InitOnceExecuteOnce(&gMemMutexInitStruct, \
70  &gMemMutexInitFunc, NULL, NULL)
71 # define gMemLock EnterCriticalSection(&gMemMutex);
72 # define gMemUnlock LeaveCriticalSection(&gMemMutex);
73 # else
74 # include <pthread.h>
75  static pthread_mutex_t gMemMutex = PTHREAD_MUTEX_INITIALIZER;
76 # define gMemInitMutex
77 # define gMemLock pthread_mutex_lock(&gMemMutex)
78 # define gMemUnlock pthread_mutex_unlock(&gMemMutex)
79 # endif
80 #else
81 # define gMemInitMutex
82 # define gMemLock
83 # define gMemUnlock
84 #endif
85 
86 #endif /* DEBUG_MEM */
87 
88 #ifdef DEBUG_MEM
89 void *gmalloc(int size, int ignore) GMEM_EXCEP {
90  int size1;
91  char *mem;
92  GMemHdr *hdr;
93  void *data;
94  unsigned long *trl, *p;
95 
96  gMemInitMutex;
97  if (size < 0) {
98  gMemError("Invalid memory allocation size");
99  }
100  if (size == 0) {
101  return NULL;
102  }
103  size1 = gMemDataSize(size);
104  if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
105  gMemError("Out of memory");
106  }
107  hdr = (GMemHdr *)mem;
108  data = (void *)(mem + gMemHdrSize);
109  trl = (unsigned long *)(mem + gMemHdrSize + size1);
110  hdr->magic = gMemMagic;
111  hdr->size = size;
112  gMemLock;
113  if (ignore) {
114  hdr->index = -1;
115  } else {
116  hdr->index = gMemIndex++;
117  }
118  if (gMemTail) {
119  gMemTail->next = hdr;
120  hdr->prev = gMemTail;
121  gMemTail = hdr;
122  } else {
123  hdr->prev = NULL;
124  gMemHead = gMemTail = hdr;
125  }
126  hdr->next = NULL;
127  ++gMemAlloc;
128  gMemInUse += size;
129  if (gMemInUse > gMaxMemInUse) {
130  gMaxMemInUse = gMemInUse;
131  }
132  gMemUnlock;
133  for (p = (unsigned long *)data; p <= trl; ++p) {
134  *p = gMemDeadVal;
135  }
136  return data;
137 }
138 #else
139 void *gmalloc(int size) GMEM_EXCEP {
140  void *p;
141 
142  if (size < 0) {
143  gMemError("Invalid memory allocation size");
144  }
145  if (size == 0) {
146  return NULL;
147  }
148  if (!(p = malloc(size))) {
149  gMemError("Out of memory");
150  }
151  return p;
152 }
153 #endif
154 
155 void *grealloc(void *p, int size) GMEM_EXCEP {
156 #ifdef DEBUG_MEM
157  GMemHdr *hdr;
158  void *q;
159  int oldSize;
160 
161  if (size < 0) {
162  gMemError("Invalid memory allocation size");
163  }
164  if (size == 0) {
165  if (p) {
166  gfree(p);
167  }
168  return NULL;
169  }
170  if (p) {
171  hdr = (GMemHdr *)((char *)p - gMemHdrSize);
172  oldSize = (int)hdr->size;
173  q = gmalloc(size);
174  memcpy(q, p, size < oldSize ? size : oldSize);
175  gfree(p);
176  } else {
177  q = gmalloc(size);
178  }
179  return q;
180 #else
181  void *q;
182 
183  if (size < 0) {
184  gMemError("Invalid memory allocation size");
185  }
186  if (size == 0) {
187  if (p) {
188  free(p);
189  }
190  return NULL;
191  }
192  if (p) {
193  q = realloc(p, size);
194  } else {
195  q = malloc(size);
196  }
197  if (!q) {
198  gMemError("Out of memory");
199  }
200  return q;
201 #endif
202 }
203 
204 void *gmallocn(int nObjs, int objSize) GMEM_EXCEP {
205  int n;
206 
207  if (nObjs == 0) {
208  return NULL;
209  }
210  n = nObjs * objSize;
211  if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
212  gMemError("Bogus memory allocation size");
213  }
214  return gmalloc(n);
215 }
216 
217 #ifdef DEBUG_MEM
218 void *gmalloc64(size_t size, int ignore) GMEM_EXCEP {
219  size_t size1;
220  char *mem;
221  GMemHdr *hdr;
222  void *data;
223  unsigned long *trl, *p;
224 
225  gMemInitMutex;
226  if (size == 0) {
227  return NULL;
228  }
229  size1 = gMemDataSize64(size);
230  if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
231  gMemError("Out of memory");
232  }
233  hdr = (GMemHdr *)mem;
234  data = (void *)(mem + gMemHdrSize);
235  trl = (unsigned long *)(mem + gMemHdrSize + size1);
236  hdr->magic = gMemMagic;
237  hdr->size = size;
238  gMemLock;
239  if (ignore) {
240  hdr->index = -1;
241  } else {
242  hdr->index = gMemIndex++;
243  }
244  if (gMemTail) {
245  gMemTail->next = hdr;
246  hdr->prev = gMemTail;
247  gMemTail = hdr;
248  } else {
249  hdr->prev = NULL;
250  gMemHead = gMemTail = hdr;
251  }
252  hdr->next = NULL;
253  ++gMemAlloc;
254  gMemInUse += size;
255  if (gMemInUse > gMaxMemInUse) {
256  gMaxMemInUse = gMemInUse;
257  }
258  gMemUnlock;
259  for (p = (unsigned long *)data; p <= trl; ++p) {
260  *p = gMemDeadVal;
261  }
262  return data;
263 }
264 #else
265 void *gmalloc64(size_t size) GMEM_EXCEP {
266  void *p;
267 
268  if (size == 0) {
269  return NULL;
270  }
271  if (!(p = malloc(size))) {
272  gMemError("Out of memory");
273  }
274  return p;
275 }
276 #endif
277 
278 void *gmallocn64(int nObjs, size_t objSize) GMEM_EXCEP {
279  size_t n;
280 
281  if (nObjs == 0) {
282  return NULL;
283  }
284  n = nObjs * objSize;
285  if (nObjs < 0 || (size_t)nObjs >= SIZE_MAX / objSize) {
286  gMemError("Bogus memory allocation size");
287  }
288  return gmalloc64(n);
289 }
290 
291 void *greallocn(void *p, int nObjs, int objSize) GMEM_EXCEP {
292  int n;
293 
294  if (nObjs == 0) {
295  if (p) {
296  gfree(p);
297  }
298  return NULL;
299  }
300  n = nObjs * objSize;
301  if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
302  gMemError("Bogus memory allocation size");
303  }
304  return grealloc(p, n);
305 }
306 
307 void gfree(void *p) {
308 #ifdef DEBUG_MEM
309  size_t size;
310  GMemHdr *hdr;
311  unsigned long *trl, *clr;
312 
313  if (p) {
314  hdr = (GMemHdr *)((char *)p - gMemHdrSize);
315  gMemLock;
316  if (hdr->magic == gMemMagic &&
317  ((hdr->prev == NULL) == (hdr == gMemHead)) &&
318  ((hdr->next == NULL) == (hdr == gMemTail))) {
319  if (hdr->prev) {
320  hdr->prev->next = hdr->next;
321  } else {
322  gMemHead = hdr->next;
323  }
324  if (hdr->next) {
325  hdr->next->prev = hdr->prev;
326  } else {
327  gMemTail = hdr->prev;
328  }
329  --gMemAlloc;
330  gMemInUse -= hdr->size;
331  gMemUnlock;
332  size = gMemDataSize64(hdr->size);
333  trl = (unsigned long *)((char *)hdr + gMemHdrSize + size);
334  if (*trl != gMemDeadVal) {
335  fprintf(stderr, "Overwrite past end of block %d at address %p\n",
336  hdr->index, p);
337  }
338  for (clr = (unsigned long *)hdr; clr <= trl; ++clr) {
339  *clr = gMemDeadVal;
340  }
341  free(hdr);
342  } else {
343  gMemUnlock;
344  fprintf(stderr, "Attempted to free bad address %p\n", p);
345  }
346  }
347 #else
348  if (p) {
349  free(p);
350  }
351 #endif
352 }
353 
354 void gMemError(const char *msg) GMEM_EXCEP {
355 #if USE_EXCEPTIONS
356  throw GMemException();
357 #else
358  fprintf(stderr, "%s\n", msg);
359  exit(1);
360 #endif
361 }
362 
363 #ifdef DEBUG_MEM
364 void gMemReport(FILE *f) {
365  GMemHdr *p;
366  int left;
367 
368  fprintf(f, "%d memory allocations in all\n", gMemIndex);
369  fprintf(f, "maximum memory in use: %zd bytes\n", gMaxMemInUse);
370  left = 0;
371  if (gMemAlloc > 0) {
372  for (p = gMemHead; p; p = p->next) {
373  if (p->index >= 0) {
374  if (!left) {
375  fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
376  fprintf(f, " index size\n");
377  fprintf(f, "-------- --------\n");
378  left = 1;
379  }
380  fprintf(f, "%8d %8zd\n", p->index, p->size);
381  }
382  }
383  }
384  if (!left) {
385  fprintf(f, "No memory blocks left allocated\n");
386  }
387 }
388 #endif
389 
390 char *copyString(const char *s) {
391  char *s1;
392 
393  s1 = (char *)gmalloc((int)strlen(s) + 1);
394  strcpy(s1, s);
395  return s1;
396 }
#define CALLBACK
q
Definition: afm2pl.c:2287
#define next(a)
Definition: aptex-macros.h:924
#define param(a, b)
#define n
Definition: t4ht.c:1290
BOOL
Definition: dd.h:100
@ TRUE
Definition: dd.h:102
#define free(a)
Definition: decNumber.cpp:310
char * strcpy()
struct rect data
Definition: dvipdfm.c:64
mpz_t * f
Definition: gen-fib.c:34
#define s
Definition: afcover.h:80
static FIELD_PTR prev
Definition: genind.c:36
void gMemError(const char *msg)
Definition: gmem.cc:354
void * grealloc(void *p, int size)
Definition: gmem.cc:155
void * greallocn(void *p, int nObjs, int objSize)
Definition: gmem.cc:291
void gfree(void *p)
Definition: gmem.cc:307
void * gmalloc64(size_t size)
Definition: gmem.cc:265
void * gmalloc(int size)
Definition: gmem.cc:139
void * gmallocn64(int nObjs, size_t objSize)
Definition: gmem.cc:278
void * gmallocn(int nObjs, int objSize)
Definition: gmem.cc:204
char * copyString(const char *s)
Definition: gmem.cc:390
#define memcpy(d, s, n)
Definition: gsftopk.c:64
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p
Definition: afcover.h:72
void exit()
#define SIZE_MAX
Definition: stdint.h:206
#define GMEM_EXCEP
Definition: gmem.h:31
#define gMemReport(f)
Definition: gmem.h:87
#define INT_MAX
Definition: c-minmax.h:53
#define fprintf
Definition: mendex.h:64
#define ignore
Definition: ctangleboot.c:133
#define malloc
Definition: alloca.c:91
#define mem
Definition: synctex.c:171
#define realloc
Definition: glob.c:206
static UInitOnce initOnce
#define index(s, c)
Definition: plain2.h:351
static int size
Definition: ppmlabel.c:24
lft_cell * left
Definition: routines.h:73
Definition: texview.c:48
#define FILE
Definition: t1stdio.h:34
s1
Definition: t4ht.c:1059
*job_name strlen((char *) job_name) - 4)
return() int(((double) *(font_tbl[cur_fnt].wtbl+(int)(*(font_tbl[cur_fnt].char_wi+(int)(ch - font_tbl[cur_fnt].char_f)% 256)))/(double)(1L<< 20)) *(double) font_tbl[cur_fnt].scale)
Definition: alloca.c:152
union hdr * next
Definition: alloca.c:156
#define hdr(h)
Definition: gc.c:359