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 2.5 by greg, Mon Jun 29 22:39:51 1992 UTC vs.
Revision 2.15 by greg, Tue May 13 17:58:32 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1992 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  
26 + #ifndef  BSD
27 + #define  bcopy(s,d,n)           (void)memcpy(d,s,n)
28 + #define  bzero(d,n)             (void)memset(d,0,n)
29 + #endif
30 +
31   #ifdef MSTATS
32   #include  <stdio.h>
33 < static unsigned b_nsbrked = 0;
33 > static unsigned b_nsbrked = 0;
34   static unsigned b_nalloced = 0;
35   static unsigned b_nfreed = 0;
36   static unsigned b_nscrounged = 0;
# Line 38 | Line 42 | static unsigned        m_nwasted = 0;
42   #define  NULL           0
43   #endif
44  
45 < #ifndef ALIGN
46 < #define  ALIGN          int                     /* align type */
45 > #ifndef ALIGNT
46 > #define  ALIGNT         int                     /* align type */
47   #endif
48 < #define  BYTES_WORD     sizeof(ALIGN)
48 > #define  BYTES_WORD     sizeof(ALIGNT)
49  
50   #ifndef  MAXINCR
51   #define  MAXINCR        (1<<16)                 /* largest sbrk(2) increment */
# Line 53 | Line 57 | typedef union m_head {
57                  short           magic;
58                  short           bucket;
59          }       a;
60 <        ALIGN           dummy;
60 >        ALIGNT          dummy;
61   } M_HEAD;
62  
63   #define MAGIC           0x1a2           /* magic number for allocated memory */
# Line 63 | Line 67 | typedef union m_head {
67  
68   static M_HEAD   *free_list[NBUCKETS];
69  
70 < static ALIGN    dummy_mem;
70 > static ALIGNT   dummy_mem;
71  
72 + static char     *memlim[2];
73 +
74   #define DUMMYLOC        ((char *)&dummy_mem)
75  
76 + #define BADPTR(p)       ((p) < memlim[0] | (p) >= memlim[1])
77 +
78   #ifdef  MCOMP                   /* memory compaction routines */
79   static char     seedtab[1024];          /* seed for compaction table */
80  
# Line 150 | Line 158 | unsigned       *np;
158  
159          for ( ; ; ) {
160                                          /* compact free lists */
161 <                compactfree();
161 >                while (compactfree())
162 >                        ;
163                                          /* find largest block */
164                  tab = mtab(&cptab); tablen = mtablen(&cptab);
165                  big = tab;
# Line 163 | Line 172 | unsigned       *np;
172                          big->siz = 0;           /* remove from table */
173                          return(big->ptr);       /* return it */
174                  }
175 <                if (mtablen(big) < tablen+1) {
175 >                if (mtablen(big) <= tablen) {
176                          *np = 0;                /* cannot grow table */
177                          return(NULL);           /* report failure */
178                  }
# Line 173 | Line 182 | unsigned       *np;
182                  cptab.ptr = big->ptr;
183                  cptab.siz = big->siz;
184                  big->siz = 0;                   /* clear and copy */
176 #ifdef BSD
185                  bcopy((char *)tab, (char *)(mtab(&cptab)+1),
186                                  tablen*sizeof(struct mblk));
187                  bzero((char *)(mtab(&cptab)+tablen+1),
188                          (mtablen(&cptab)-tablen-1)*sizeof(struct mblk));
181 #else
182                (void)memcpy((char *)(mtab(&cptab)+1), (char *)tab,
183                                tablen*sizeof(struct mblk));
184                memset((char *)(mtab(&cptab)+tablen+1), 0,
185                        (mtablen(&cptab)-tablen-1)*sizeof(struct mblk));
186 #endif
189          }                       /* next round */
190   }
191   #endif          /* MCOMP */
# Line 241 | Line 243 | register unsigned  n;
243   #endif
244                  bpos += nrem & (BYTES_WORD-1);          /* align pointer */
245                  nrem &= ~(BYTES_WORD-1);
246 +                memlim[0] = bpos;
247 +                memlim[1] = bpos + nrem;
248          }
249  
250          n = (n+(BYTES_WORD-1))&~(BYTES_WORD-1);         /* word align rqst. */
251  
252          if (n > nrem) {                                 /* need more core */
253 +        tryagain:
254                  if (n > amnt) {                         /* big chunk */
255                          thisamnt = (n+(pagesz-1))&~(pagesz-1);
256                          if (thisamnt <= MAXINCR)        /* increase amnt */
# Line 254 | Line 259 | register unsigned  n;
259                          thisamnt = amnt;
260                  p = sbrk(thisamnt);
261                  if ((int)p == -1) {                     /* uh-oh, ENOMEM */
262 <                        thisamnt = n;                   /* search free lists */
263 <                        p = mscrounge(&thisamnt);
264 <                        if (p == NULL)                  /* we're really out */
262 >                        errno = 0;                      /* call cavalry */
263 >                        if (thisamnt >= n+pagesz) {
264 >                                amnt = pagesz;          /* minimize request */
265 >                                goto tryagain;
266 >                        }
267 >                        thisamnt = n;
268 >                        p = mscrounge(&thisamnt);       /* search free lists */
269 >                        if (p == NULL) {                /* we're really out */
270 >                                errno = ENOMEM;
271                                  return(NULL);
272 +                        }
273                  }
274   #ifdef MSTATS
275                  else b_nsbrked += thisamnt;
# Line 268 | Line 280 | register unsigned  n;
280                          nrem = thisamnt;
281                  } else                                  /* otherwise tack on */
282                          nrem += thisamnt;
283 +                if (bpos < memlim[0])
284 +                        memlim[0] = bpos;
285 +                if (bpos + nrem > memlim[1])
286 +                        memlim[1] = bpos + nrem;
287          }
288          p = bpos;
289          bpos += n;                                      /* advance */
# Line 286 | Line 302 | register unsigned  n;
302          register int    bucket;
303          register unsigned       bsiz;
304  
305 <        if (n < 1<<FIRSTBUCKET)
305 >        if (n < 1<<FIRSTBUCKET || p == NULL)
306                  return;
307   #ifdef MSTATS
308          b_nfreed += n;
# Line 297 | Line 313 | register unsigned  n;
313                  p += bsiz;
314                  n -= bsiz;
315          }
316 +        if (p < memlim[0])
317 +                memlim[0] = p;
318 +        if (p + n > memlim[1])
319 +                memlim[1] = p + n;
320                                          /* fill big buckets first */
321          for (bucket = NBUCKETS-1, bsiz = 1<<(NBUCKETS-1);
322                          bucket >= FIRSTBUCKET; bucket--, bsiz >>= 1)
# Line 313 | Line 333 | char *
333   malloc(n)                       /* allocate n bytes of memory */
334   unsigned        n;
335   {
316        extern int  errno;
336          register M_HEAD *mp;
337          register int    bucket;
338          register unsigned       bsiz;
# Line 355 | Line 374 | unsigned       n;
374          char    *p;
375          register unsigned       on;
376                                          /* get old size */
377 <        if (op != NULL && op != DUMMYLOC && ((M_HEAD *)op-1)->a.magic == MAGIC)
377 >        if (op != DUMMYLOC && !BADPTR(op) &&
378 >                        ((M_HEAD *)op-1)->a.magic == MAGIC)
379                  on = 1 << ((M_HEAD *)op-1)->a.bucket;
380          else
381                  on = 0;
# Line 364 | Line 384 | unsigned       n;
384          if ((p = malloc(n)) == NULL)
385                  return(n<=on ? op : NULL);
386          if (on) {
367 #ifdef  BSD
387                  bcopy(op, p, n>on ? on : n);
369 #else
370                (void)memcpy(p, op, n>on ? on : n);
371 #endif
388                  free(op);
389          }
390          return(p);
# Line 381 | Line 397 | char   *p;
397          register M_HEAD *mp;
398          register int    bucket;
399  
400 <        if (p == NULL | p == DUMMYLOC)
400 >        if (p == DUMMYLOC)
401                  return(1);
402 +        if (BADPTR(p))
403 +                goto invalid;
404          mp = (M_HEAD *)p - 1;
405          if (mp->a.magic != MAGIC)               /* sanity check */
406 <                return(0);
406 >                goto invalid;
407          bucket = mp->a.bucket;
408          if (bucket < FIRSTBUCKET | bucket >= NBUCKETS)
409 <                return(0);
409 >                goto invalid;
410          mp->next = free_list[bucket];
411          free_list[bucket] = mp;
412   #ifdef MSTATS
413          m_nfreed += (1 << bucket) + sizeof(M_HEAD);
414   #endif
415          return(1);
416 + invalid:
417 +        errno = EINVAL;
418 +        return(0);
419   }
420  
421  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines