ArchWizard

DGD/

source navigation ]
diff markup ]
identifier search ]
file search ]
Version: [ 1.0.a0 ] [ 1.1 ] [ 1.2 ] [ 1.2p1 ] [ 1.2p2 ] [ 1.2p3 ] [ 1.2p4 ] [ 1.2.151 ]

  1 # include "dgd.h"
  2 
  3 # ifndef STRUCT_AL
  4 # define STRUCT_AL      2               /* default memory alignment */
  5 # endif
  6 
  7 # define MAGIC_MASK     0xc0000000L     /* magic number mask */
  8 # define SIZE_MASK      0x3fffffffL     /* size mask */
  9 
 10 # define SM_MAGIC       0x80000000L     /* static mem */
 11 # define DM_MAGIC       0xc0000000L     /* dynamic mem */
 12 
 13 # define UINTSIZE       ALGN(sizeof(Uint), STRUCT_AL)
 14 # define SIZETSIZE      ALGN(sizeof(size_t), STRUCT_AL)
 15 
 16 # ifdef DEBUG
 17 # define MOFFSET        ALGN(sizeof(header), STRUCT_AL)
 18 # else
 19 # define MOFFSET        UINTSIZE
 20 # endif
 21 
 22 typedef struct _chunk_ {
 23     Uint size;                  /* size of chunk */
 24     struct _chunk_ *next;       /* next chunk */
 25 } chunk;
 26 
 27 # ifdef DEBUG
 28 typedef struct _header_ {
 29     Uint size;                  /* size of chunk */
 30     struct _header_ *prev;      /* previous in list */
 31     struct _header_ *next;      /* next in list */
 32     int line;                   /* line it was allocated from */
 33     char *file;                 /* file it was allocated from */
 34 } header;
 35 # endif
 36 
 37 
 38 static allocinfo mstat;         /* memory statistics */
 39 
 40 /*
 41  * NAME:        newmem()
 42  * DESCRIPTION: allocate new memory
 43  */
 44 static char *newmem(size, list)
 45 size_t size;
 46 char **list;
 47 {
 48     char *mem;
 49 
 50     if (list != (char **) NULL) {
 51         size += ALGN(sizeof(char *), STRUCT_AL);
 52     }
 53     mem = (char *) malloc(size);
 54     if (mem == (char *) NULL) {
 55         fatal("out of memory");
 56     }
 57     if (list != (char **) NULL) {
 58         *((char **) mem) = *list;
 59         *list = mem;
 60         mem += ALGN(sizeof(char *), STRUCT_AL);
 61     }
 62     return mem;
 63 }
 64 
 65 /*
 66  * static memory manager
 67  */
 68 
 69 # define INIT_MEM       15360           /* initial static memory chunk */
 70 # define SLIMIT         (STRINGSZ + MOFFSET)
 71 # define SSMALL         (MOFFSET + STRINGSZ / 8)
 72 # define SCHUNKS        (STRINGSZ / STRUCT_AL - 1)
 73 # define LCHUNKS        32
 74 
 75 typedef struct {
 76     size_t size;                /* size of chunks in list */
 77     chunk *list;                /* list of chunks (possibly empty) */
 78 } clist;
 79 
 80 static char *slist;                     /* list of static chunks */
 81 static chunk *schunk;                   /* current chunk */
 82 static size_t schunksz;                 /* size of current chunk */
 83 static chunk *schunks[SCHUNKS];         /* lists of small free chunks */
 84 static clist lchunks[LCHUNKS];          /* lists of large free chunks */
 85 static unsigned int nlc;                /* # elements in large chunk list */
 86 static chunk *sflist;                   /* list of small unused chunks */
 87 static int slevel;                      /* static level */
 88 
 89 /*
 90  * NAME:        lchunk()
 91  * DESCRIPTION: get the address of a list of large chunks
 92  */
 93 static chunk **lchunk(size, new)
 94 register size_t size;
 95 bool new;
 96 {
 97     register unsigned int h, l, m;
 98 
 99     l = m = 0;
100     h = nlc;
101     while (l < h) {
102         m = (l + h) >> 1;
103         if (lchunks[m].size == size) {
104             return &lchunks[m].list;    /* found */
105         } else if (lchunks[m].size > size) {
106             h = m;                      /* search in lower half */
107         } else {
108             l = ++m;                    /* search in upper half */
109         }
110     }
111 
112     if (!new) {
113         return (chunk **) NULL;         /* not found */
114     }
115     /* make a new list */
116     if (nlc == LCHUNKS) {
117         fatal("too many different large static chunks");
118     }
119     for (l = nlc++; l > m; --l) {
120         lchunks[l] = lchunks[l - 1];
121     }
122     lchunks[m].size = size;
123     lchunks[m].list = (chunk *) NULL;
124     return &lchunks[m].list;
125 }
126 
127 /*
128  * NAME:        salloc()
129  * DESCRIPTION: allocate static memory
130  */
131 static chunk *salloc(size)
132 register size_t size;
133 {
134     register chunk *c;
135 
136     /* try lists of free chunks */
137     if (size >= SLIMIT) {
138         register chunk **lc;
139 
140         lc = lchunk(size, FALSE);
141         if (lc != (chunk **) NULL && *lc != (chunk *) NULL) {
142             /* large chunk */
143             c = *lc;
144             *lc = c->next;
145             return c;
146         }
147     } else if ((c=schunks[(size - MOFFSET) / STRUCT_AL - 1]) != (chunk *) NULL)
148     {
149         /* small chunk */
150         schunks[(size - MOFFSET) / STRUCT_AL - 1] = c->next;
151         return c;
152     }
153 
154     /* try unused chunk list */
155     if (sflist != (chunk *) NULL && sflist->size >= size) {
156         if (sflist->size - size <= MOFFSET) {
157             /* remainder is too small to put in free list */
158             c = sflist;
159             sflist = c->next;
160         } else {
161             register chunk *n;
162 
163             /* split the chunk in two */
164             c = sflist;
165             n = (chunk *) ((char *) sflist + size);
166             n->size = c->size - size;
167             if (n->size <= SSMALL) {
168                 /* small chunk */
169                 n->next = schunks[(n->size - MOFFSET) / STRUCT_AL - 1];
170                 schunks[(n->size - MOFFSET) / STRUCT_AL - 1] = n;
171                 sflist = c->next;
172             } else {
173                 /* large enough chunk */
174                 n->next = c->next;
175                 sflist = n;
176             }
177             c->size = size;
178         }
179         return c;
180     }
181 
182     /* try current chunk */
183     if (schunk == (chunk *) NULL ||
184         (schunk->size < size && (schunksz != 0 || size <= INIT_MEM))) {
185         /*
186          * allocate default static memory block
187          */
188         if (schunk != (chunk *) NULL) {
189             schunk->next = sflist;
190             sflist = schunk;
191         }
192         schunk = (chunk *) newmem(INIT_MEM, &slist);
193         mstat.smemsize += schunk->size = INIT_MEM;
194         if (schunksz != 0) {
195             /* fragmentation matters */
196             P_message("*** Ran out of static memory (increase static_chunk)\012"); /* LF */
197         }
198     }
199     if (schunk->size >= size) {
200         if (schunk->size - size <= MOFFSET) {
201             /* remainder is too small */
202             c = schunk;
203             schunk = (chunk *) NULL;
204         } else {
205             c = schunk;
206             schunk = (chunk *) ((char *) schunk + size);
207             if ((schunk->size=c->size - size) <= SSMALL) {
208                 /* small chunk */
209                 schunk->next = schunks[(schunk->size - MOFFSET) / STRUCT_AL -1];
210                 schunks[(schunk->size - MOFFSET) / STRUCT_AL - 1] = schunk;
211                 schunk = (chunk *) NULL;
212             }
213             c->size = size;
214         }
215         return c;
216     }
217 
218     /* allocate static memory directly */
219     c = (chunk *) newmem(size, &slist);
220     mstat.smemsize += c->size = size;
221     return c;
222 }
223 
224 /*
225  * NAME:        sfree()
226  * DESCRIPTION: free static memory
227  */
228 static void sfree(c)
229 register chunk *c;
230 {
231     if (c->size < SLIMIT) {
232         /* small chunk */
233         c->next = schunks[(c->size - MOFFSET) / STRUCT_AL - 1];
234         schunks[(c->size - MOFFSET) / STRUCT_AL - 1] = c;
235     } else {
236         register chunk **lc;
237 
238         /* large chunk */
239         lc = lchunk(c->size, TRUE);
240         c->next = *lc;
241         *lc = c;
242     }
243 }
244 
245 /*
246  * NAME:        mstatic()
247  * DESCRIPTION: enter static mode
248  */
249 void m_static()
250 {
251     slevel++;
252 }
253 
254 /*
255  * NAME:        mdynamic()
256  * DESCRIPTION: reenter dynamic mode
257  */
258 void m_dynamic()
259 {
260     --slevel;
261 }
262 
263 
264 /*
265  * dynamic memory manager
266  */
267 
268 typedef struct _spnode_ {
269     Uint size;                  /* size of chunk */
270     struct _spnode_ *parent;    /* parent node */
271     struct _spnode_ *left;      /* left child node */
272     struct _spnode_ *right;     /* right child node */
273 } spnode;
274 
275 static size_t dchunksz;         /* dynamic chunk size */
276 static spnode *dtree;           /* splay tree of large dynamic free chunks */
277 
278 /*
279  * NAME:        insert()
280  * DESCRIPTION: insert a chunk in the splay tree
281  */
282 static void insert(c)
283 chunk *c;
284 {
285     register spnode *n, *t;
286     register spnode *l, *r;
287     register Uint size;
288 
289     n = dtree;
290     dtree = t = (spnode *) c;
291     t->parent = (spnode *) NULL;
292 
293     if (n == (spnode *) NULL) {
294         /* first in splay tree */
295         t->left = (spnode *) NULL;
296         t->right = (spnode *) NULL;
297     } else {
298         size = t->size;
299         l = r = t;
300 
301         for (;;) {
302             if (n->size < size) {
303                 if ((t=n->right) == (spnode *) NULL) {
304                     l->right = n; n->parent = l;
305                     r->left = (spnode *) NULL;
306                     break;      /* finished */
307                 }
308                 if (t->size >= size) {
309                     l->right = n; n->parent = l;
310                     l = n;
311                     n = t;
312                 } else {
313                     /* rotate */
314                     if ((n->right=t->left) != (spnode *) NULL) {
315                         t->left->parent = n;
316                     }
317                     t->left = n; n->parent = t;
318                     l->right = t; t->parent = l;
319                     if ((n=t->right) == (spnode *) NULL) {
320                         r->left = (spnode *) NULL;
321                         break;  /* finished */
322                     }
323                     l = t;
324                 }
325             } else {
326                 if ((t=n->left) == (spnode *) NULL) {
327                     r->left = n; n->parent = r;
328                     l->right = (spnode *) NULL;
329                     break;      /* finished */
330                 }
331                 if (t->size < size) {
332                     r->left = n; n->parent = r;
333                     r = n;
334                     n = t;
335                 } else {
336                     /* rotate */
337                     if ((n->left=t->right) != (spnode *) NULL) {
338                         t->right->parent = n;
339                     }
340                     t->right = n; n->parent = t;
341                     r->left = t; t->parent = r;
342                     if ((n=t->left) == (spnode *) NULL) {
343                         l->right = (spnode *) NULL;
344                         break;  /* finished */
345                     }
346                     r = t;
347                 }
348             }
349         }
350 
351         /* exchange left and right subtree */
352         n = dtree;
353         t = n->left;
354         n->left = n->right;
355         n->right = t;
356     }
357 }
358 
359 /*
360  * NAME:        seek()
361  * DESCRIPTION: find a chunk of the proper size in the splay tree
362  */
363 static chunk *seek(size)
364 register Uint size;
365 {
366     spnode dummy;
367     register spnode *n, *t;
368     register spnode *l, *r;
369 
370     if ((n=dtree) == (spnode *) NULL) {
371         /* empty splay tree */
372         return (chunk *) NULL;
373     } else {
374         l = r = &dummy;
375 
376         for (;;) {
377             if (n->size < size) {
378                 if ((t=n->right) == (spnode *) NULL) {
379                     l->right = n; n->parent = l;
380                     if (r == &dummy) {
381                         /* all chunks are too small */
382                         dtree = dummy.right;
383                         dtree->parent = (spnode *) NULL;
384                         return (chunk *) NULL;
385                     }
386                     if ((r->parent->left=r->right) != (spnode *) NULL) {
387                         r->right->parent = r->parent;
388                     }
389                     n = r;
390                     break;      /* finished */
391                 }
392                 if (t->size >= size) {
393                     l->right = n; n->parent = l;
394                     l = n;
395                     n = t;
396                 } else {
397                     /* rotate */
398                     if ((n->right=t->left) != (spnode *) NULL) {
399                         t->left->parent = n;
400                     }
401                     t->left = n; n->parent = t;
402                     l->right = t; t->parent = l;
403                     if ((n=t->right) == (spnode *) NULL) {
404                         if (r == &dummy) {
405                             /* all chunks are too small */
406                             dtree = dummy.right;
407                             dtree->parent = (spnode *) NULL;
408                             return (chunk *) NULL;
409                         }
410                         if ((r->parent->left=r->right) != (spnode *) NULL) {
411                             r->right->parent = r->parent;
412                         }
413                         n = r;
414                         break;  /* finished */
415                     }
416                     l = t;
417                 }
418             } else {
419                 if ((t=n->left) == (spnode *) NULL) {
420                     if ((r->left=n->right) != (spnode *) NULL) {
421                         n->right->parent = r;
422                     }
423                     l->right = (spnode *) NULL;
424                     break;      /* finished */
425                 }
426                 if (t->size < size) {
427                     r->left = n; n->parent = r;
428                     r = n;
429                     n = t;
430                 } else {
431                     /* rotate */
432                     if ((n->left=t->right) != (spnode *) NULL) {
433                         t->right->parent = n;
434                     }
435                     if (t->left == (spnode *) NULL) {
436                         r->left = n; n->parent = r;
437                         l->right = (spnode *) NULL;
438                         n = t;
439                         break;  /* finished */
440                     }
441                     t->right = n; n->parent = t;
442                     r->left = t; t->parent = r;
443                     r = t;
444                     n = t->left;
445                 }
446             }
447         }
448 
449         n->parent = (spnode *) NULL;
450         if ((n->right=dummy.left) != (spnode *) NULL) {
451             dummy.left->parent = n;
452         }
453         if ((n->left=dummy.right) != (spnode *) NULL) {
454             dummy.right->parent = n;
455         }
456 
457         return (chunk *) (dtree = n);
458     }
459 }
460 
461 /*
462  * NAME:        delete()
463  * DESCRIPTION: delete a chunk from the splay tree
464  */
465 static void delete(c)
466 chunk *c;
467 {
468     register spnode *t, *r;
469     register spnode *p, *n;
470 
471     n = (spnode *) c;
472     p = n->parent;
473 
474     if (n->left == (spnode *) NULL) {
475         /* there is no left subtree */
476         if (p == (spnode *) NULL) {
477             if ((dtree=n->right) != (spnode *) NULL) {
478                 dtree->parent = (spnode *) NULL;
479             }
480         } else if (n == p->left) {
481             if ((p->left=n->right) != (spnode *) NULL) {
482                 p->left->parent = p;
483             }
484         } else if ((p->right=n->right) != (spnode *) NULL) {
485             p->right->parent = p;
486         }
487     } else {
488         t = n->left;
489 
490         /* walk to the right in the left subtree */
491         while ((r=t->right) != (spnode *) NULL) {
492             if ((t->right=r->left) != (spnode *) NULL) {
493                 r->left->parent = t;
494             }
495             r->left = t; t->parent = r;
496             t = r;
497         }
498 
499         if (p == (spnode *) NULL) {
500             dtree = t;
501         } else if (n == p->left) {
502             p->left = t;
503         } else {
504             p->right = t;
505         }
506         t->parent = p;
507         if ((t->right=n->right) != (spnode *) NULL) {
508             t->right->parent = t;
509         }
510     }
511 }
512 
513 # define DSMALL         64
514 # define DLIMIT         (DSMALL + MOFFSET)
515 # define DCHUNKS        (DSMALL / STRUCT_AL - 1)
516 # define DCHUNKSZ       32768
517 
518 static char *dlist;             /* list of dynamic memory chunks */
519 static chunk *dchunks[DCHUNKS]; /* list of free small chunks */
520 static chunk *dchunk;           /* chunk of small chunks */
521 
522 /*
523  * NAME:        dalloc()
524  * DESCRIPTION: allocate dynamic memory
525  */
526 static chunk *dalloc(size)
527 register size_t size;
528 {
529     register chunk *c;
530     register char *p;
531     register size_t sz;
532 
533     if (dchunksz == 0) {
534         /*
535          * memory manager hasn't been initialized yet
536          */
537         c = (chunk *) newmem(size, (char **) NULL);
538         c->size = size;
539         return c;
540     }
541 
542     if (size < DLIMIT) {
543         /*
544          * small chunk
545          */
546         if ((c=dchunks[(size - MOFFSET) / STRUCT_AL - 1]) != (chunk *) NULL) {
547             /* small chunk from free list */
548             dchunks[(size - MOFFSET) / STRUCT_AL - 1] = c->next;
549             return c;
550         }
551         if (dchunk == (chunk *) NULL) {
552             /* get new chunks chunk */
553             dchunk = dalloc(DCHUNKSZ);  /* cannot use alloc() here */
554             p = (char *) dchunk + UINTSIZE;
555             ((chunk *) p)->size = dchunk->size - UINTSIZE - SIZETSIZE;
556             dchunk->size |= DM_MAGIC;
557             dchunk = (chunk *) p;
558         }
559         sz = dchunk->size - size;
560         c = dchunk;
561         c->size = size;
562         if (sz >= DLIMIT - STRUCT_AL) {
563             /* enough is left for another small chunk */
564             dchunk = (chunk *) ((char *) c + size);
565             dchunk->size = sz;
566         } else {
567             /* waste sz bytes of memory */
568             dchunk = (chunk *) NULL;
569         }
570         return c;
571     }
572 
573     size += SIZETSIZE;
574     c = seek((Uint) size);
575     if (c != (chunk *) NULL) {
576         /*
577          * remove from free list
578          */
579         delete(c);
580     } else {
581         /*
582          * get new dynamic chunk
583          */
584         for (sz = dchunksz; sz < size + SIZETSIZE + UINTSIZE; sz += dchunksz) ;
585         p = newmem(sz, &dlist);
586         mstat.dmemsize += sz;
587 
588         /* no previous chunk */
589         *(size_t *) p = 0;
590         c = (chunk *) (p + SIZETSIZE);
591         /* initialize chunk */
592         c->size = sz - SIZETSIZE - UINTSIZE;
593         p += c->size;
594         *(size_t *) p = c->size;
595         /* no following chunk */
596         p += SIZETSIZE;
597         ((chunk *) p)->size = 0;
598     }
599 
600     if ((sz=c->size - size) >= DLIMIT + SIZETSIZE) {
601         /*
602          * split block, put second part in free list
603          */
604         c->size = size;
605         p = (char *) c + size - SIZETSIZE;
606         *(size_t *) p = size;
607         p += SIZETSIZE;
608         ((chunk *) p)->size = sz;
609         *((size_t *) (p + sz - SIZETSIZE)) = sz;
610         insert((chunk *) p);    /* add to free list */
611     }
612     return c;
613 }
614 
615 /*
616  * NAME:        dfree()
617  * DESCRIPTION: free dynamic memory
618  */
619 static void dfree(c)
620 register chunk *c;
621 {
622     register char *p;
623 
624     if (dchunksz == 0) {
625         /*
626          * memory manager not yet initialized
627          */
628         free((char *) c);
629         return;
630     }
631 
632     if (c->size < DLIMIT) {
633         /* small chunk */
634         c->next = dchunks[(c->size - MOFFSET) / STRUCT_AL - 1];
635         dchunks[(c->size - MOFFSET) / STRUCT_AL - 1] = c;
636         return;
637     }
638 
639     p = (char *) c - SIZETSIZE;
640     if (*(size_t *) p != 0) {
641         p -= *(size_t *) p - SIZETSIZE;
642         if ((((chunk *) p)->size & MAGIC_MASK) == 0) {
643             /*
644              * merge with previous block
645              */
646             delete((chunk *) p);
647             ((chunk *) p)->size += c->size;
648             c = (chunk *) p;
649             *((size_t *) (p + c->size - SIZETSIZE)) = c->size;
650         }
651     }
652     p = (char*) c + c->size;
653     if (((chunk *) p)->size != 0 && (((chunk *) p)->size & MAGIC_MASK) == 0) {
654         /*
655          * merge with next block
656          */
657         delete((chunk *) p);
658         c->size += ((chunk *) p)->size;
659         *((size_t *) ((char *) c + c->size - SIZETSIZE)) = c->size;
660     }
661 
662     insert(c);  /* add to free list */
663 }
664 
665 
666 /*
667  * NAME:        mem->init()
668  * DESCRIPTION: initialize memory manager
669  */
670 void m_init(ssz, dsz)
671 size_t ssz, dsz;
672 {
673     schunksz = ALGN(ssz, STRUCT_AL);
674     dchunksz = ALGN(dsz, STRUCT_AL);
675     if (schunksz != 0) {
676         if (schunk != (chunk *) NULL) {
677             schunk->next = sflist;
678             sflist = schunk;
679         }
680         schunk = (chunk *) newmem(schunksz, &slist);
681         mstat.smemsize += schunk->size = schunksz;
682     }
683 }
684 
685 
686 # ifdef DEBUG
687 static header *hlist;                   /* list of all dynamic memory chunks */
688 # endif
689 
690 /*
691  * NAME:        mem->alloc()
692  * DESCRIPTION: allocate memory
693  */
694 # ifdef DEBUG
695 char *m_alloc(size, file, line)
696 register size_t size;
697 char *file;
698 int line;
699 # else
700 char *m_alloc(size)
701 register size_t size;
702 # endif
703 {
704     register chunk *c;
705 
706 # ifdef DEBUG
707     if (size == 0) {
708         fatal("m_alloc(0)");
709     }
710 # endif
711     size = ALGN(size + MOFFSET, STRUCT_AL);
712 # ifndef DEBUG
713     if (size < ALGN(sizeof(chunk), STRUCT_AL)) {
714         size = ALGN(sizeof(chunk), STRUCT_AL);
715     }
716 # endif
717     if (slevel > 0) {
718         c = salloc(size);
719         mstat.smemused += c->size;
720         c->size |= SM_MAGIC;
721     } else {
722         c = dalloc(size);
723         mstat.dmemused += c->size;
724         c->size |= DM_MAGIC;
725 # ifdef DEBUG
726         ((header *) c)->prev = (header *) NULL;
727         ((header *) c)->next = hlist;
728         if (hlist != (header *) NULL) {
729             hlist->prev = (header *) c;
730         }
731         hlist = (header *) c;
732 # endif
733     }
734 # ifdef DEBUG
735     ((header *) c)->file = file;
736     ((header *) c)->line = line;
737 # endif
738     return (char *) c + MOFFSET;
739 }
740 
741 /*
742  * NAME:        mem->free()
743  * DESCRIPTION: free memory
744  */
745 void m_free(mem)
746 char *mem;
747 {
748     register chunk *c;
749 
750     c = (chunk *) (mem - MOFFSET);
751     if ((c->size & MAGIC_MASK) == SM_MAGIC) {
752         c->size &= SIZE_MASK;
753         mstat.smemused -= c->size;
754         sfree(c);
755     } else if ((c->size & MAGIC_MASK) == DM_MAGIC) {
756         c->size &= SIZE_MASK;
757         mstat.dmemused -= c->size;
758 # ifdef DEBUG
759         if (((header *) c)->next != (header *) NULL) {
760             ((header *) c)->next->prev = ((header *) c)->prev;
761         }
762         if (((header *) c) == hlist) {
763             hlist = ((header *) c)->next;
764         } else {
765             ((header *) c)->prev->next = ((header *) c)->next;
766         }
767 # endif
768         dfree(c);
769     } else {
770         fatal("bad pointer in m_free");
771     }
772 }
773 
774 /*
775  * NAME:        mem->realloc()
776  * DESCRIPTION: reallocate memory
777  */
778 # ifdef DEBUG
779 char *m_realloc(mem, size1, size2, file, line)
780 char *mem, *file;
781 register size_t size1, size2;
782 int line;
783 # else
784 char *m_realloc(mem, size1, size2)
785 char *mem;
786 register size_t size1, size2;
787 # endif
788 {
789     register chunk *c1, *c2;
790 
791     if (mem == (char *) NULL) {
792         if (size2 == 0) {
793             return (char *) NULL;
794         }
795 # ifdef DEBUG
796         return m_alloc(size2, file, line);
797 # else
798         return m_alloc(size2);
799 # endif
800     }
801     if (size2 == 0) {
802         m_free(mem);
803         return (char *) NULL;
804     }
805 
806     size2 = ALGN(size2 + MOFFSET, STRUCT_AL);
807 # ifndef DEBUG
808     if (size2 < ALGN(sizeof(chunk), STRUCT_AL)) {
809         size2 = ALGN(sizeof(chunk), STRUCT_AL);
810     }
811 # endif
812     c1 = (chunk *) (mem - MOFFSET);
813     if ((c1->size & MAGIC_MASK) == SM_MAGIC) {
814 # ifdef DEBUG
815         if (size1 > (c1->size & SIZE_MASK)) {
816             fatal("bad size1 in m_realloc");
817         }
818 # endif
819         if ((c1->size & SIZE_MASK) < size2) {
820             c2 = salloc(size2);
821             if (size1 != 0) {
822                 memcpy((char *) c2 + MOFFSET, mem, size1);
823             }
824             c1->size &= SIZE_MASK;
825             mstat.smemused += c2->size - c1->size;
826             c2->size |= SM_MAGIC;
827             sfree(c1);
828             c1 = c2;
829         }
830     } else if ((c1->size & MAGIC_MASK) == DM_MAGIC) {
831 # ifdef DEBUG
832         if (size1 > (c1->size & SIZE_MASK)) {
833             fatal("bad size1 in m_realloc");
834         }
835 # endif
836         if ((c1->size & SIZE_MASK) < ((size2 < DLIMIT) ?
837                                        size2 : size2 + SIZETSIZE)) {
838             c2 = dalloc(size2);
839             if (size1 != 0) {
840                 memcpy((char *) c2 + MOFFSET, mem, size1);
841             }
842             c1->size &= SIZE_MASK;
843             mstat.dmemused += c2->size - c1->size;
844             c2->size |= DM_MAGIC;
845 # ifdef DEBUG
846             ((header *) c2)->next = ((header *) c1)->next;
847             if (((header *) c1)->next != (header *) NULL) {
848                 ((header *) c2)->next->prev = (header *) c2;
849             }
850             ((header *) c2)->prev = ((header *) c1)->prev;
851             if (((header *) c1) == hlist) {
852                 hlist = (header *) c2;
853             } else {
854                 ((header *) c2)->prev->next = (header *) c2;
855             }
856 # endif
857             dfree(c1);
858             c1 = c2;
859         }
860     } else {
861         fatal("bad pointer in m_realloc");
862     }
863 # ifdef DEBUG
864     ((header *) c1)->file = file;
865     ((header *) c1)->line = line;
866 # endif
867     return (char *) c1 + MOFFSET;
868 }
869 
870 /*
871  * NAME:        mem->check()
872  * DESCRIPTION: return TRUE if there is enough static memory left, or FALSE
873  *              otherwise
874  */
875 bool m_check()
876 {
877     if (schunk == (chunk *) NULL) {
878         return FALSE;
879     } else {
880         return (schunksz == 0 || schunk->size >= schunksz);
881     }
882 }
883 
884 /*
885  * NAME:        mem->purge()
886  * DESCRIPTION: purge dynamic memory
887  */
888 void m_purge()
889 {
890     register char *p;
891 
892 # ifdef DEBUG
893     while (hlist != (header *) NULL) {
894         char buf[160];
895         register size_t n;
896 
897         n = (hlist->size & SIZE_MASK) - MOFFSET;
898         if (n >= DLIMIT) {
899             n -= SIZETSIZE;
900         }
901         sprintf(buf, "FREE(%08lx/%u), %s line %u:\012", /* LF */
902                 (unsigned long) (hlist + 1), n, hlist->file, hlist->line);
903         if (n > 26) {
904             n = 26;
905         }
906         for (p = (char *) (hlist + 1); n > 0; --n, p++) {
907             if (*p >= ' ') {
908                 sprintf(buf + strlen(buf), " '%c", *p);
909             } else {
910                 sprintf(buf + strlen(buf), " %02x", UCHAR(*p));
911             }
912         }
913         strcat(buf, "\012");    /* LF */
914         P_message(buf);
915         m_free((char *) (hlist + 1));
916     }
917 # endif
918 
919     /* purge dynamic memory */
920     while (dlist != (char *) NULL) {
921         p = dlist;
922         dlist = *(char **) p;
923         free(p);
924     }
925     memset(dchunks, '\0', sizeof(dchunks));
926     dchunk = (chunk *) NULL;
927     dtree = (spnode *) NULL;
928     mstat.dmemsize = mstat.dmemused = 0;
929 
930     if (schunksz != 0 &&
931         (schunk == (chunk *) NULL || schunk->size < schunksz ||
932          (mstat.smemsize - mstat.smemused) * 2 < schunksz * 3)) {
933         /* expand static memory */
934         if (schunk != (chunk *) NULL) {
935             schunk->next = sflist;
936             sflist = schunk;
937         }
938         schunk = (chunk *) newmem(schunksz, &slist);
939         mstat.smemsize += schunk->size = schunksz;
940     }
941 }
942 
943 /*
944  * NAME:        mem->info()
945  * DESCRIPTION: return informaton about memory usage
946  */
947 allocinfo *m_info()
948 {
949     return &mstat;
950 }
951 
952 
953 /*
954  * NAME:        mem->finish()
955  * DESCRIPTION: finish up memory manager
956  */
957 void m_finish()
958 {
959     register char *p;
960 
961     schunksz = 0;
962     dchunksz = 0;
963 
964     /* purge dynamic memory */
965 # ifdef DEBUG
966     hlist = (header *) NULL;
967 # endif
968     m_purge();
969 
970     /* purge static memory */
971     while (slist != (char *) NULL) {
972         p = slist;
973         slist = *(char **) p;
974         free(p);
975     }
976     memset(schunks, '\0', sizeof(schunks));
977     memset(lchunks, '\0', sizeof(lchunks));
978     nlc = 0;
979     schunk = (chunk *) NULL;
980     sflist = (chunk *) NULL;
981     slevel = 0;
982     mstat.smemsize = mstat.smemused = 0;
983 }
984 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.