home *** CD-ROM | disk | FTP | other *** search
/ Total Destruction / Total_Destruction.iso / addons / Lccwin32.exe / Lccwin32 / lccpub / src / Alloc.c next >
Encoding:
C/C++ Source or Header  |  1997-11-11  |  2.5 KB  |  123 lines

  1. #include "c.h"
  2. #define ALLOCSIZE 64*1024
  3. struct block {
  4.     struct block *next;
  5.     char *limit;
  6.     char *avail;
  7. };
  8. union align {
  9.     long l;
  10.     char *p;
  11.     double d;
  12.     int (*f) ARGS((void));
  13. };
  14. union header {
  15.     struct block b;
  16.     union align a;
  17. };
  18. #ifdef PURIFY
  19. union header *arena[4];
  20.  
  21. void *allocate(n, a) unsigned long n, a; {
  22.     union header *new = malloc(sizeof *new + n);
  23.  
  24.     assert(a < NELEMS(arena));
  25.     if (new == NULL) {
  26.         error("insufficient memory\n");
  27.         exit(1);
  28.     }
  29.     new->b.next = (void *)arena[a];
  30.     arena[a] = new;
  31.     return new + 1;
  32. }
  33.  
  34. void deallocate(a) unsigned a; {
  35.     union header *p, *q;
  36.  
  37.     assert(a < NELEMS(arena));
  38.     for (p = arena[a]; p; p = q) {
  39.         q = (void *)p->b.next;
  40.         free(p);
  41.     }
  42.     arena[a] = NULL;
  43. }
  44.  
  45. void *newarray(m, n, a) unsigned long m, n; unsigned a; {
  46.     return allocate(m*n, a);
  47. }
  48. #else
  49. #ifndef ASM_LIB
  50. static
  51. #endif
  52. struct block
  53.      first[] = {  { NULL },  { NULL },  { NULL },{NULL},{NULL} },
  54.     *arena[] = { &first[0], &first[1], &first[2],&first[3],&first[4]};
  55. static struct block *freeblocks;
  56. int memused=0;
  57. void *allocateslow(register unsigned long n, unsigned a);
  58. #ifndef ASM_LIB
  59. void *allocate(unsigned long n,unsigned a)
  60. {
  61.     struct block *ap;
  62.     void *r=NULL;
  63.     ap = arena[a];
  64.     n = roundup(n, sizeof (union align));
  65.     if (ap->avail + n <= ap->limit) {
  66.         r = ap->avail;
  67.         ap->avail += n;
  68.         return r;
  69.     }
  70.     else
  71.     return allocateslow(n,a);
  72. }
  73. #else
  74. extern void *allocate(unsigned long n,unsigned a);
  75. #endif
  76. extern void * _stdcall GlobalAlloc(unsigned int,unsigned long);
  77.  
  78. void *allocateslow(register unsigned long n, unsigned a)
  79. {
  80.     register struct block *ap;
  81.  
  82. //    assert(a < NELEMS(arena));
  83. //    assert(n > 0);
  84.     ap = arena[a];
  85. //    n = roundup(n, sizeof (union align));
  86.     while (ap->avail + n > ap->limit) {
  87.         if ((ap->next = freeblocks) != NULL) {
  88.             freeblocks = freeblocks->next;
  89.             ap = ap->next;
  90.         } else
  91.             {
  92.                 ap->next = GlobalAlloc(0,ALLOCSIZE);
  93.                 ap = ap->next;
  94.                 if (ap == NULL) {
  95.                     error("insufficient memory\n");
  96.                     exit(1);
  97.                 }
  98.                 ap->limit = (char *)ap + ALLOCSIZE;
  99.                 memused += ALLOCSIZE;
  100.             }
  101.         ap->avail = (char *)((union header *)ap + 1);
  102.         ap->next = NULL;
  103.         arena[a] = ap;
  104.  
  105.     }
  106.     ap->avail += n;
  107.     return ap->avail - n;
  108. }
  109.  
  110. void *newarray(unsigned long m,unsigned long n,unsigned a)
  111. {
  112.     return allocate(m*n, a);
  113. }
  114. void deallocate(unsigned a) 
  115. {
  116.     assert(a < NELEMS(arena));
  117.     arena[a]->next = freeblocks;
  118.     freeblocks = first[a].next;
  119.     first[a].next = NULL;
  120.     arena[a] = &first[a];
  121. }
  122. #endif
  123.