diff options
| author | Peter Wemm <peter@FreeBSD.org> | 1995-12-11 14:28:12 +0000 | 
|---|---|---|
| committer | Peter Wemm <peter@FreeBSD.org> | 1995-12-11 14:28:12 +0000 | 
| commit | 04936d2e080c2f7697cc1000bb1022b0140d3e80 (patch) | |
| tree | a1b1975ac1c2ec298a74a991d1100a647283fed1 /lib/libc/stdlib/malloc.c | |
| parent | 34321f66e107084f4ea08d8b65be5e521230a57d (diff) | |
Notes
Diffstat (limited to 'lib/libc/stdlib/malloc.c')
| -rw-r--r-- | lib/libc/stdlib/malloc.c | 76 | 
1 files changed, 47 insertions, 29 deletions
diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c index 0e39fa947100..cc240455b8bc 100644 --- a/lib/libc/stdlib/malloc.c +++ b/lib/libc/stdlib/malloc.c @@ -6,7 +6,7 @@   * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp   * ----------------------------------------------------------------------------   * - * $Id: malloc.c,v 1.5 1995/10/08 18:44:20 phk Exp $ + * $Id: malloc.c,v 1.6 1995/10/22 14:47:00 phk Exp $   *   */ @@ -17,6 +17,17 @@  #undef EXTRA_SANITY  /* + * Defining MALLOC_STATS will enable you to call malloc_dump() and set + * the [dD] options in the MALLOC_OPTIONS environment variable. + * It has no run-time performance hit. + */ +#define MALLOC_STATS + +#if defined(EXTRA_SANITY) && !defined(MALLOC_STATS) +# define MALLOC_STATS	/* required for EXTRA_SANITY */ +#endif + +/*   * What to use for Junk   */  #define SOME_JUNK	0xd0		/* as in "Duh" :-) */ @@ -213,12 +224,12 @@ static int malloc_abort;   */  static int suicide; -#ifdef EXTRA_SANITY +#ifdef MALLOC_STATS  /*   * dump statistics   */  static int malloc_stats; -#endif /* EXTRA_SANITY */ +#endif /* MALLOC_STATS */  /*   * always realloc ? @@ -250,7 +261,7 @@ static struct pgfree *px;   */  static int extend_pgdir(u_long index); -#ifdef EXTRA_SANITY +#ifdef MALLOC_STATS  void  malloc_dump(FILE *fd)  { @@ -306,7 +317,7 @@ malloc_dump(FILE *fd)  	(last_index + malloc_pageshift) << malloc_pageshift);      fprintf(fd,"Break\t%ld\n",(u_long)sbrk(0) >> malloc_pageshift);  } -#endif /* EXTRA_SANITY */ +#endif /* MALLOC_STATS */  static void  wrterror(char *p) @@ -315,10 +326,10 @@ wrterror(char *p)      suicide = 1;      write(2,q,strlen(q));      write(2,p,strlen(p)); -#ifdef EXTRA_SANITY +#ifdef MALLOC_STATS      if (malloc_stats)  	malloc_dump(stderr); -#endif /* EXTRA_SANITY */ +#endif /* MALLOC_STATS */      abort();  } @@ -428,20 +439,38 @@ static int  extend_pgdir(u_long index)  {      struct  pginfo **new,**old; -    int i; +    int i, oldlen;      /* Make it this many pages */      i = index * sizeof *page_dir;      i /= malloc_pagesize;      i += 2; +    /* remember the old mapping size */ +    oldlen = malloc_ninfo * sizeof *page_dir; + +    /* +     * NOTE: we allocate new pages and copy the directory rather than tempt +     * fate by trying to "grow" the region.. There is nothing to prevent +     * us from accidently re-mapping space that's been allocated by our caller +     * via dlopen() or other mmap(). +     * +     * The copy problem is not too bad, as there is 4K of page index per +     * 4MB of malloc arena. +     * +     * We can totally avoid the copy if we open a file descriptor to associate +     * the anon mappings with.  Then, when we remap the pages at the new +     * address, the old pages will be "magically" remapped..  But this means +     * keeping open a "secret" file descriptor..... +     */ +      /* Get new pages */ -    new = (struct pginfo**) map_pages(i,0); -    if (!new) +    new = (struct pginfo**) mmap(0, i * malloc_pagesize, PROT_READ|PROT_WRITE, +				 MAP_ANON|MAP_PRIVATE, -1, 0); +    if (new == (struct pginfo **)-1)  	return 0;      /* Copy the old stuff */ -    memset(new, 0, i * malloc_pagesize);      memcpy(new, page_dir,  	    malloc_ninfo * sizeof *page_dir); @@ -452,15 +481,8 @@ extend_pgdir(u_long index)      old = page_dir;      page_dir = new; -    /* Mark the pages */ -    index = ptr2index(new); -    page_dir[index] = MALLOC_FIRST; -    while (--i) { -	page_dir[++index] = MALLOC_FOLLOW; -    } -      /* Now free the old stuff */ -    free(old); +    munmap((caddr_t)old, oldlen);      return 1;  } @@ -480,10 +502,10 @@ malloc_init ()  	switch (*p) {  	    case 'a': malloc_abort   = 0; break;  	    case 'A': malloc_abort   = 1; break; -#ifdef EXTRA_SANITY +#ifdef MALLOC_STATS  	    case 'd': malloc_stats   = 0; break;  	    case 'D': malloc_stats   = 1; break; -#endif /* EXTRA_SANITY */ +#endif /* MALLOC_STATS */  	    case 'r': malloc_realloc = 0; break;  	    case 'R': malloc_realloc = 1; break;  	    case 'j': malloc_junk    = 0; break; @@ -557,24 +579,20 @@ malloc_init ()  #endif /* malloc_minsize */      /* Allocate one page for the page directory */ -    page_dir = (struct pginfo **) map_pages(1,0); -    if (!page_dir) +    page_dir = (struct pginfo **) mmap(0, malloc_pagesize, PROT_READ|PROT_WRITE, +				       MAP_ANON|MAP_PRIVATE, -1, 0); +    if (page_dir == (struct pginfo **) -1)  	wrterror("(Init) my first mmap failed.  (check limits ?)\n");      /*       * We need a maximum of malloc_pageshift buckets, steal these from the       * front of the page_directory;       */ -    malloc_origo = (u_long) page_dir >> malloc_pageshift; +    malloc_origo = ((u_long)pageround((u_long)sbrk(0))) >> malloc_pageshift;      malloc_origo -= malloc_pageshift; -    memset(page_dir,0,malloc_pagesize); -      malloc_ninfo = malloc_pagesize / sizeof *page_dir; -    /* Plug the page directory into itself */ -    page_dir[ptr2index(page_dir)] = MALLOC_FIRST; -      /* Been here, done that */      initialized++;  }  | 
