Modified the UGetCursor() routine to return a valid response if the
[xcircuit.git] / spiceparser / memory.c
blob64f390bd90bb389678a5ca4374fdd34a82273e5b
1 /********************
2 This file is part of the software library CADLIB written by Conrad Ziesler
3 Copyright 2003, Conrad Ziesler, all rights reserved.
5 *************************
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 ******************/
21 /* memory.c, sequential memory allocator
22 Conrad Ziesler
23 */
26 these routines are used to allocate char aligned
27 objects (namely strings) in such a way that we
28 1. allocate in big chunks
29 2. keep track of all the chunk allocations
30 3. free a bunch at once without having to
31 remember all the little pointers we once had.
33 this allows any module to maintain private string
34 (or equations too) storage space that is leak-proof
36 #include "debug.h"
37 #include "memory.h"
40 static memory_chain_t *memory_newblock(void)
42 int i;
43 memory_chain_t *p;
44 p=malloc(sizeof(memory_chain_t));
45 p->q=0;
46 for(i=0;i<4;i++)p->magic[i]=MEMORY_MAGIC+i;
47 p->next=NULL;
48 p->qref=0;
49 /*assert(p!=((void *)0x80d8008)); */
50 return p;
53 void memory_init(memory_t *ma)
55 memory_t def=MEMORY_INIT;
56 *ma=def;
59 void memory_checkblock(memory_chain_t *p)
61 int i;
62 for(i=0;i<4;i++)
63 if(p->magic[i]!=MEMORY_MAGIC+i)
64 assert(0);
67 void *memory_alloc(memory_t *ma, int size)
69 memory_chain_t *p,*pp;
70 memory_other_t *op;
72 if(size==0)return NULL;
74 /* round up to word alignment, thus all allocations will be aligned */
75 size=(size+(sizeof(int)-1))&(~(sizeof(int)-1));
77 /* directly allocate big blocks */
78 if(size> (MEMORY_CHUNKSIZE/2))
80 op=malloc(size+sizeof(memory_other_t)+4);
81 op->next=ma->others;
82 ma->others=op;
83 return (op+1);
86 /* indirectly allocate small blocks */
87 while(1)
89 for(pp=NULL,p=ma->head;p!=NULL;p=p->next)
91 memory_checkblock(p);
92 if((MEMORY_CHUNKSIZE-p->q)>=size)
94 void *d=p->data+p->q;
95 p->q+=size;
96 p->qref++;
97 if(p->q> (MEMORY_CHUNKSIZE-MEMORY_THRESHOLD))
99 if(pp==NULL)
101 ma->head=p->next;
102 p->next=ma->full;
103 ma->full=p;
105 else
107 pp->next=p->next;
108 p->next=ma->full;
109 ma->full=p;
112 return d;
114 pp=p;
117 if(ma->head==NULL) ma->head= memory_newblock();
118 else
120 for(pp=NULL,p=ma->head;p!=NULL;p=p->next)
121 pp=p;
122 pp->next=memory_newblock();
129 void memory_free(memory_t *ma, void *vp)
131 memory_chain_t *p,*pp, **hp;
132 char *ca,*cb,*c=vp;
133 memory_other_t *op,*pop;
135 for(hp=&ma->head,pp=NULL,p=ma->head;p!=NULL;p=p->next)
137 ca=(void*)p;
138 cb=(void*) (p+1);
139 if((c>=ca)&&(c<cb)) { p->qref--; break; }
140 pp=p;
142 if(p!=NULL)
143 for(hp=&ma->full,pp=NULL,p=ma->full;p!=NULL;p=p->next)
145 ca=(void*)p;
146 cb=(void*) (p+1);
147 if((c>=ca)&&(c<cb)) { p->qref--; break; }
148 pp=p;
150 if(p!=NULL)
152 if(pp==NULL)
153 *hp=p->next;
154 else
155 pp->next=p->next;
156 free(p);
157 return ;
160 for(pop=NULL,op=ma->others;op!=NULL;op=op->next)
162 if(op==vp)
164 if(pop==NULL)ma->others=op->next;
165 else pop->next=ma->others;
166 free(op);
167 return;
169 pop=op;
173 void memory_freeall(memory_t *ma)
175 memory_chain_t *p,*pp;
176 memory_other_t *op,*pop;
178 for(pp=NULL,p=ma->head;p!=NULL;p=p->next)
180 if(pp!=NULL)
182 memory_checkblock(pp);
183 free(pp);
185 pp=p;
188 if(pp!=NULL)
190 memory_checkblock(pp);
191 free(pp);
193 ma->head=NULL;
195 for(pp=NULL,p=ma->full;p!=NULL;p=p->next)
197 if(pp!=NULL)
199 memory_checkblock(pp);
200 free(pp);
202 pp=p;
205 if(pp!=NULL)
207 memory_checkblock(pp);
208 free(pp);
210 ma->full=NULL;
211 for(pop=NULL,op=ma->others;op!=NULL;op=op->next)
213 if(pop!=NULL)
214 free(pop);
215 pop=op;
217 if(pop!=NULL)
219 free(pop);
221 ma->others=NULL;