xref: /netbsd-src/external/bsd/jemalloc.old/include/jemalloc/internal/bin.h (revision 8e33eff89e26cf71871ead62f0d5063e1313c33a)
1*8e33eff8Schristos #ifndef JEMALLOC_INTERNAL_BIN_H
2*8e33eff8Schristos #define JEMALLOC_INTERNAL_BIN_H
3*8e33eff8Schristos 
4*8e33eff8Schristos #include "jemalloc/internal/extent_types.h"
5*8e33eff8Schristos #include "jemalloc/internal/extent_structs.h"
6*8e33eff8Schristos #include "jemalloc/internal/mutex.h"
7*8e33eff8Schristos #include "jemalloc/internal/bin_stats.h"
8*8e33eff8Schristos 
9*8e33eff8Schristos /*
10*8e33eff8Schristos  * A bin contains a set of extents that are currently being used for slab
11*8e33eff8Schristos  * allocations.
12*8e33eff8Schristos  */
13*8e33eff8Schristos 
14*8e33eff8Schristos /*
15*8e33eff8Schristos  * Read-only information associated with each element of arena_t's bins array
16*8e33eff8Schristos  * is stored separately, partly to reduce memory usage (only one copy, rather
17*8e33eff8Schristos  * than one per arena), but mainly to avoid false cacheline sharing.
18*8e33eff8Schristos  *
19*8e33eff8Schristos  * Each slab has the following layout:
20*8e33eff8Schristos  *
21*8e33eff8Schristos  *   /--------------------\
22*8e33eff8Schristos  *   | region 0           |
23*8e33eff8Schristos  *   |--------------------|
24*8e33eff8Schristos  *   | region 1           |
25*8e33eff8Schristos  *   |--------------------|
26*8e33eff8Schristos  *   | ...                |
27*8e33eff8Schristos  *   | ...                |
28*8e33eff8Schristos  *   | ...                |
29*8e33eff8Schristos  *   |--------------------|
30*8e33eff8Schristos  *   | region nregs-1     |
31*8e33eff8Schristos  *   \--------------------/
32*8e33eff8Schristos  */
33*8e33eff8Schristos typedef struct bin_info_s bin_info_t;
34*8e33eff8Schristos struct bin_info_s {
35*8e33eff8Schristos 	/* Size of regions in a slab for this bin's size class. */
36*8e33eff8Schristos 	size_t			reg_size;
37*8e33eff8Schristos 
38*8e33eff8Schristos 	/* Total size of a slab for this bin's size class. */
39*8e33eff8Schristos 	size_t			slab_size;
40*8e33eff8Schristos 
41*8e33eff8Schristos 	/* Total number of regions in a slab for this bin's size class. */
42*8e33eff8Schristos 	uint32_t		nregs;
43*8e33eff8Schristos 
44*8e33eff8Schristos 	/*
45*8e33eff8Schristos 	 * Metadata used to manipulate bitmaps for slabs associated with this
46*8e33eff8Schristos 	 * bin.
47*8e33eff8Schristos 	 */
48*8e33eff8Schristos 	bitmap_info_t		bitmap_info;
49*8e33eff8Schristos };
50*8e33eff8Schristos 
51*8e33eff8Schristos extern const bin_info_t bin_infos[NBINS];
52*8e33eff8Schristos 
53*8e33eff8Schristos 
54*8e33eff8Schristos typedef struct bin_s bin_t;
55*8e33eff8Schristos struct bin_s {
56*8e33eff8Schristos 	/* All operations on bin_t fields require lock ownership. */
57*8e33eff8Schristos 	malloc_mutex_t		lock;
58*8e33eff8Schristos 
59*8e33eff8Schristos 	/*
60*8e33eff8Schristos 	 * Current slab being used to service allocations of this bin's size
61*8e33eff8Schristos 	 * class.  slabcur is independent of slabs_{nonfull,full}; whenever
62*8e33eff8Schristos 	 * slabcur is reassigned, the previous slab must be deallocated or
63*8e33eff8Schristos 	 * inserted into slabs_{nonfull,full}.
64*8e33eff8Schristos 	 */
65*8e33eff8Schristos 	extent_t		*slabcur;
66*8e33eff8Schristos 
67*8e33eff8Schristos 	/*
68*8e33eff8Schristos 	 * Heap of non-full slabs.  This heap is used to assure that new
69*8e33eff8Schristos 	 * allocations come from the non-full slab that is oldest/lowest in
70*8e33eff8Schristos 	 * memory.
71*8e33eff8Schristos 	 */
72*8e33eff8Schristos 	extent_heap_t		slabs_nonfull;
73*8e33eff8Schristos 
74*8e33eff8Schristos 	/* List used to track full slabs. */
75*8e33eff8Schristos 	extent_list_t		slabs_full;
76*8e33eff8Schristos 
77*8e33eff8Schristos 	/* Bin statistics. */
78*8e33eff8Schristos 	bin_stats_t	stats;
79*8e33eff8Schristos };
80*8e33eff8Schristos 
81*8e33eff8Schristos /* Initializes a bin to empty.  Returns true on error. */
82*8e33eff8Schristos bool bin_init(bin_t *bin);
83*8e33eff8Schristos 
84*8e33eff8Schristos /* Forking. */
85*8e33eff8Schristos void bin_prefork(tsdn_t *tsdn, bin_t *bin);
86*8e33eff8Schristos void bin_postfork_parent(tsdn_t *tsdn, bin_t *bin);
87*8e33eff8Schristos void bin_postfork_child(tsdn_t *tsdn, bin_t *bin);
88*8e33eff8Schristos 
89*8e33eff8Schristos /* Stats. */
90*8e33eff8Schristos static inline void
91*8e33eff8Schristos bin_stats_merge(tsdn_t *tsdn, bin_stats_t *dst_bin_stats, bin_t *bin) {
92*8e33eff8Schristos 	malloc_mutex_lock(tsdn, &bin->lock);
93*8e33eff8Schristos 	malloc_mutex_prof_read(tsdn, &dst_bin_stats->mutex_data, &bin->lock);
94*8e33eff8Schristos 	dst_bin_stats->nmalloc += bin->stats.nmalloc;
95*8e33eff8Schristos 	dst_bin_stats->ndalloc += bin->stats.ndalloc;
96*8e33eff8Schristos 	dst_bin_stats->nrequests += bin->stats.nrequests;
97*8e33eff8Schristos 	dst_bin_stats->curregs += bin->stats.curregs;
98*8e33eff8Schristos 	dst_bin_stats->nfills += bin->stats.nfills;
99*8e33eff8Schristos 	dst_bin_stats->nflushes += bin->stats.nflushes;
100*8e33eff8Schristos 	dst_bin_stats->nslabs += bin->stats.nslabs;
101*8e33eff8Schristos 	dst_bin_stats->reslabs += bin->stats.reslabs;
102*8e33eff8Schristos 	dst_bin_stats->curslabs += bin->stats.curslabs;
103*8e33eff8Schristos 	malloc_mutex_unlock(tsdn, &bin->lock);
104*8e33eff8Schristos }
105*8e33eff8Schristos 
106*8e33eff8Schristos #endif /* JEMALLOC_INTERNAL_BIN_H */
107