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.8 by greg, Thu Oct 8 12:27:02 1992 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1991 Regents of the University of California */
1 > /* Copyright (c) 1992 Regents of the University of California */
2  
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ LBL";
# Line 24 | Line 24 | static char SCCSid[] = "$SunId$ LBL";
24  
25   #include  <errno.h>
26  
27 + #ifndef  BSD
28 + #define  bcopy(s,d,n)           (void)memcpy(d,s,n)
29 + #define  bzero(d,n)             (void)memset(d,0,n)
30 + extern char  *memcpy(), *memset();
31 + #endif
32 +
33   #ifdef MSTATS
34   #include  <stdio.h>
35 < static unsigned b_nsbrked = 0;
35 > static unsigned b_nsbrked = 0;
36   static unsigned b_nalloced = 0;
37   static unsigned b_nfreed = 0;
38   static unsigned b_nscrounged = 0;
# Line 43 | Line 49 | static unsigned        m_nwasted = 0;
49   #endif
50   #define  BYTES_WORD     sizeof(ALIGN)
51  
52 + #ifndef  MAXINCR
53   #define  MAXINCR        (1<<16)                 /* largest sbrk(2) increment */
47
48 #ifdef  NOVMEM
49 #define  getpagesize()  1024
54   #endif
55                                          /* malloc free lists */
56   typedef union m_head {
# Line 67 | Line 71 | static M_HEAD  *free_list[NBUCKETS];
71  
72   static ALIGN    dummy_mem;
73  
74 + static char     *memlim[2];
75 +
76   #define DUMMYLOC        ((char *)&dummy_mem)
77  
78 + #define BADPTR(p)       ((p) < memlim[0] | (p) >= memlim[1])
79 +
80   #ifdef  MCOMP                   /* memory compaction routines */
81   static char     seedtab[1024];          /* seed for compaction table */
82  
# Line 165 | Line 173 | unsigned       *np;
173                          big->siz = 0;           /* remove from table */
174                          return(big->ptr);       /* return it */
175                  }
176 <                if (mtablen(big) < tablen+1) {
176 >                if (mtablen(big) <= tablen) {
177                          *np = 0;                /* cannot grow table */
178                          return(NULL);           /* report failure */
179                  }
# Line 175 | Line 183 | unsigned       *np;
183                  cptab.ptr = big->ptr;
184                  cptab.siz = big->siz;
185                  big->siz = 0;                   /* clear and copy */
178 #ifdef BSD
186                  bcopy((char *)tab, (char *)(mtab(&cptab)+1),
187                                  tablen*sizeof(struct mblk));
188                  bzero((char *)(mtab(&cptab)+tablen+1),
189                          (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
190          }                       /* next round */
191   }
192   #endif          /* MCOMP */
# Line 235 | Line 236 | register unsigned  n;
236                  pagesz = amnt = getpagesize();
237                  nrem = (int)sbrk(0);                    /* page align break */
238                  nrem = pagesz - (nrem&(pagesz-1));
239 <                bpos = sbrk(nrem);                      /* word aligned! */
239 >                bpos = sbrk(nrem);
240                  if ((int)bpos == -1)
241                          return(NULL);
242   #ifdef MSTATS
243                  b_nsbrked += nrem;
244   #endif
245 +                bpos += nrem & (BYTES_WORD-1);          /* align pointer */
246 +                nrem &= ~(BYTES_WORD-1);
247 +                memlim[0] = bpos;
248 +                memlim[1] = bpos + nrem;
249          }
250  
251          n = (n+(BYTES_WORD-1))&~(BYTES_WORD-1);         /* word align rqst. */
252  
253          if (n > nrem) {                                 /* need more core */
254 +        tryagain:
255                  if (n > amnt) {                         /* big chunk */
256                          thisamnt = (n+(pagesz-1))&~(pagesz-1);
257                          if (thisamnt <= MAXINCR)        /* increase amnt */
# Line 254 | Line 260 | register unsigned  n;
260                          thisamnt = amnt;
261                  p = sbrk(thisamnt);
262                  if ((int)p == -1) {                     /* uh-oh, ENOMEM */
263 <                        thisamnt = n;                   /* search free lists */
264 <                        p = mscrounge(&thisamnt);
265 <                        if (p == NULL)                  /* we're really out */
263 >                        errno = 0;                      /* call cavalry */
264 >                        if (thisamnt >= n+pagesz) {
265 >                                amnt = pagesz;          /* minimize request */
266 >                                goto tryagain;
267 >                        }
268 >                        thisamnt = n;
269 >                        p = mscrounge(&thisamnt);       /* search free lists */
270 >                        if (p == NULL) {                /* we're really out */
271 >                                errno = ENOMEM;
272                                  return(NULL);
273 +                        }
274                  }
275   #ifdef MSTATS
276                  else b_nsbrked += thisamnt;
# Line 268 | Line 281 | register unsigned  n;
281                          nrem = thisamnt;
282                  } else                                  /* otherwise tack on */
283                          nrem += thisamnt;
284 +                if (bpos < memlim[0])
285 +                        memlim[0] = bpos;
286 +                if (bpos + nrem > memlim[1])
287 +                        memlim[1] = bpos + nrem;
288          }
289          p = bpos;
290          bpos += n;                                      /* advance */
# Line 286 | Line 303 | register unsigned  n;
303          register int    bucket;
304          register unsigned       bsiz;
305  
306 +        if (n < 1<<FIRSTBUCKET)
307 +                return;
308   #ifdef MSTATS
309          b_nfreed += n;
310   #endif
# Line 295 | Line 314 | register unsigned  n;
314                  p += bsiz;
315                  n -= bsiz;
316          }
317 +        if (p < memlim[0])
318 +                memlim[0] = p;
319 +        if (p + n > memlim[1])
320 +                memlim[1] = p + n;
321                                          /* fill big buckets first */
322          for (bucket = NBUCKETS-1, bsiz = 1<<(NBUCKETS-1);
323                          bucket >= FIRSTBUCKET; bucket--, bsiz >>= 1)
# Line 311 | Line 334 | char *
334   malloc(n)                       /* allocate n bytes of memory */
335   unsigned        n;
336   {
314        extern int  errno;
337          register M_HEAD *mp;
338          register int    bucket;
339          register unsigned       bsiz;
# Line 353 | Line 375 | unsigned       n;
375          char    *p;
376          register unsigned       on;
377                                          /* get old size */
378 <        if (op != NULL && op != DUMMYLOC && ((M_HEAD *)op-1)->a.magic == MAGIC)
378 >        if (op != DUMMYLOC && !BADPTR(op) &&
379 >                        ((M_HEAD *)op-1)->a.magic == MAGIC)
380                  on = 1 << ((M_HEAD *)op-1)->a.bucket;
381          else
382                  on = 0;
383          if (n <= on && (n > on>>1 || on == 1<<FIRSTBUCKET))
384                  return(op);             /* same bucket */
385          if ((p = malloc(n)) == NULL)
386 <                return(NULL);
386 >                return(n<=on ? op : NULL);
387          if (on) {
365 #ifdef  BSD
388                  bcopy(op, p, n>on ? on : n);
367 #else
368                (void)memcpy(p, op, n>on ? on : n);
369 #endif
389                  free(op);
390          }
391          return(p);
# Line 379 | Line 398 | char   *p;
398          register M_HEAD *mp;
399          register int    bucket;
400  
401 <        if (p == NULL || p == DUMMYLOC)
401 >        if (p == DUMMYLOC)
402                  return(1);
403 +        if (BADPTR(p))
404 +                goto invalid;
405          mp = (M_HEAD *)p - 1;
406          if (mp->a.magic != MAGIC)               /* sanity check */
407 <                return(0);
407 >                goto invalid;
408          bucket = mp->a.bucket;
409 +        if (bucket < FIRSTBUCKET | bucket >= NBUCKETS)
410 +                goto invalid;
411          mp->next = free_list[bucket];
412          free_list[bucket] = mp;
413   #ifdef MSTATS
414          m_nfreed += (1 << bucket) + sizeof(M_HEAD);
415   #endif
416          return(1);
417 + invalid:
418 +        errno = EINVAL;
419 +        return(0);
420   }
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
421  
422  
423   #ifdef MSTATS

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines