ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/malloc.c
(Generate patch)

Comparing ray/src/common/malloc.c (file contents):
Revision 1.14 by greg, Mon Aug 26 10:12:24 1991 UTC vs.
Revision 2.16 by schorsch, Mon Jun 30 14:59:11 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1991 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * Fast malloc for memory hogs and VM environments.
6   * Performs a minimum of searching through free lists.
# Line 22 | Line 19 | static char SCCSid[] = "$SunId$ LBL";
19   *      Greg Ward       Lawrence Berkeley Laboratory
20   */
21  
22 + #include "copyright.h"
23 +
24   #include  <errno.h>
25 + #include  <string.h>
26  
27 +
28   #ifdef MSTATS
29   #include  <stdio.h>
30 < static unsigned b_nsbrked = 0;
30 > static unsigned b_nsbrked = 0;
31   static unsigned b_nalloced = 0;
32   static unsigned b_nfreed = 0;
33   static unsigned b_nscrounged = 0;
# Line 38 | Line 39 | static unsigned        m_nwasted = 0;
39   #define  NULL           0
40   #endif
41  
42 < #ifndef ALIGN
43 < #define  ALIGN          int                     /* align type */
42 > #ifndef ALIGNT
43 > #define  ALIGNT         int                     /* align type */
44   #endif
45 < #define  BYTES_WORD     sizeof(ALIGN)
45 > #define  BYTES_WORD     sizeof(ALIGNT)
46  
47 + #ifndef  MAXINCR
48   #define  MAXINCR        (1<<16)                 /* largest sbrk(2) increment */
47
48 #ifdef  NOVMEM
49 #define  getpagesize()  1024
49   #endif
50                                          /* malloc free lists */
51   typedef union m_head {
# Line 55 | Line 54 | typedef union m_head {
54                  short           magic;
55                  short           bucket;
56          }       a;
57 <        ALIGN           dummy;
57 >        ALIGNT          dummy;
58   } M_HEAD;
59  
60   #define MAGIC           0x1a2           /* magic number for allocated memory */
# Line 65 | Line 64 | typedef union m_head {
64  
65   static M_HEAD   *free_list[NBUCKETS];
66  
67 < static ALIGN    dummy_mem;
67 > static ALIGNT   dummy_mem;
68  
69 + static char     *memlim[2];
70 +
71   #define DUMMYLOC        ((char *)&dummy_mem)
72  
73 + #define BADPTR(p)       ((p) < memlim[0] | (p) >= memlim[1])
74 +
75   #ifdef  MCOMP                   /* memory compaction routines */
76   static char     seedtab[1024];          /* seed for compaction table */
77  
# Line 152 | Line 155 | unsigned       *np;
155  
156          for ( ; ; ) {
157                                          /* compact free lists */
158 <                compactfree();
158 >                while (compactfree())
159 >                        ;
160                                          /* find largest block */
161                  tab = mtab(&cptab); tablen = mtablen(&cptab);
162                  big = tab;
# Line 165 | Line 169 | unsigned       *np;
169                          big->siz = 0;           /* remove from table */
170                          return(big->ptr);       /* return it */
171                  }
172 <                if (mtablen(big) < tablen+1) {
172 >                if (mtablen(big) <= tablen) {
173                          *np = 0;                /* cannot grow table */
174                          return(NULL);           /* report failure */
175                  }
# Line 175 | Line 179 | unsigned       *np;
179                  cptab.ptr = big->ptr;
180                  cptab.siz = big->siz;
181                  big->siz = 0;                   /* clear and copy */
182 < #ifdef BSD
179 <                bcopy((char *)tab, (char *)(mtab(&cptab)+1),
182 >                memcpy((char *)(mtab(&cptab)+1), (char *)tab,
183                                  tablen*sizeof(struct mblk));
184 <                bzero((char *)(mtab(&cptab)+tablen+1),
184 >                memset((char *)(mtab(&cptab)+tablen+1), '\0',
185                          (mtablen(&cptab)-tablen-1)*sizeof(struct mblk));
183 #else
184                (void)memcpy((char *)(mtab(&cptab)+1), (char *)tab,
185                                tablen*sizeof(struct mblk));
186                memset((char *)(mtab(&cptab)+tablen+1), 0,
187                        (mtablen(&cptab)-tablen-1)*sizeof(struct mblk));
188 #endif
186          }                       /* next round */
187   }
188   #endif          /* MCOMP */
# Line 235 | Line 232 | register unsigned  n;
232                  pagesz = amnt = getpagesize();
233                  nrem = (int)sbrk(0);                    /* page align break */
234                  nrem = pagesz - (nrem&(pagesz-1));
235 <                bpos = sbrk(nrem);                      /* word aligned! */
235 >                bpos = sbrk(nrem);
236                  if ((int)bpos == -1)
237                          return(NULL);
238   #ifdef MSTATS
239                  b_nsbrked += nrem;
240   #endif
241 +                bpos += nrem & (BYTES_WORD-1);          /* align pointer */
242 +                nrem &= ~(BYTES_WORD-1);
243 +                memlim[0] = bpos;
244 +                memlim[1] = bpos + nrem;
245          }
246  
247          n = (n+(BYTES_WORD-1))&~(BYTES_WORD-1);         /* word align rqst. */
248  
249          if (n > nrem) {                                 /* need more core */
250 +        tryagain:
251                  if (n > amnt) {                         /* big chunk */
252                          thisamnt = (n+(pagesz-1))&~(pagesz-1);
253                          if (thisamnt <= MAXINCR)        /* increase amnt */
# Line 254 | Line 256 | register unsigned  n;
256                          thisamnt = amnt;
257                  p = sbrk(thisamnt);
258                  if ((int)p == -1) {                     /* uh-oh, ENOMEM */
259 <                        thisamnt = n;                   /* search free lists */
260 <                        p = mscrounge(&thisamnt);
261 <                        if (p == NULL)                  /* we're really out */
259 >                        errno = 0;                      /* call cavalry */
260 >                        if (thisamnt >= n+pagesz) {
261 >                                amnt = pagesz;          /* minimize request */
262 >                                goto tryagain;
263 >                        }
264 >                        thisamnt = n;
265 >                        p = mscrounge(&thisamnt);       /* search free lists */
266 >                        if (p == NULL) {                /* we're really out */
267 >                                errno = ENOMEM;
268                                  return(NULL);
269 +                        }
270                  }
271   #ifdef MSTATS
272                  else b_nsbrked += thisamnt;
# Line 268 | Line 277 | register unsigned  n;
277                          nrem = thisamnt;
278                  } else                                  /* otherwise tack on */
279                          nrem += thisamnt;
280 +                if (bpos < memlim[0])
281 +                        memlim[0] = bpos;
282 +                if (bpos + nrem > memlim[1])
283 +                        memlim[1] = bpos + nrem;
284          }
285          p = bpos;
286          bpos += n;                                      /* advance */
# Line 286 | Line 299 | register unsigned  n;
299          register int    bucket;
300          register unsigned       bsiz;
301  
302 +        if (n < 1<<FIRSTBUCKET || p == NULL)
303 +                return;
304   #ifdef MSTATS
305          b_nfreed += n;
306   #endif
# Line 295 | Line 310 | register unsigned  n;
310                  p += bsiz;
311                  n -= bsiz;
312          }
313 +        if (p < memlim[0])
314 +                memlim[0] = p;
315 +        if (p + n > memlim[1])
316 +                memlim[1] = p + n;
317                                          /* fill big buckets first */
318          for (bucket = NBUCKETS-1, bsiz = 1<<(NBUCKETS-1);
319                          bucket >= FIRSTBUCKET; bucket--, bsiz >>= 1)
# Line 311 | Line 330 | char *
330   malloc(n)                       /* allocate n bytes of memory */
331   unsigned        n;
332   {
314        extern int  errno;
333          register M_HEAD *mp;
334          register int    bucket;
335          register unsigned       bsiz;
# Line 353 | Line 371 | unsigned       n;
371          char    *p;
372          register unsigned       on;
373                                          /* get old size */
374 <        if (op != NULL && op != DUMMYLOC && ((M_HEAD *)op-1)->a.magic == MAGIC)
374 >        if (op != DUMMYLOC && !BADPTR(op) &&
375 >                        ((M_HEAD *)op-1)->a.magic == MAGIC)
376                  on = 1 << ((M_HEAD *)op-1)->a.bucket;
377          else
378                  on = 0;
379          if (n <= on && (n > on>>1 || on == 1<<FIRSTBUCKET))
380                  return(op);             /* same bucket */
381          if ((p = malloc(n)) == NULL)
382 <                return(NULL);
382 >                return(n<=on ? op : NULL);
383          if (on) {
384 < #ifdef  BSD
366 <                bcopy(op, p, n>on ? on : n);
367 < #else
368 <                (void)memcpy(p, op, n>on ? on : n);
369 < #endif
384 >                memcpy(p, op, n>on ? on : n);
385                  free(op);
386          }
387          return(p);
# Line 379 | Line 394 | char   *p;
394          register M_HEAD *mp;
395          register int    bucket;
396  
397 <        if (p == NULL || p == DUMMYLOC)
397 >        if (p == DUMMYLOC)
398                  return(1);
399 +        if (BADPTR(p))
400 +                goto invalid;
401          mp = (M_HEAD *)p - 1;
402          if (mp->a.magic != MAGIC)               /* sanity check */
403 <                return(0);
403 >                goto invalid;
404          bucket = mp->a.bucket;
405 +        if (bucket < FIRSTBUCKET | bucket >= NBUCKETS)
406 +                goto invalid;
407          mp->next = free_list[bucket];
408          free_list[bucket] = mp;
409   #ifdef MSTATS
410          m_nfreed += (1 << bucket) + sizeof(M_HEAD);
411   #endif
412          return(1);
413 + invalid:
414 +        errno = EINVAL;
415 +        return(0);
416   }
395
396
397 #ifndef NOVMEM
398 #ifndef BSD
399 #include <sys/var.h>
400 int
401 getpagesize()                   /* use SYSV var structure to get page size */
402 {
403        struct var  v;
404
405        uvar(&v);
406        return(1 << v.v_pageshift);
407 }
408 #endif
409 #endif
417  
418  
419   #ifdef MSTATS

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines