[BACK]Return to jemalloc.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / stdlib

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/lib/libc/stdlib/jemalloc.c between version 1.17 and 1.24.6.2

version 1.17, 2008/03/08 13:17:13 version 1.24.6.2, 2012/04/23 23:40:40
Line 319  __strerror_r(int e, char *s, size_t l)
Line 319  __strerror_r(int e, char *s, size_t l)
 #define SMALL_MAX_DEFAULT       (1 << SMALL_MAX_2POW_DEFAULT)  #define SMALL_MAX_DEFAULT       (1 << SMALL_MAX_2POW_DEFAULT)
   
 /*  /*
  * Maximum desired run header overhead.  Runs are sized as small as possible   * RUN_MAX_OVRHD indicates maximum desired run header overhead.  Runs are sized
  * such that this setting is still honored, without violating other constraints.   * as small as possible such that this setting is still honored, without
  * The goal is to make runs as small as possible without exceeding a per run   * violating other constraints.  The goal is to make runs as small as possible
  * external fragmentation threshold.   * without exceeding a per run external fragmentation threshold.
  *   *
  * Note that it is possible to set this low enough that it cannot be honored   * We use binary fixed point math for overhead computations, where the binary
  * for some/all object sizes, since there is one bit of header overhead per   * point is implicitly RUN_BFP bits to the left.
  * object (plus a constant).  In such cases, this constraint is relaxed.  
  *   *
  * RUN_MAX_OVRHD_RELAX specifies the maximum number of bits per region of   * Note that it is possible to set RUN_MAX_OVRHD low enough that it cannot be
  * overhead for which RUN_MAX_OVRHD is relaxed.   * honored for some/all object sizes, since there is one bit of header overhead
    * per object (plus a constant).  This constraint is relaxed (ignored) for runs
    * that are so small that the per-region overhead is greater than:
    *
    *   (RUN_MAX_OVRHD / (reg_size << (3+RUN_BFP))
  */   */
 #define RUN_MAX_OVRHD           0.015  #define RUN_BFP                 12
 #define RUN_MAX_OVRHD_RELAX     1.5  /*                              \/   Implicit binary fixed point. */
   #define RUN_MAX_OVRHD           0x0000003dU
   #define RUN_MAX_OVRHD_RELAX     0x00001800U
   
 /* Put a cap on small object run size.  This overrides RUN_MAX_OVRHD. */  /* Put a cap on small object run size.  This overrides RUN_MAX_OVRHD. */
 #define RUN_MAX_SMALL_2POW      15  #define RUN_MAX_SMALL_2POW      15
Line 1029  base_pages_alloc(size_t minsize)
Line 1034  base_pages_alloc(size_t minsize)
                          */                           */
                         incr = (intptr_t)chunksize                          incr = (intptr_t)chunksize
                             - (intptr_t)CHUNK_ADDR2OFFSET(brk_cur);                              - (intptr_t)CHUNK_ADDR2OFFSET(brk_cur);
                         if (incr < minsize)                          assert(incr >= 0);
                           if ((size_t)incr < minsize)
                                 incr += csize;                                  incr += csize;
   
                         brk_prev = sbrk(incr);                          brk_prev = sbrk(incr);
Line 1364  chunk_alloc(size_t size)
Line 1370  chunk_alloc(size_t size)
                          */                           */
                         incr = (intptr_t)size                          incr = (intptr_t)size
                             - (intptr_t)CHUNK_ADDR2OFFSET(brk_cur);                              - (intptr_t)CHUNK_ADDR2OFFSET(brk_cur);
                         if (incr == size) {                          if (incr == (intptr_t)size) {
                                 ret = brk_cur;                                  ret = brk_cur;
                         } else {                          } else {
                                 ret = (void *)((intptr_t)brk_cur + incr);                                  ret = (void *)((intptr_t)brk_cur + incr);
Line 1529  chunk_dealloc(void *chunk, size_t size)
Line 1535  chunk_dealloc(void *chunk, size_t size)
  * amongst threads.  To accomplish this, next_arena advances only in   * amongst threads.  To accomplish this, next_arena advances only in
  * ncpu steps.   * ncpu steps.
  */   */
 static inline arena_t *  static __noinline arena_t *
 choose_arena(void)  choose_arena_hard(void)
 {  {
         unsigned i, curcpu;          unsigned i, curcpu;
         arena_t **map;          arena_t **map;
   
         map = get_arenas_map();  
         curcpu = thr_curcpu();  
         if (__predict_true(map != NULL && map[curcpu] != NULL))  
                 return map[curcpu];  
   
         /* Initialize the current block of arenas and advance to next. */          /* Initialize the current block of arenas and advance to next. */
         malloc_mutex_lock(&arenas_mtx);          malloc_mutex_lock(&arenas_mtx);
         assert(next_arena % ncpus == 0);          assert(next_arena % ncpus == 0);
Line 1563  choose_arena(void)
Line 1564  choose_arena(void)
         return arenas[0];          return arenas[0];
 }  }
   
   static inline arena_t *
   choose_arena(void)
   {
           unsigned curcpu;
           arena_t **map;
   
           map = get_arenas_map();
           curcpu = thr_curcpu();
           if (__predict_true(map != NULL && map[curcpu] != NULL))
                   return map[curcpu];
   
           return choose_arena_hard();
   }
   
 #ifndef lint  #ifndef lint
 static inline int  static inline int
 arena_chunk_comp(arena_chunk_t *a, arena_chunk_t *b)  arena_chunk_comp(arena_chunk_t *a, arena_chunk_t *b)
Line 2133  arena_bin_run_size_calc(arena_bin_t *bin
Line 2148  arena_bin_run_size_calc(arena_bin_t *bin
         size_t try_run_size, good_run_size;          size_t try_run_size, good_run_size;
         unsigned good_nregs, good_mask_nelms, good_reg0_offset;          unsigned good_nregs, good_mask_nelms, good_reg0_offset;
         unsigned try_nregs, try_mask_nelms, try_reg0_offset;          unsigned try_nregs, try_mask_nelms, try_reg0_offset;
         float max_ovrhd = RUN_MAX_OVRHD;  
   
         assert(min_run_size >= pagesize);          assert(min_run_size >= pagesize);
         assert(min_run_size <= arena_maxclass);          assert(min_run_size <= arena_maxclass);
Line 2151  arena_bin_run_size_calc(arena_bin_t *bin
Line 2165  arena_bin_run_size_calc(arena_bin_t *bin
          */           */
         try_run_size = min_run_size;          try_run_size = min_run_size;
         try_nregs = (unsigned)(((try_run_size - sizeof(arena_run_t)) /          try_nregs = (unsigned)(((try_run_size - sizeof(arena_run_t)) /
             bin->reg_size) + 1); /* Counter-act the first line of the loop. */              bin->reg_size) + 1); /* Counter-act try_nregs-- in loop. */
         do {          do {
                 try_nregs--;                  try_nregs--;
                 try_mask_nelms = (try_nregs >> (SIZEOF_INT_2POW + 3)) +                  try_mask_nelms = (try_nregs >> (SIZEOF_INT_2POW + 3)) +
Line 2185  arena_bin_run_size_calc(arena_bin_t *bin
Line 2199  arena_bin_run_size_calc(arena_bin_t *bin
                 } while (sizeof(arena_run_t) + (sizeof(unsigned) *                  } while (sizeof(arena_run_t) + (sizeof(unsigned) *
                     (try_mask_nelms - 1)) > try_reg0_offset);                      (try_mask_nelms - 1)) > try_reg0_offset);
         } while (try_run_size <= arena_maxclass && try_run_size <= RUN_MAX_SMALL          } while (try_run_size <= arena_maxclass && try_run_size <= RUN_MAX_SMALL
             && max_ovrhd > RUN_MAX_OVRHD_RELAX / ((float)(bin->reg_size << 3))              && RUN_MAX_OVRHD * (bin->reg_size << 3) > RUN_MAX_OVRHD_RELAX
             && ((float)(try_reg0_offset)) / ((float)(try_run_size)) >              && (try_reg0_offset << RUN_BFP) > RUN_MAX_OVRHD * try_run_size);
             max_ovrhd);  
   
         assert(sizeof(arena_run_t) + (sizeof(unsigned) * (good_mask_nelms - 1))          assert(sizeof(arena_run_t) + (sizeof(unsigned) * (good_mask_nelms - 1))
             <= good_reg0_offset);              <= good_reg0_offset);
Line 2846  huge_ralloc(void *ptr, size_t size, size
Line 2859  huge_ralloc(void *ptr, size_t size, size
                         /* size_t wrap-around */                          /* size_t wrap-around */
                         return (NULL);                          return (NULL);
                 }                  }
   
                   /*
                    * Remove the old region from the tree now.  If mremap()
                    * returns the region to the system, other thread may
                    * map it for same huge allocation and insert it to the
                    * tree before we acquire the mutex lock again.
                    */
                   malloc_mutex_lock(&chunks_mtx);
                   key.chunk = __DECONST(void *, ptr);
                   /* LINTED */
                   node = RB_FIND(chunk_tree_s, &huge, &key);
                   assert(node != NULL);
                   assert(node->chunk == ptr);
                   assert(node->size == oldcsize);
                   RB_REMOVE(chunk_tree_s, &huge, node);
                   malloc_mutex_unlock(&chunks_mtx);
   
                 newptr = mremap(ptr, oldcsize, NULL, newcsize,                  newptr = mremap(ptr, oldcsize, NULL, newcsize,
                     MAP_ALIGNED(chunksize_2pow));                      MAP_ALIGNED(chunksize_2pow));
                 if (newptr != MAP_FAILED) {                  if (newptr == MAP_FAILED) {
                           /* We still own the old region. */
                           malloc_mutex_lock(&chunks_mtx);
                           RB_INSERT(chunk_tree_s, &huge, node);
                           malloc_mutex_unlock(&chunks_mtx);
                   } else {
                         assert(CHUNK_ADDR2BASE(newptr) == newptr);                          assert(CHUNK_ADDR2BASE(newptr) == newptr);
   
                         /* update tree */                          /* Insert new or resized old region. */
                         malloc_mutex_lock(&chunks_mtx);                          malloc_mutex_lock(&chunks_mtx);
                         key.chunk = __DECONST(void *, ptr);  
                         /* LINTED */  
                         node = RB_FIND(chunk_tree_s, &huge, &key);  
                         assert(node != NULL);  
                         assert(node->chunk == ptr);  
                         assert(node->size == oldcsize);  
                         node->size = newcsize;                          node->size = newcsize;
                         if (ptr != newptr) {                          node->chunk = newptr;
                                 RB_REMOVE(chunk_tree_s, &huge, node);                          RB_INSERT(chunk_tree_s, &huge, node);
                                 node->chunk = newptr;  
                                 RB_INSERT(chunk_tree_s, &huge, node);  
                         }  
 #ifdef MALLOC_STATS  #ifdef MALLOC_STATS
                         huge_nralloc++;                          huge_nralloc++;
                         huge_allocated += newcsize - oldcsize;                          huge_allocated += newcsize - oldcsize;
Line 3299  malloc_init_hard(void)
Line 3325  malloc_init_hard(void)
         ssize_t linklen;          ssize_t linklen;
         char buf[PATH_MAX + 1];          char buf[PATH_MAX + 1];
         const char *opts = "";          const char *opts = "";
           int serrno;
   
         malloc_mutex_lock(&init_lock);          malloc_mutex_lock(&init_lock);
         if (malloc_initialized) {          if (malloc_initialized) {
Line 3310  malloc_init_hard(void)
Line 3337  malloc_init_hard(void)
                 return (false);                  return (false);
         }          }
   
           serrno = errno;
         /* Get number of CPUs. */          /* Get number of CPUs. */
         {          {
                 int mib[2];                  int mib[2];
Line 3360  malloc_init_hard(void)
Line 3388  malloc_init_hard(void)
                         }                          }
                         break;                          break;
                 case 1:                  case 1:
                         if (issetugid() == 0 && (opts =                          if ((opts = getenv("MALLOC_OPTIONS")) != NULL &&
                             getenv("MALLOC_OPTIONS")) != NULL) {                              issetugid() == 0) {
                                 /*                                  /*
                                  * Do nothing; opts is already initialized to                                   * Do nothing; opts is already initialized to
                                  * the value of the MALLOC_OPTIONS environment                                   * the value of the MALLOC_OPTIONS environment
Line 3421  malloc_init_hard(void)
Line 3449  malloc_init_hard(void)
                                         opt_chunk_2pow--;                                          opt_chunk_2pow--;
                                 break;                                  break;
                         case 'K':                          case 'K':
                                 /*                                  if (opt_chunk_2pow + 1 <
                                  * There must be fewer pages in a chunk than                                      (int)(sizeof(size_t) << 3))
                                  * can be recorded by the pos field of  
                                  * arena_chunk_map_t, in order to make POS_FREE  
                                  * special.  
                                  */  
                                 if (opt_chunk_2pow - pagesize_2pow  
                                     < (sizeof(uint32_t) << 3) - 1)  
                                         opt_chunk_2pow++;                                          opt_chunk_2pow++;
                                 break;                                  break;
                         case 'n':                          case 'n':
Line 3495  malloc_init_hard(void)
Line 3517  malloc_init_hard(void)
                         }                          }
                 }                  }
         }          }
           errno = serrno;
   
         /* Take care to call atexit() only once. */          /* Take care to call atexit() only once. */
         if (opt_print_stats) {          if (opt_print_stats) {

Legend:
Removed from v.1.17  
changed lines
  Added in v.1.24.6.2

CVSweb <webmaster@jp.NetBSD.org>