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);  | 
