[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.34 and 1.34.2.3

version 1.34, 2014/08/10 05:57:31 version 1.34.2.3, 2016/05/10 09:10:11
Line 382  static malloc_mutex_t init_lock = {_SPIN
Line 382  static malloc_mutex_t init_lock = {_SPIN
 /* Set to true once the allocator has been initialized. */  /* Set to true once the allocator has been initialized. */
 static bool malloc_initialized = false;  static bool malloc_initialized = false;
   
   #ifdef _REENTRANT
 /* Used to avoid initialization races. */  /* Used to avoid initialization races. */
 static mutex_t init_lock = MUTEX_INITIALIZER;  static mutex_t init_lock = MUTEX_INITIALIZER;
 #endif  #endif
   #endif
   
 /******************************************************************************/  /******************************************************************************/
 /*  /*
Line 694  static size_t  arena_maxclass; /* Max si
Line 696  static size_t  arena_maxclass; /* Max si
  * Chunks.   * Chunks.
  */   */
   
   #ifdef _REENTRANT
 /* Protects chunk-related data structures. */  /* Protects chunk-related data structures. */
 static malloc_mutex_t   chunks_mtx;  static malloc_mutex_t   chunks_mtx;
   #endif
   
 /* Tree of chunks that are stand-alone huge allocations. */  /* Tree of chunks that are stand-alone huge allocations. */
 static chunk_tree_t     huge;  static chunk_tree_t     huge;
Line 746  static void  *base_pages;
Line 750  static void  *base_pages;
 static void             *base_next_addr;  static void             *base_next_addr;
 static void             *base_past_addr; /* Addr immediately past base_pages. */  static void             *base_past_addr; /* Addr immediately past base_pages. */
 static chunk_node_t     *base_chunk_nodes; /* LIFO cache of chunk nodes. */  static chunk_node_t     *base_chunk_nodes; /* LIFO cache of chunk nodes. */
   #ifdef _REENTRANT
 static malloc_mutex_t   base_mtx;  static malloc_mutex_t   base_mtx;
   #endif
 #ifdef MALLOC_STATS  #ifdef MALLOC_STATS
 static size_t           base_mapped;  static size_t           base_mapped;
 #endif  #endif
Line 763  static size_t  base_mapped;
Line 769  static size_t  base_mapped;
 static arena_t          **arenas;  static arena_t          **arenas;
 static unsigned         narenas;  static unsigned         narenas;
 static unsigned         next_arena;  static unsigned         next_arena;
   #ifdef _REENTRANT
 static malloc_mutex_t   arenas_mtx; /* Protects arenas initialization. */  static malloc_mutex_t   arenas_mtx; /* Protects arenas initialization. */
   #endif
   
 #ifndef NO_TLS  
 /*  /*
  * Map of pthread_self() --> arenas[???], used for selecting an arena to use   * Map of pthread_self() --> arenas[???], used for selecting an arena to use
  * for allocations.   * for allocations.
  */   */
 static __thread arena_t *arenas_map;  #ifndef NO_TLS
 #define get_arenas_map()        (arenas_map)  static __thread arena_t **arenas_map;
 #define set_arenas_map(x)       (arenas_map = x)  
 #else  #else
 static thread_key_t arenas_map_key;  static arena_t  **arenas_map;
 #define get_arenas_map()        thr_getspecific(arenas_map_key)  #endif
 #define set_arenas_map(x)       thr_setspecific(arenas_map_key, x)  
   #if !defined(NO_TLS) || !defined(_REENTRANT)
   # define        get_arenas_map()        (arenas_map)
   # define        set_arenas_map(x)       (arenas_map = x)
   #else
   
   static thread_key_t arenas_map_key = -1;
   
   static inline arena_t **
   get_arenas_map(void)
   {
           if (!__isthreaded)
                   return arenas_map;
   
           if (arenas_map_key == -1) {
                   (void)thr_keycreate(&arenas_map_key, NULL);
                   if (arenas_map != NULL) {
                           thr_setspecific(arenas_map_key, arenas_map);
                           arenas_map = NULL;
                   }
           }
   
           return thr_getspecific(arenas_map_key);
   }
   
   static __inline void
   set_arenas_map(arena_t **a)
   {
           if (!__isthreaded) {
                   arenas_map = a;
                   return;
           }
   
           if (arenas_map_key == -1) {
                   (void)thr_keycreate(&arenas_map_key, NULL);
                   if (arenas_map != NULL) {
                           _DIAGASSERT(arenas_map == a);
                           arenas_map = NULL;
                   }
           }
   
           thr_setspecific(arenas_map_key, a);
   }
 #endif  #endif
   
 #ifdef MALLOC_STATS  #ifdef MALLOC_STATS
Line 1603  arena_chunk_comp(arena_chunk_t *a, arena
Line 1651  arena_chunk_comp(arena_chunk_t *a, arena
         assert(a != NULL);          assert(a != NULL);
         assert(b != NULL);          assert(b != NULL);
   
           if (a->max_frun_npages < b->max_frun_npages)
                   return -1;
           if (a->max_frun_npages > b->max_frun_npages)
                   return 1;
   
         if ((uintptr_t)a < (uintptr_t)b)          if ((uintptr_t)a < (uintptr_t)b)
                 return (-1);                  return (-1);
         else if (a == b)          else if (a == b)
Line 1854  arena_chunk_alloc(arena_t *arena)
Line 1907  arena_chunk_alloc(arena_t *arena)
   
                 chunk->arena = arena;                  chunk->arena = arena;
   
                 /* LINTED */  
                 RB_INSERT(arena_chunk_tree_s, &arena->chunks, chunk);  
   
                 /*                  /*
                  * Claim that no pages are in use, since the header is merely                   * Claim that no pages are in use, since the header is merely
                  * overhead.                   * overhead.
Line 1876  arena_chunk_alloc(arena_t *arena)
Line 1926  arena_chunk_alloc(arena_t *arena)
                 chunk->map[chunk_npages - 1].npages = chunk_npages -                  chunk->map[chunk_npages - 1].npages = chunk_npages -
                     arena_chunk_header_npages;                      arena_chunk_header_npages;
                 chunk->map[chunk_npages - 1].pos = POS_FREE;                  chunk->map[chunk_npages - 1].pos = POS_FREE;
   
                   RB_INSERT(arena_chunk_tree_s, &arena->chunks, chunk);
         }          }
   
         return (chunk);          return (chunk);
Line 1912  arena_chunk_dealloc(arena_t *arena, aren
Line 1964  arena_chunk_dealloc(arena_t *arena, aren
 static arena_run_t *  static arena_run_t *
 arena_run_alloc(arena_t *arena, size_t size)  arena_run_alloc(arena_t *arena, size_t size)
 {  {
         arena_chunk_t *chunk;          arena_chunk_t *chunk, *chunk_tmp;
         arena_run_t *run;          arena_run_t *run;
         unsigned need_npages, limit_pages, compl_need_npages;          unsigned need_npages;
   
         assert(size <= (chunksize - (arena_chunk_header_npages <<          assert(size <= (chunksize - (arena_chunk_header_npages <<
             pagesize_2pow)));              pagesize_2pow)));
         assert((size & pagesize_mask) == 0);          assert((size & pagesize_mask) == 0);
   
         /*          /*
          * Search through arena's chunks in address order for a free run that is           * Search through the arena chunk tree for a large enough free run.
          * large enough.  Look for the first fit.           * Tree order ensures that any exact fit is picked immediately or
            * otherwise the lowest address of the next size.
          */           */
         need_npages = (unsigned)(size >> pagesize_2pow);          need_npages = (unsigned)(size >> pagesize_2pow);
         limit_pages = chunk_npages - arena_chunk_header_npages;  
         compl_need_npages = limit_pages - need_npages;  
         /* LINTED */          /* LINTED */
         RB_FOREACH(chunk, arena_chunk_tree_s, &arena->chunks) {          for (;;) {
                   chunk_tmp = RB_ROOT(&arena->chunks);
                   chunk = NULL;
                   while (chunk_tmp) {
                           if (chunk_tmp->max_frun_npages == need_npages) {
                                   chunk = chunk_tmp;
                                   break;
                           }
                           if (chunk_tmp->max_frun_npages < need_npages) {
                                   chunk_tmp = RB_RIGHT(chunk_tmp, link);
                                   continue;
                           }
                           chunk = chunk_tmp;
                           chunk_tmp = RB_LEFT(chunk, link);
                   }
                   if (chunk == NULL)
                           break;
                 /*                  /*
                  * Avoid searching this chunk if there are not enough                   * At this point, the chunk must have a cached run size large
                  * contiguous free pages for there to possibly be a large                   * enough to fit the allocation.
                  * enough free run.  
                  */                   */
                 if (chunk->pages_used <= compl_need_npages &&                  assert(need_npages <= chunk->max_frun_npages);
                     need_npages <= chunk->max_frun_npages) {                  {
                         arena_chunk_map_t *mapelm;                          arena_chunk_map_t *mapelm;
                         unsigned i;                          unsigned i;
                         unsigned max_frun_npages = 0;                          unsigned max_frun_npages = 0;
Line 1973  arena_run_alloc(arena_t *arena, size_t s
Line 2039  arena_run_alloc(arena_t *arena, size_t s
                          * chunk->min_frun_ind was already reset above (if                           * chunk->min_frun_ind was already reset above (if
                          * necessary).                           * necessary).
                          */                           */
                           RB_REMOVE(arena_chunk_tree_s, &arena->chunks, chunk);
                         chunk->max_frun_npages = max_frun_npages;                          chunk->max_frun_npages = max_frun_npages;
                           RB_INSERT(arena_chunk_tree_s, &arena->chunks, chunk);
                 }                  }
         }          }
   
Line 2056  arena_run_dalloc(arena_t *arena, arena_r
Line 2124  arena_run_dalloc(arena_t *arena, arena_r
                 assert(chunk->map[run_ind + run_pages - 1].pos == POS_FREE);                  assert(chunk->map[run_ind + run_pages - 1].pos == POS_FREE);
         }          }
   
         if (chunk->map[run_ind].npages > chunk->max_frun_npages)          if (chunk->map[run_ind].npages > chunk->max_frun_npages) {
                   RB_REMOVE(arena_chunk_tree_s, &arena->chunks, chunk);
                 chunk->max_frun_npages = chunk->map[run_ind].npages;                  chunk->max_frun_npages = chunk->map[run_ind].npages;
                   RB_INSERT(arena_chunk_tree_s, &arena->chunks, chunk);
           }
         if (run_ind < chunk->min_frun_ind)          if (run_ind < chunk->min_frun_ind)
                 chunk->min_frun_ind = run_ind;                  chunk->min_frun_ind = run_ind;
   
Line 3634  malloc_init_hard(void)
Line 3705  malloc_init_hard(void)
                 opt_narenas_lshift += 2;                  opt_narenas_lshift += 2;
         }          }
   
 #ifdef NO_TLS  
         /* Initialize arena key. */  
         (void)thr_keycreate(&arenas_map_key, NULL);  
 #endif  
   
         /* Determine how many arenas to use. */          /* Determine how many arenas to use. */
         narenas = ncpus;          narenas = ncpus;
         if (opt_narenas_lshift > 0) {          if (opt_narenas_lshift > 0) {

Legend:
Removed from v.1.34  
changed lines
  Added in v.1.34.2.3

CVSweb <webmaster@jp.NetBSD.org>