diff options
Diffstat (limited to 'libglusterfs/src/mem-pool.c')
| -rw-r--r-- | libglusterfs/src/mem-pool.c | 131 | 
1 files changed, 74 insertions, 57 deletions
diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c index 16e413e22f2..ec8e40d2bc0 100644 --- a/libglusterfs/src/mem-pool.c +++ b/libglusterfs/src/mem-pool.c @@ -412,36 +412,33 @@ static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;  static unsigned int init_count = 0;  static pthread_t sweeper_tid; -void +gf_boolean_t  collect_garbage(sweep_state_t *state, per_thread_pool_list_t *pool_list)  {      unsigned int i;      per_thread_pool_t *pt_pool; - -    if (pool_list->poison) { -        list_del(&pool_list->thr_list); -        list_add(&pool_list->thr_list, &state->death_row); -        return; -    } - -    if (state->n_cold_lists >= N_COLD_LISTS) { -        return; -    } +    gf_boolean_t poisoned;      (void)pthread_spin_lock(&pool_list->lock); -    for (i = 0; i < NPOOLS; ++i) { -        pt_pool = &pool_list->pools[i]; -        if (pt_pool->cold_list) { -            state->cold_lists[state->n_cold_lists++] = pt_pool->cold_list; -        } -        pt_pool->cold_list = pt_pool->hot_list; -        pt_pool->hot_list = NULL; -        if (state->n_cold_lists >= N_COLD_LISTS) { -            /* We'll just catch up on a future pass. */ -            break; + +    poisoned = pool_list->poison != 0; +    if (!poisoned) { +        for (i = 0; i < NPOOLS; ++i) { +            pt_pool = &pool_list->pools[i]; +            if (pt_pool->cold_list) { +                if (state->n_cold_lists >= N_COLD_LISTS) { +                    break; +                } +                state->cold_lists[state->n_cold_lists++] = pt_pool->cold_list; +            } +            pt_pool->cold_list = pt_pool->hot_list; +            pt_pool->hot_list = NULL;          }      } +      (void)pthread_spin_unlock(&pool_list->lock); + +    return poisoned;  }  void @@ -468,6 +465,7 @@ pool_sweeper(void *arg)      struct timeval begin_time;      struct timeval end_time;      struct timeval elapsed; +    gf_boolean_t poisoned;      /*       * This is all a bit inelegant, but the point is to avoid doing @@ -487,7 +485,13 @@ pool_sweeper(void *arg)          (void)pthread_mutex_lock(&pool_lock);          list_for_each_entry_safe(pool_list, next_pl, &pool_threads, thr_list)          { -            collect_garbage(&state, pool_list); +            (void)pthread_mutex_unlock(&pool_lock); +            poisoned = collect_garbage(&state, pool_list); +            (void)pthread_mutex_lock(&pool_lock); + +            if (poisoned) { +                list_move(&pool_list->thr_list, &state.death_row); +            }          }          (void)pthread_mutex_unlock(&pool_lock);          (void)gettimeofday(&end_time, NULL); @@ -771,7 +775,7 @@ mem_get_pool_list(void)      (void)pthread_mutex_unlock(&pool_free_lock);      if (!pool_list) { -        pool_list = CALLOC(pool_list_size, 1); +        pool_list = MALLOC(pool_list_size);          if (!pool_list) {              return NULL;          } @@ -785,8 +789,9 @@ mem_get_pool_list(void)          }      } -    (void)pthread_mutex_lock(&pool_lock);      pool_list->poison = 0; + +    (void)pthread_mutex_lock(&pool_lock);      list_add(&pool_list->thr_list, &pool_threads);      (void)pthread_mutex_unlock(&pool_lock); @@ -795,26 +800,47 @@ mem_get_pool_list(void)  }  pooled_obj_hdr_t * -mem_get_from_pool(per_thread_pool_t *pt_pool) +mem_get_from_pool(struct mem_pool *mem_pool)  { +    per_thread_pool_list_t *pool_list; +    per_thread_pool_t *pt_pool;      pooled_obj_hdr_t *retval; +    pool_list = mem_get_pool_list(); +    if (!pool_list || pool_list->poison) { +        return NULL; +    } + +    pt_pool = &pool_list->pools[mem_pool->pool->power_of_two - POOL_SMALLEST]; + +    (void)pthread_spin_lock(&pool_list->lock); +      retval = pt_pool->hot_list;      if (retval) { -        GF_ATOMIC_INC(pt_pool->parent->allocs_hot);          pt_pool->hot_list = retval->next; -        return retval; +        (void)pthread_spin_unlock(&pool_list->lock); +        GF_ATOMIC_INC(pt_pool->parent->allocs_hot); +    } else { +        retval = pt_pool->cold_list; +        if (retval) { +            pt_pool->cold_list = retval->next; +            (void)pthread_spin_unlock(&pool_list->lock); +            GF_ATOMIC_INC(pt_pool->parent->allocs_cold); +        } else { +            (void)pthread_spin_unlock(&pool_list->lock); +            GF_ATOMIC_INC(pt_pool->parent->allocs_stdc); +            retval = malloc(1 << pt_pool->parent->power_of_two); +        }      } -    retval = pt_pool->cold_list; -    if (retval) { -        GF_ATOMIC_INC(pt_pool->parent->allocs_cold); -        pt_pool->cold_list = retval->next; -        return retval; +    if (retval != NULL) { +        retval->magic = GF_MEM_HEADER_MAGIC; +        retval->pool = mem_pool; +        retval->pool_list = pool_list; +        retval->power_of_two = mem_pool->pool->power_of_two;      } -    GF_ATOMIC_INC(pt_pool->parent->allocs_stdc); -    return malloc(1 << pt_pool->parent->power_of_two); +    return retval;  }  void * @@ -823,8 +849,6 @@ mem_get(struct mem_pool *mem_pool)  #if defined(GF_DISABLE_MEMPOOL)      return GF_MALLOC(mem_pool->sizeof_type, gf_common_mt_mem_pool);  #else -    per_thread_pool_list_t *pool_list; -    per_thread_pool_t *pt_pool;      pooled_obj_hdr_t *retval;      if (!mem_pool) { @@ -833,26 +857,11 @@ mem_get(struct mem_pool *mem_pool)          return NULL;      } -    pool_list = mem_get_pool_list(); -    if (!pool_list || pool_list->poison) { -        return NULL; -    } - -    (void)pthread_spin_lock(&pool_list->lock); -    pt_pool = &pool_list->pools[mem_pool->pool->power_of_two - POOL_SMALLEST]; -    retval = mem_get_from_pool(pt_pool); - +    retval = mem_get_from_pool(mem_pool);      if (!retval) { -        (void)pthread_spin_unlock(&pool_list->lock);          return NULL;      } -    retval->magic = GF_MEM_HEADER_MAGIC; -    retval->pool = mem_pool; -    retval->pool_list = pool_list; -    retval->power_of_two = mem_pool->pool->power_of_two; -    (void)pthread_spin_unlock(&pool_list->lock); -      GF_ATOMIC_INC(mem_pool->active);      return retval + 1; @@ -885,12 +894,20 @@ mem_put(void *ptr)      GF_ATOMIC_DEC(hdr->pool->active); -    (void)pthread_spin_lock(&pool_list->lock);      hdr->magic = GF_MEM_INVALID_MAGIC; -    hdr->next = pt_pool->hot_list; -    pt_pool->hot_list = hdr; -    GF_ATOMIC_INC(pt_pool->parent->frees_to_list); -    (void)pthread_spin_unlock(&pool_list->lock); + +    (void)pthread_spin_lock(&pool_list->lock); +    if (!pool_list->poison) { +        hdr->next = pt_pool->hot_list; +        pt_pool->hot_list = hdr; +        (void)pthread_spin_unlock(&pool_list->lock); +        GF_ATOMIC_INC(pt_pool->parent->frees_to_list); +    } else { +        /* If the owner thread of this element has terminated, we simply +         * release its memory. */ +        (void)pthread_spin_unlock(&pool_list->lock); +        free(hdr); +    }  #endif /* GF_DISABLE_MEMPOOL */  }  | 
