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

# User Rev Content
1 greg 1.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