ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/malloc.c
Revision: 1.1
Committed: Tue Sep 25 17:14:04 1990 UTC (33 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

# Content
1 /* Copyright (c) 1990 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * Fast malloc for memory hogs and VM environments.
9 * Performs a minimum of searching through free lists.
10 * bmalloc() doesn't keep track of free lists -- it's basically
11 * just a buffered call to sbrk().
12 * bfree() puts memory from any source into malloc() free lists.
13 * malloc(), realloc() and free() use buckets
14 * containing blocks in powers of two, similar to CIT routines.
15 *
16 * Greg Ward Lawrence Berkeley Laboratory
17 */
18
19 #define NULL 0
20
21 #ifndef ALIGN
22 #define ALIGN int /* align type */
23 #endif
24 #define BYTES_WORD sizeof(ALIGN)
25
26 #ifdef NOVMEM
27 #define getpagesize() BYTES_WORD
28 #endif
29
30 /* malloc free lists */
31 typedef union m_head {
32 union m_head *next;
33 int bucket;
34 ALIGN dummy;
35 } M_HEAD;
36
37 #define FIRSTBUCKET 3
38 #define NBUCKETS 30
39
40 static M_HEAD *free_list[NBUCKETS];
41
42
43 char *
44 bmalloc(n) /* allocate a block of n bytes, sans header */
45 register unsigned n;
46 {
47 extern char *sbrk();
48 static int pagesz = 0;
49 static int amnt;
50 static char *bpos;
51 static int nrem;
52 register char *p;
53
54 if (pagesz == 0) { /* initialize */
55 amnt = pagesz = getpagesize();
56 nrem = (int)sbrk(0); /* page align break */
57 nrem = pagesz - (nrem&(pagesz-1));
58 bpos = sbrk(nrem); /* word aligned! */
59 if ((int)bpos == -1)
60 return(NULL);
61 }
62
63 n = (n+(BYTES_WORD-1))&~(BYTES_WORD-1); /* word align rqst. */
64
65 if (n > nrem) { /* need more core */
66 if (n > amnt) /* increase amount */
67 amnt = (n+(pagesz-1))&~(pagesz-1);
68 p = sbrk(amnt);
69 if ((int)p == -1)
70 return(NULL);
71 if (p != bpos+nrem) { /* someone called sbrk()! */
72 bfree(bpos, nrem);
73 bpos = p;
74 nrem = amnt;
75 } else
76 nrem += amnt;
77 }
78 p = bpos;
79 bpos += n; /* advance */
80 nrem -= n;
81 return(p);
82 }
83
84
85 bfree(p, n) /* free n bytes of random memory */
86 char *p;
87 unsigned n;
88 {
89 register M_HEAD *mp;
90 register int bucket;
91 register unsigned bsiz;
92 /* find largest bucket */
93 bucket = 0;
94 for (bsiz = 1; bsiz+sizeof(M_HEAD) <= n; bsiz <<= 1)
95 bucket++;
96 mp = (M_HEAD *)p;
97 while (bucket > FIRSTBUCKET) {
98 bsiz >>= 1;
99 bucket--;
100 if (n < bsiz+sizeof(M_HEAD)) /* nothing for this bucket */
101 continue;
102 mp->next = free_list[bucket];
103 free_list[bucket] = mp;
104 (char *)mp += bsiz+sizeof(M_HEAD);
105 n -= bsiz+sizeof(M_HEAD);
106 }
107 }
108
109
110 char *
111 malloc(n) /* allocate n bytes of memory */
112 unsigned n;
113 {
114 register M_HEAD *mp;
115 register int bucket;
116 register unsigned bsiz;
117
118 bucket = FIRSTBUCKET;
119 for (bsiz = 1<<FIRSTBUCKET; bsiz < n; bsiz <<= 1)
120 bucket++;
121 if (free_list[bucket] == NULL) {
122 mp = (M_HEAD *)bmalloc(bsiz+sizeof(M_HEAD));
123 if (mp == NULL)
124 return(NULL);
125 } else {
126 mp = free_list[bucket];
127 free_list[bucket] = mp->next;
128 }
129 mp->bucket = bucket;
130 return((char *)(mp+1));
131 }
132
133
134 char *
135 realloc(op, n) /* reallocate memory using malloc() */
136 char *op;
137 unsigned n;
138 {
139 register char *p;
140 register unsigned on;
141
142 if (op != NULL)
143 on = 1 << ((M_HEAD *)op-1)->bucket;
144 else
145 on = 0;
146 if (n <= on && n > on>>1)
147 return(op); /* same bucket */
148 p = malloc(n);
149 if (p == NULL)
150 return(NULL);
151 #ifdef BSD
152 bcopy(op, p, n>on ? on : n);
153 #else
154 (void)memcpy(p, op, n>on ? on : n);
155 #endif
156 free(op);
157 return(p);
158 }
159
160
161 free(p) /* free memory allocated by malloc */
162 char *p;
163 {
164 register M_HEAD *mp;
165 register int bucket;
166
167 mp = (M_HEAD *)p - 1;
168 bucket = mp->bucket;
169 mp->next = free_list[bucket];
170 free_list[bucket] = mp;
171 }
172
173
174 #ifndef NOVMEM
175 #ifndef BSD
176 #include <sys/var.h>
177 int
178 getpagesize() /* use SYSV var structure to get page size */
179 {
180 static int pagesz = 0;
181 struct var v;
182
183 if (pagesz == 0) {
184 uvar(&v);
185 pagesz = 1 << v.v_pageshift;
186 }
187 return(pagesz);
188 }
189 #endif
190 #endif