diff options
Diffstat (limited to 'libglusterfs/src/mem-pool.h')
-rw-r--r-- | libglusterfs/src/mem-pool.h | 67 |
1 files changed, 52 insertions, 15 deletions
diff --git a/libglusterfs/src/mem-pool.h b/libglusterfs/src/mem-pool.h index 6cff7be94f4..0dc186341b2 100644 --- a/libglusterfs/src/mem-pool.h +++ b/libglusterfs/src/mem-pool.h @@ -209,24 +209,61 @@ out: return dup_mem; } +typedef struct pooled_obj_hdr { + unsigned long magic; + struct pooled_obj_hdr *next; + struct per_thread_pool_list *pool_list; + unsigned int power_of_two; +} pooled_obj_hdr_t; + +#define AVAILABLE_SIZE(p2) ((1 << (p2)) - sizeof(pooled_obj_hdr_t)) + +typedef struct per_thread_pool { + /* This never changes, so doesn't need a lock. */ + struct mem_pool *parent; + /* Everything else is protected by our own lock. */ + pooled_obj_hdr_t *hot_list; + pooled_obj_hdr_t *cold_list; +} per_thread_pool_t; + +typedef struct per_thread_pool_list { + /* + * These first two members are protected by the global pool lock. When + * a thread first tries to use any pool, we create one of these. We + * link it into the global list using thr_list so the pool-sweeper + * thread can find it, and use pthread_setspecific so this thread can + * find it. When the per-thread destructor runs, we "poison" the pool + * list to prevent further allocations. This also signals to the + * pool-sweeper thread that the list should be detached and freed after + * the next time it's swept. + */ + struct list_head thr_list; + unsigned int poison; + /* + * There's really more than one pool, but the actual number is hidden + * in the implementation code so we just make it a single-element array + * here. + */ + pthread_spinlock_t lock; + per_thread_pool_t pools[1]; +} per_thread_pool_list_t; + struct mem_pool { - struct list_head list; - int hot_count; - int cold_count; - gf_lock_t lock; - unsigned long padded_sizeof_type; - void *pool; - void *pool_end; - int real_sizeof_type; - uint64_t alloc_count; - uint64_t pool_misses; - int max_alloc; - int curr_stdalloc; - int max_stdalloc; - char *name; - struct list_head global_list; + unsigned int power_of_two; + /* + * Updates to these are *not* protected by a global lock, so races + * could occur and the numbers might be slightly off. Don't expect + * them to line up exactly. It's the general trends that matter, and + * it's not worth the locked-bus-cycle overhead to make these precise. + */ + unsigned long allocs_hot; + unsigned long allocs_cold; + unsigned long allocs_stdc; + unsigned long frees_to_list; }; +void mem_pools_init (void); + struct mem_pool * mem_pool_new_fn (unsigned long sizeof_type, unsigned long count, char *name); |