home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / z / zsh220.zip / zsh2.2 / src / mem.c < prev    next >
C/C++ Source or Header  |  1992-05-07  |  5KB  |  254 lines

  1. /*
  2.  *
  3.  * mem.c - memory management
  4.  *
  5.  * This file is part of zsh, the Z shell.
  6.  *
  7.  * This software is Copyright 1992 by Paul Falstad
  8.  *
  9.  * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  10.  * use this software as long as: there is no monetary profit gained
  11.  * specifically from the use or reproduction of this software, it is not
  12.  * sold, rented, traded or otherwise marketed, and this copyright notice is
  13.  * included prominently in any copy made. 
  14.  *
  15.  * The author make no claims as to the fitness or correctness of this software
  16.  * for any use whatsoever, and it is provided as is. Any use of this software
  17.  * is at the user's own risk. 
  18.  *
  19.  */
  20. /*
  21.  
  22.     mem.c - memory management
  23.  
  24.     This file is part of zsh, the Z shell.
  25.  
  26.     zsh is free software; no one can prevent you from reading the source
  27.    code, or giving it to someone else.
  28.  
  29.    This file is copyrighted under the GNU General Public License, which
  30.    can be found in the file called COPYING.
  31.  
  32.    Copyright (C) 1990, 1991 Paul Falstad
  33.  
  34. */
  35.  
  36. #include "zsh.h"
  37. #define HEAPSIZE 8192
  38.  
  39. /*
  40.  
  41.     There are two ways to allocate memory in zsh.  The first way is
  42.     to call zalloc/zcalloc, which call malloc/calloc directly.  It
  43.     is legal to call realloc() or free() on memory allocated this way.
  44.     The second way is to call halloc/hcalloc, which allocates memory
  45.     from one of the memory pools on the heap stack.  A pool can be
  46.     created by calling pushheap(), and destroyed by calling popheap().
  47.     To free the memory in the pool without destroying it, call
  48.     freeheap(); this is equivalent to { popheap(); pushheap(); }
  49.     Memory allocated in this way does not have to be freed explicitly;
  50.     it will all be freed when the pool is destroyed.  In fact,
  51.     attempting to free this memory may result in a core dump.
  52.     The pair of pointers ncalloc and alloc may point to either
  53.     zalloc & zcalloc or halloc & hcalloc; permalloc() sets them to the
  54.     former, and heapalloc() sets them to the latter. This can be useful.
  55.     For example, the dupstruct() routine duplicates a syntax tree,
  56.     allocating the new memory for the tree using alloc().  If you want
  57.     to duplicate a structure for a one-time use (i.e. to execute the list
  58.     in a for loop), call heapalloc(), then dupstruct().  If you want
  59.     to duplicate a structure in order to preserve it (i.e. a function
  60.     definition), call permalloc(), then dupstruct().
  61.  
  62. */
  63.  
  64. /* initialize heap stack */
  65.  
  66. void meminit() /**/
  67. {
  68.     permalloc();
  69.     heaplist = newlist();
  70.     pushheap();
  71. }
  72.  
  73. /* set default allocation to heap stack */
  74.  
  75. void heapalloc() /**/
  76. {
  77.     alloc = hcalloc;
  78.     ncalloc = halloc;
  79.     useheap = 1;
  80. }
  81.  
  82. static vptr (*lastcalloc) DCLPROTO((int));
  83. static vptr (*lastncalloc) DCLPROTO((int));
  84.  
  85. /* set default allocation to malloc() */
  86.  
  87. void permalloc() /**/
  88. {
  89.     lastcalloc = alloc;
  90.     lastncalloc = ncalloc;
  91.     alloc = zcalloc;
  92.     ncalloc = zalloc;
  93.     useheap = 0;
  94. }
  95.  
  96. /* reset previous default allocation */
  97.  
  98. void lastalloc() /**/
  99. {
  100.     alloc = lastcalloc;
  101.     ncalloc = lastncalloc;
  102. }
  103.  
  104. struct heap {
  105.     char *pool,*ptr;
  106.     int free;
  107.     struct heap *next;
  108.     };
  109.  
  110. /* create a memory pool */
  111.  
  112. void pushheap() /**/
  113. {
  114. Heap h;
  115.  
  116.     h = (Heap) zalloc(sizeof *h);
  117.     h->pool = h->ptr = zalloc(HEAPSIZE);
  118.     h->free = HEAPSIZE;
  119.     h->next = NULL;
  120.     permalloc();
  121.     pushnode(heaplist,h);
  122.     lastalloc();
  123. }
  124.  
  125. /* reset a memory pool */
  126.  
  127. void freeheap() /**/
  128. {
  129. Heap h = (Heap) peekfirst(heaplist);
  130.  
  131.     freeh(h->next);
  132.     h->next = NULL;
  133.     h->free += (h->ptr-h->pool);
  134.     h->ptr = h->pool;
  135. }
  136.  
  137. /* destroy a memory pool */
  138.  
  139. void popheap() /**/
  140. {
  141. Heap h = (Heap) getnode(heaplist);
  142.  
  143.     freeh(h);
  144. }
  145.  
  146. void freeh(h) /**/
  147. Heap h;
  148. {
  149.     if (h)
  150.         {
  151.         freeh(h->next);
  152.         free(h->pool);
  153.         free(h);
  154.         }
  155. }
  156.  
  157. /* allocate memory from the current memory pool */
  158.  
  159. vptr halloc(size) /**/
  160. int size;
  161. {
  162. Heap h = (Heap) peekfirst(heaplist),h2;
  163. char *ret;
  164.  
  165.     size = (size|7)+1;
  166.     while (h && h->free-size < 0)
  167.         h = h->next;
  168.     if (!h) {
  169.         h2 = (Heap) zalloc(sizeof *h2);
  170.         h2->pool = h2->ptr = zalloc(h2->free = 
  171.             (size < HEAPSIZE) ? HEAPSIZE : (size|(HEAPSIZE-1))+1);
  172.         h2->next = (Heap) peekfirst(heaplist);
  173.         setdata(firstnode(heaplist),(vptr) h2);
  174.         h = h2;
  175.     }
  176.     h->free -= size;
  177.     ret = h->ptr;
  178.     h->ptr += size;
  179.     return ret;
  180. }
  181.  
  182. /* allocate memory from the current memory pool and clear it */
  183.  
  184. vptr hcalloc(size) /**/
  185. int size;
  186. {
  187. vptr ptr;
  188.  
  189.     ptr = halloc(size);
  190.     memset(ptr,0,size);
  191.     return ptr;
  192. }
  193.  
  194. vptr hrealloc(p,old,new) /**/
  195. char *p;int old;int new;
  196. {
  197. char *ptr;
  198.  
  199.     ptr = halloc(new);
  200.     memcpy(ptr,p,old);
  201.     return ptr;
  202. }
  203.  
  204. /* allocate permanent memory */
  205.  
  206. vptr zalloc(l) /**/
  207. int l;
  208. {
  209. vptr z;
  210.  
  211.     if (!l) l = 1;
  212.     if (!(z = malloc(l)))
  213.         {
  214.         zerr("fatal error: out of memory",NULL,0);
  215.         exit(1);
  216.         }
  217.     return z;
  218. }
  219.  
  220. vptr zcalloc(size) /**/
  221. int size;
  222. {
  223. vptr ptr;
  224.  
  225.     ptr = zalloc(size);
  226.     memset(ptr,0,size);
  227.     return ptr;
  228. }
  229.  
  230. char *strdup(s) /**/
  231. char *s;
  232. {
  233. char *t;
  234.  
  235.     if (!s)
  236.         return NULL;
  237.     t = ncalloc(strlen(s)+1);
  238.     strcpy(t,s);
  239.     return t;
  240. }
  241.  
  242. char *ztrdup(s) /**/
  243. char *s;
  244. {
  245. char *t;
  246.  
  247.     if (!s)
  248.         return NULL;
  249.     t = zalloc(strlen(s)+1);
  250.     strcpy(t,s);
  251.     return t;
  252. }
  253.  
  254.